【问题标题】:Using a string with libusb causes segmentation fault将字符串与 libusb 一起使用会导致分段错误
【发布时间】:2018-12-17 01:47:56
【问题描述】:

我正在使用带有 gcc 的 netbeans 进行编译。当我运行附加的代码时,我得到了错误: RUN FINISHED; Segmentation fault; core dumped; real time: 310ms; user: 40ms; system: 10ms

如果 'char stringData' 被注释掉,则没有分段错误。此外,如果 libusb_get_device_descriptor 被删除(以及随附的结构引用),则不会出现分段错误。

如果它在调试模式下运行,它会给出一个错误提示:

#error "Never use <bits/string_fortified.h> directly; include <string.h> instead."

我看不出它们如何相互影响。

#include <stdio.h>
#include <stdlib.h>
#include <libusb.h>
#define DATLENGTH 15

int main() {
    libusb_context *context;
    int i; 
    libusb_device **list;
    libusb_device *device;
    const struct libusb_version *libVersion;
    ssize_t numDev = 0;
    struct libusb_device_descriptor *dev_descriptor;
    struct libusb_config_descriptor *config;
    libusb_device_handle * dev_handle;
    char stringData[DATLENGTH];

    libusb_init(&context);


    libVersion = libusb_get_version();
    printf("Library Version: %i.%i.%i.%i\n", (int)libVersion->major, (int)libVersion->minor, (int)libVersion->micro, (int)libVersion->nano);

    numDev = libusb_get_device_list(context, &list);    
    if(numDev < 0){
        printf("Error %i\n", numDev);
        return -1;
    }
    else{
        printf("Number of devices: %i\n\n", numDev);
    }

    for(i=0;i<numDev;i++){    
        device = list[0];

        struct libusb_device_descriptor *dev_descriptor;

        libusb_get_device_descriptor(device, dev_descriptor);
        printf("Device #:  %i\n", i);
        printf("idVendor:  %04x\n", (dev_descriptor->idVendor & 0x0000FFFF));
        printf("idProduct: %04x\n", (dev_descriptor->idProduct & 0x0000FFFF));
        printf("Number of Configurations: %i\n", dev_descriptor->bNumConfigurations);
        libusb_open(device, &dev_handle);
        libusb_get_string_descriptor_ascii(dev_handle, dev_descriptor->iManufacturer, stringData, DATLENGTH);
        printf("Manufacturer ID: %s\n", stringData);        
        libusb_get_string_descriptor_ascii(dev_handle, dev_descriptor->iProduct, stringData, DATLENGTH);
        printf("Product ID: %s\n", stringData);       


        printf("\n");
        }

        libusb_free_device_list(list, 1); 

        libusb_exit(context);

    return (EXIT_SUCCESS);
}

【问题讨论】:

    标签: c string libusb


    【解决方案1】:

    您正在产生未定义的行为:

    struct libusb_device_descriptor *dev_descriptor;
    libusb_get_device_descriptor(device, dev_descriptor);
    

    dev_descriptor 应该是指向struct libusb_device_descriptor 的指针。但它是一个指向无处的指针,因为您从未初始化它。当libusb_get_device_descriptor 尝试在结构中存储信息时,它会出现段错误或覆盖随机内存。

    你应该把它改成:

    struct libusb_device_descriptor dev_descriptor;
    libusb_get_device_descriptor(device, &dev_descriptor);
    

    它实际上在堆栈上分配了一个struct libusb_device_descriptor,然后传递结构的地址。请注意,您必须在整个过程中将 dev_descriptor-&gt;field 更改为 dev_descriptor.field

    【讨论】:

    • 这是有道理的。像 libusb_version 这样的东西呢?这似乎从来没有引起任何问题,还是只是运气?
    • @gacekky1: libusb_version 不会要求您提供复制数据的位置。由于版本字符串是常量,它只是给你一个指向它的指针。 (而且因为它是恒定的,你最好不要试图改变它,但你为什么要......)。注意原型的区别。
    猜你喜欢
    • 2017-08-02
    • 1970-01-01
    • 2023-03-20
    • 2019-09-16
    • 2015-09-03
    • 1970-01-01
    • 2013-06-22
    • 2011-06-30
    • 2015-08-06
    相关资源
    最近更新 更多