Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation Fault when using hidapi with MCP2111a #465

Closed
NunoGaioPereira opened this issue Dec 18, 2020 · 3 comments
Closed

Segmentation Fault when using hidapi with MCP2111a #465

NunoGaioPereira opened this issue Dec 18, 2020 · 3 comments

Comments

@NunoGaioPereira
Copy link

NunoGaioPereira commented Dec 18, 2020

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 am running on Ubuntu 20.
  • I have libudev-dev and libusb-1.0-0-dev up to date.

I would really appreciate any help or guidance.

@todbot
Copy link

todbot commented Dec 18, 2020

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

@Youw
Copy link

Youw commented Dec 18, 2020

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

@NunoGaioPereira
Copy link
Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants