ZakKemble / libmcp2221

MCP2221 HID Library
https://blog.zakkemble.net/mcp2221-hid-library/
GNU General Public License v3.0
53 stars 14 forks source link

Can't connect to MCP2221a - Segmentation Fault #5

Closed NunoGaioPereira closed 3 years ago

NunoGaioPereira commented 3 years ago

Hello,

I have acquired an MCP2221a breakout board. I have been able to use it successfully with their guide, and python board and digitalio libraries, which also makes use of the hidapi. However, I need to use C/C++ for sure so I am trying to use this library. The problem seems to come from inside the hidapi library but maybe someone has encountered this problem or there is some extra configuration I have to do with the MCP2221a.

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 the 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.

ZakKemble commented 3 years ago

Hey Nuno, have you tried printfing the contents of tmp? It looks like it should be a human readable string, maybe another USB device is messing it up. It might also be a good idea to try libusb's hidapi fork since signal11's hasn't been touched in 4 years or so.

NunoGaioPereira commented 3 years ago

Hey zkemble,

Thanks a lot for your suggestion, I tried using libusb's hidapi fork and it worked perfectly!

Many thanks, I really appreciate your help! Nuno

anon1a1 commented 2 years ago

hi there, I am using the fork version and I am still seeing

Starting! Looking for devices... found 2 devices Opening device... No MCP2221s found

Is there something issue with the USBaddevice function such that the static devList is still empty?

ZakKemble commented 2 years ago

Hi @anon1a1, please open a new issue since your problem is not related to this one.

stigabonzaa commented 2 years ago

Hello @ZakKemble and @NunoGaioPereira, this thread is a little old now but hopefully you will see this. I am somewhat of a novice and wondered if you can expand on your answer a little as I to have the same problem as Nuno explained. Was the solution to just start form scratch with the libusb's hidapi fork or did you splice bits together and if so how.

Cheers,