libusbdi.a problem

My process will segmentation fault in the memchunk module of libusbdi.a.
What I did to create this is insert and remove a usb device continuously.
When the device is inserted, my program gathers information from it. This
occurs after all memory has been allocated, of course. When I remove the
device, all memory is freed. The segmentation fault occurs in various
places. Sometimes in usbd_free, sometimes in usbd_interface_descriptor, and
maybe some other place as well. All of them could be traced to the memchunk
module in libusbdi.a.

Please help.

Rex

Rex Lam <Rex.Lam@igt.com> wrote:

My process will segmentation fault in the memchunk module of libusbdi.a.
What I did to create this is insert and remove a usb device continuously.
When the device is inserted, my program gathers information from it. This
occurs after all memory has been allocated, of course. When I remove the
device, all memory is freed. The segmentation fault occurs in various
places. Sometimes in usbd_free, sometimes in usbd_interface_descriptor, and
maybe some other place as well. All of them could be traced to the memchunk
module in libusbdi.a.

It sounds like something is clobbering the usb memory allocator. Can you post
the code that causes the SIGSEGV?

The SIGSEGV does not happen in a consistent place. Here are some of the
places it happens:

Example 1:
printf (“usbd_interface_descriptor (%p, %d, %d, %d, %p)\n”, ekey->device,
ekey->instance.config,
ekey->instance.iface, ekey->instance.alternate, &ifc);
if ((interface = usbd_interface_descriptor (ekey->device,
ekey->instance.config, ekey->instance.iface,
ekey->instance.alternate, &ifc)) != NULL)
{
printf (" usbd_device_descriptor\n");
if ((device = usbd_device_descriptor (ekey->device, &ept)) != NULL)

}
In this example, it happens in usbd_interface_descriptor.

Example 2:
usbd_free_urb (ekey->urb);
usbd_abort_pipe (ekey->ep_cntl);
usbd_free (ekey->buffer);
In this example, it happens in usbd_free. ekey->urb was allocated with
usbd_alloc_urb. ekey->ep_cntl was obtained from usbd_open_pipe.
ekey->buffer was allocated with usbd_alloc.

Example 3:
if ((device = usbd_device_descriptor (ekey->device, &ept)) != NULL)
{
printf ("\n");
printf (“Device Descriptor\n\n”);
printf (“Vendor ID = 0x%04X\n”, device->idVendor);
printf (“Product ID = 0x%04X\n”, device->idProduct);
printf (“USB spec = %04X\n”, device->bcdUSB);
printf (“Product rel. = %04X\n”, device->bcdDevice);
printf (“Max Packet = %02X\n”, device->bMaxPacketSize0);
if (device->iManufacturer)
printf (“Manufacturer = %s\n”, usbd_string (ekey->device,
device->iManufacturer, 0));
if (device->iProduct)
printf (“Product Name = %s\n”, usbd_string (ekey->device,
device->iProduct, 0));
if (device->iSerialNumber)
printf (“Serial Number = %s\n”, usbd_string (ekey->device,
device->iSerialNumber, 0));
printf ("\n");
}
In this example, it happens in usbd_string.



“Kevin Chiles” <kchiles@qnx.com> wrote in message
news:995ndp$o4d$1@nntp.qnx.com
Rex Lam <Rex.Lam@igt.com> wrote:

My process will segmentation fault in the memchunk module of libusbdi.a.
What I did to create this is insert and remove a usb device continuously.
When the device is inserted, my program gathers information from it. This
occurs after all memory has been allocated, of course. When I remove the
device, all memory is freed. The segmentation fault occurs in various
places. Sometimes in usbd_free, sometimes in usbd_interface_descriptor,
and
maybe some other place as well. All of them could be traced to the
memchunk
module in libusbdi.a.

It sounds like something is clobbering the usb memory allocator. Can you
post
the code that causes the SIGSEGV?

Is it possible for me to get the source code for memchunk? I would like to
find out if there is anything in there that may have caused this problem.
So far, everything I have tried have failed to solve this problem.

Rex

“Rex Lam” <Rex.Lam@igt.com> wrote in message
news:9954sf$isg$1@inn.qnx.com
My process will segmentation fault in the memchunk module of libusbdi.a.
What I did to create this is insert and remove a usb device continuously.
When the device is inserted, my program gathers information from it. This
occurs after all memory has been allocated, of course. When I remove the
device, all memory is freed. The segmentation fault occurs in various
places. Sometimes in usbd_free, sometimes in usbd_interface_descriptor, and
maybe some other place as well. All of them could be traced to the memchunk
module in libusbdi.a.

Please help.

Rex

Rex Lam <Rex.Lam@igt.com> wrote:

