signal11 / hidapi

A Simple library for communicating with USB and Bluetooth HID devices on Linux, Mac, and Windows.
http://www.signal11.us/oss/hidapi/
Other
2.44k stars 899 forks source link

Segmentation Fault when using hidapi with MCP2111a #465

Closed NunoGaioPereira closed 3 years ago

NunoGaioPereira commented 3 years ago

Hello,

I have acquired an MCP2221a breakout board which has GPIO's. I have been able to use it successfully with their guide, and python board and digitalio libraries, which also makes use of the python's hidapi. However, I need to use C/C++ for sure. There is a C library called libmcp2221 that should work and that uses hidapi under the hoods.

The problem that I am obtaining seems to come from inside the hidapi library so maybe someone has encountered this problem before.

I have been trying to use libmcp2221 and compiled the libraries as per described in the readme, but I am having a segmentation fault error when running the examples. I am using their example (mainly gpio) but the same problem occurs in the other examples.

Problem

In the main code of libmcp2221 gpio example, mcp2221_find method is called:

int count = mcp2221_find(MCP2221_DEFAULT_VID, MCP2221_DEFAULT_PID, NULL, NULL, NULL);

This method then calls hid_enumerate() from hid.c, which in turn calls parse_uevent_info(), also from hid.c. I have managed to trace back that the Segmentation fault (core dumped) comes from this parse_uevent_info() method.

What has been tried

Running GDB with original code

In the original hid.c code, the method parse_uevent_info is declared as follows:

static int
parse_uevent_info(const char *uevent, int *bus_type,
    unsigned short *vendor_id, unsigned short *product_id,
    char **serial_number_utf8, char **product_name_utf8)

When this method is being called by hid_enumerate() inside hid.c, the following is obtained with gdb:

Program received signal SIGSEGV, Segmentation fault.
__GI___strtok_r (
    s=0x5556b780 <error: Cannot access memory at address 0x5556b780>, 
    delim=0x7fffffffd270 "", save_ptr=0x0) at strtok_r.c:49
49  strtok_r.c: No such file or directory.

where 0x5556b780 is the memory address of uevent passed as an argument to parse_uevent_info(). This comes from the line: line = strtok_r(tmp, &saveptr);

The problem always seems to be in accessing tmp variable.

Running GDB with code changes

After identifying that the problem is in the call of tmp variable inside parse_uevent_info() I tried to play a bit with the code inside hid.c.

Removed constness of uevent argument just to test if I could call strtok_r with it. and obtained a segmentation fault further along, in

Passed through: line = strtok_r(tmp, "\n", &saveptr); but (with gdb) got:

Program received signal SIGSEGV, Segmentation fault.
__strchr_avx2 () at ../sysdeps/x86_64/multiarch/strchr-avx2.S:57
57  ../sysdeps/x86_64/multiarch/strchr-avx2.S: No such file or directory.
or segmentation fault at value = strchr(line, '=');

I tried other small changes like this but always reached a segmentation fault.

Assert

Tried using assert()

#include <assert.h>
assert(strcmp(uevent, tmp) == 0);

but I obtained segmentation fault in the assert() call.

MCP2221 Windows Utility

I installed MCP2221 Utility, which can be downloaded from this link under Documents. This showed that the values of VID and PID are indeed the default defined in libmcp2221.h:

#define MCP2221_DEFAULT_VID     0x04D8  /**< Default VID */
#define MCP2221_DEFAULT_PID     0x00DD  /**< Default PID */

This two values are the two arguments sent to hid_enumerate() and I confirmed that they are correct in the Windows Utility.

Valgrind

I have also tried to use valgrind. When I launch the gpio example with valgrind, the segmentation fault does not occur. This behaviour is actually described in their FAQ. But I obtain the following:

found 1 devices
Opening device... No MCP2221s found

I am pretty sure that device is the actual mcp2221a as when I remove it and run the program no device is detected. This FAQ explains how valgrind may alter the memory environment of a program and why segmentation fault does not occur.

-> I am wondering if this has anything to do with some environmental setup or if someone had to do any extra step.

Some specs:

I would really appreciate any help or guidance.

todbot commented 3 years ago

Just a quick check: have you set the udev permissions for this device?

Youw commented 3 years ago

I suggest try to use mainstream master first. See #373.

NunoGaioPereira commented 3 years ago

Hello,

Apologies for my late reply and thank you for your help!

@todbot, yes I have set the udev permissions for the device. @Youw I tried libusb's hidapi fork and it worked just fine!

Thanks for both your replies! I will close the issue now.