The SIGSEGV does not happen in a consistent place. Here are some of the
places it happens:

I am guessing that your class driver is corrupting the allocator. Can you
post the source to your class driver or send it to Randy Martin?

“Kevin Chiles” <kchiles@qnx.com> wrote in message news:99a8od$g17$1@nntp.qnx.com

Rex Lam <> Rex.Lam@igt.com> > wrote:
The SIGSEGV does not happen in a consistent place. Here are some of the
places it happens:

I am guessing that your class driver is corrupting the allocator. Can you
post the source to your class driver or send it to Randy Martin?

Here is the code I am running. Please look through it and let me know if I did something wrong. The problems I am encountering do not always happen. When it crashes, it happens when I insert and remove a usb device rapidly. The SIGSEGV always ends up happening in the same place - offset 0xA1 in the memchunk module of libusbdi.a.

#include “usb_device.h”
#include <share.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/resmgr.h>
#include <sys/procmgr.h>
#include <sys/dcmd_chr.h>
#include <sys/rsrcdbmgr.h>

usb_device_ctrl_t usb_device_ctrl;

int usb_device_free (usb_device_t *usb_device)
{
int status = 0;

printf (“usb_device_free\n”);

if (!usb_device)
return 0;
else
{
printf (“rsrcdbmgr_devno_detach\n”);
rsrcdbmgr_devno_detach (usb_device->attr.rdev, 0);

printf (“resmgr_detach\n”);
resmgr_detach (usb_device_ctrl.dispatch, usb_device->resmgr_id, _RESMGR_DETACH_ALL | _RESMGR_DETACH_CLOSE);
}
if (usb_device->urb)
{
printf (“usbd_free_urb\n”);
usbd_free_urb (usb_device->urb);
usb_device->urb = 0;
}
if (usb_device->ep_cntl)
{
printf (“free ep_cntl\n”);
usbd_abort_pipe (usb_device->ep_cntl);
usb_device->ep_cntl = 0;
}
if (usb_device->int_urb)
{
printf (“usbd_free_int_urb\n”);
usbd_free_urb (usb_device->int_urb);
usb_device->int_urb = 0;
}
if (usb_device->ep_intr)
{
printf (“free ep_intr\n”);
usbd_abort_pipe (usb_device->ep_intr);
usb_device->ep_intr = 0;
}
if (usb_device->buffer)
{
printf (“free buffer\n”);
usbd_free (usb_device->buffer);
usb_device->buffer = 0;
}
if (usb_device->int_buf)
{
printf (“free int_buf\n”);
usbd_free (usb_device->int_buf);
usb_device->int_buf = 0;
}

TAILQ_REMOVE (&usb_device_ctrl.dlist, usb_device, dlink);

if (usb_device->device)
{
printf (“usbd_detach: usb_device = %p\n”, usb_device);
if ((status = usbd_detach( usb_device->device )))
{
fprintf (stderr, “usb_device_free: usbd_detach %d = %s\n”, status, strerror (status));
}
}

printf (“end usb_device_free\n”);
return (status);
}

void usb_device_signal_handler (void)
{
siginfo_t info;
sigset_t set;
usb_device_t *usb_device;
usb_device_t *nusb_device;

printf (“usb_device_signal_handler\n”);

sigfillset (&set);
while (SignalWaitinfo( &set, &info) == -1)
;

for (usb_device = TAILQ_FIRST (&usb_device_ctrl.dlist); usb_device; usb_device = nusb_device)
{
nusb_device = TAILQ_NEXT (usb_device, dlink);
usb_device_free (usb_device);
}
}

int usb_device_parse_descriptors (usb_device_t *usb_device)
{
_uint32 eix;
_uint32 scan;
_uint32 found;
usbd_descriptors_t *desc;
struct usbd_desc_node *ifc, *ept;
#ifdef DEBUG
usbd_device_descriptor_t *device;
usbd_configuration_descriptor_t *cfg;
usbd_interface_descriptor_t *interface;
usbd_endpoint_descriptor_t *endpoint;
_uint8 num_endpoints = 0;
int i;
#endif

scan = USB_DEVICE_CONTROL_EP | USB_DEVICE_INTIN_EP;
found = 0;

printf (“usb_device_parse_descriptors (%p)\n”, usb_device);

#ifdef DEBUG
printf (“usbd_interface_descriptor (%p, %d, %d, %d, %p)\n”, usb_device->device, usb_device->instance.config,
usb_device->instance.iface, usb_device->instance.alternate, &ifc);
if ((interface = usbd_interface_descriptor (usb_device->device, usb_device->instance.config, usb_device->instance.iface,
usb_device->instance.alternate, &ifc)) != NULL)
{
printf (“usbd_interface_descriptor succeeded\n”);
if ((device = usbd_device_descriptor (usb_device->device, &ept)) != NULL)
{
printf ("\n");
printf (“Device Descriptor\n\n”);
printf (“Vendor ID = 0x%04X\n”, device->idVendor);
printf (“Product ID = 0x%04X\n”, device->idProduct);
printf (“USB spec = %04X\n”, device->bcdUSB);
printf (“Product rel. = %04X\n”, device->bcdDevice);
printf (“Max Packet = %02X\n”, device->bMaxPacketSize0);
if (device->iManufacturer)
printf (“Manufacturer = %s\n”, usbd_string (usb_device->device, device->iManufacturer, 0));
if (device->iProduct)
printf (“Product Name = %s\n”, usbd_string (usb_device->device, device->iProduct, 0));
if (device->iSerialNumber)
printf (“Serial Number = %s\n”, usbd_string (usb_device->device, device->iSerialNumber, 0));
printf ("\n");
}

if ((cfg = usbd_configuration_descriptor (usb_device->device, 1, &ept)) != NULL)
{
printf (“Device Configuration\n\n”);
printf (“Cfg: Attributes = 0x%02X (0x80 = Bus Powered, 0xC0 = Self Powered)\n”, cfg->bmAttributes);
if (cfg->iConfiguration)
printf (“Cfg: Desc = %s\n”, usbd_string (usb_device->device, cfg->iConfiguration, 0));
printf ("\n");
}

{
printf (“Device Interface\n\n”);
printf (“Interface Number = 0x%02X\n”, interface->bInterfaceNumber);
printf (“Alternate Setting = 0x%02X\n”, interface->bAlternateSetting);
printf (“Number of endpoints = 0x%02X\n”, interface->bNumEndpoints);
num_endpoints = interface->bNumEndpoints;
if (interface->iInterface)
printf (“Interface description = %s\n”, usbd_string (usb_device->device, interface->iInterface, 0));
printf ("\n");
}

for (i = 0; i <= num_endpoints; i++)
{
_uint8 ep = 0x80 | (i);

if ((endpoint = usbd_endpoint_descriptor (usb_device->device, usb_device->instance.config,
usb_device->instance.iface, usb_device->instance.alternate, ep, &ifc)) != NULL)
{
printf (“Device Endpoint %d\n\n”, i);
printf (“Transfer Type = 0x%02X (00 = Control, 01 = Isochronous, 02 = Bulk, 03 = Interrupt)\n”, endpoint->bmAttributes);
printf (“Max Packet Size = 0x%04X\n”, endpoint->wMaxPacketSize);
printf (“Polling Interval = 0x%02X\n”, endpoint->bInterval);
printf ("\n");
}
}
}
#endif

if (usbd_interface_descriptor (usb_device->device, usb_device->instance.config, usb_device->instance.iface, usb_device->instance.alternate, &ifc))
{
for (eix = 0; (desc = usbd_parse_descriptors (usb_device->device, ifc, USB_DESC_ENDPOINT, eix, &ept)) != NULL; ++eix)
{
switch (desc->endpoint.bmAttributes)
{
case USB_ATTRIB_CONTROL:
printf(“attrib control\n”);
if (usbd_open_pipe (usb_device->device, desc, &usb_device->ep_cntl) == EOK)
{
printf (“usb_device = %p, pipe = %p\n”, usb_device, usb_device->ep_cntl);
found |= USB_DEVICE_CONTROL_EP;
usb_device->ep_data_size = desc->endpoint.wMaxPacketSize;
}
break;

case USB_ATTRIB_ISOCHRONOUS:
printf(“attrib isoch\n”);
break;

case USB_ATTRIB_BULK:
printf(“attrib bulk\n”);
break;

case USB_ATTRIB_INTERRUPT:
printf(“attrib int\n”);
switch( desc->endpoint.bEndpointAddress & USB_ENDPOINT_IN )
{
case USB_ENDPOINT_OUT:
break;

case USB_ENDPOINT_IN:
if (usbd_open_pipe (usb_device->device, desc, &usb_device->ep_intr) == EOK)
{
printf (“usb_device = %p, pipe = %p\n”, usb_device, usb_device->ep_intr);
found |= USB_DEVICE_INTIN_EP;
usb_device->ep_intr_size = desc->endpoint.wMaxPacketSize;
}
break;
}
break;
}
}
}
return ((found & scan) ? EOK : ENODEV);
}

void usb_device_insertion (struct usbd_connection *connection, usbd_device_instance_t *instance)
{
usb_device_t *usb_device;
struct usbd_device *device;
int status;
usbd_device_ident_t *ident;

printf (“usb_device_insertion\n”);

ident = &instance->ident;
printf( “USB enum Insertion: addr %x, dev: %x, vid %x, class %x, sclass %x, proto %x\n”,
instance->devno, ident->device, ident->vendor, ident->usb_class, ident->subclass, ident->protocol );

if (ident->usb_class != USB_CLASS_HUB && (status = usbd_attach (connection, instance, sizeof (usb_device_t), &device)) == EOK)
{
printf (" device attached\n");
usb_device = usbd_device_extra (device);
usb_device->device = device;
usb_device->instance = *instance;
if (usb_device_parse_descriptors (usb_device) == EOK)
{
if (usb_device_init (usb_device))
{
// if (usb_device_resmgr_attach (usb_device) == EOK)
{
TAILQ_INSERT_TAIL (&usb_device_ctrl.dlist, usb_device, dlink);
return;
}
}
usbd_detach (device);
}
}
}

int usb_device_init (usb_device_t *usb_device)
{
int rv = 1;
printf (“usb_device_init\n”);

if (!usb_device)
rv = 0;

if (rv && usb_device->ep_cntl)
{
if ((usb_device->buffer = usbd_alloc (64)) != 0)
{
if ((usb_device->urb = usbd_alloc_urb (NULL)) == NULL)
{
rv = 0;
}
}
else
rv = 0;
}

// Now allocate for interrupt transfer
if (rv && usb_device->ep_intr)
{
if ((usb_device->int_buf = usbd_alloc (64)) != 0)
{
if ((usb_device->int_urb = usbd_alloc_urb (NULL)) == NULL)
{
rv = 0;
}
}
else
rv = 0;
}

if (!rv)
{
// Free up interrupt buffers.
if (usb_device->int_urb)
{
usbd_free_urb (usb_device->int_urb);
usb_device->int_urb = 0;
}
if (usb_device->int_buf)
{
usbd_free (usb_device->int_buf);
usb_device->int_buf = 0;
}
// Free up control buffers.
if (usb_device->urb)
{
usbd_free_urb (usb_device->urb);
usb_device->urb = 0;
}
if (usb_device->buffer)
{
usbd_free (usb_device->buffer);
usb_device->buffer = 0;
}
}
return rv;
}

void usb_device_removal (struct usbd_connection *connection, usbd_device_instance_t *instance)
{
struct usbd_device *device;
usb_device_t *usb_device;

printf ("\nusb_device_removal\n");

if ((device = usbd_device_lookup (connection, instance)) != NULL)
{
usb_device = usbd_device_extra (device);
usb_device_free (usb_device);
}
usb_device = TAILQ_FIRST (&usb_device_ctrl.dlist);
printf (“usb_device = %p\n\n”, usb_device);
}

int main (int argc, char *argv[])
{
struct usbd_connection *connection;
usbd_funcs_t funcs = { _USBDI_NFUNCS, usb_device_insertion,
usb_device_removal, NULL };

usbd_device_ident_t interest = { USBD_CONNECT_WILDCARD, // Vendor
USBD_CONNECT_WILDCARD, // Product
USBD_CONNECT_WILDCARD,
USBD_CONNECT_WILDCARD,
USBD_CONNECT_WILDCARD };

usbd_connect_parm_t parm = { NULL, USB_VERSION, USBD_VERSION, 0, argc,
argv, 0, &interest, &funcs };
int status;
int opt;
sigset_t signals;

printf (“main\n”);

sigfillset (&signals); // No signals to resmgr threads
pthread_sigmask (SIG_BLOCK, &signals, NULL);

TAILQ_INIT (&usb_device_ctrl.dlist);
usb_device_ctrl.prefix = “usbd”;

while ((opt = getopt (argc, argv, “vn:”)) != -1)
{
switch (opt)
{
case ‘n’:
usb_device_ctrl.prefix = optarg;
break;

case ‘v’:
usb_device_ctrl.verbose++;
break;

default:
break;
}
}

if ((usb_device_ctrl.chid = ChannelCreate (_NTO_CHF_DISCONNECT | _NTO_CHF_UNBLOCK)) == -1 ||
(usb_device_ctrl.coid = ConnectAttach (0, 0, usb_device_ctrl.chid, 0, _NTO_SIDE_CHANNEL)) == -1)
{
fprintf (stderr, “Unable to attach channel and connection\n”);
exit (EXIT_FAILURE);
}

if ((status = usbd_connect (&parm, &connection)) != EOK)
{
fprintf (stderr, “USB Device Class/init - %s\n”, strerror (status));
exit (EXIT_FAILURE);
}

usb_device_signal_handler ();

exit (EXIT_SUCCESS);
}