Created
April 28, 2015 07:17
-
-
Save projectgus/c9e29f90397202dbba38 to your computer and use it in GitHub Desktop.
Minimal test program for libusb leaks on Windows. Relates to https://github.com/libusb/libusb/pull/64
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Quick sample to demonstrate Windows device leaks from libusb_get_device_list when reusing instances */ | |
#include <stdio.h> | |
#include "libusb.h" | |
#include <assert.h> | |
/* Set to zero to stop after 100 iterations, for running under drmemory/other */ | |
const int RUN_INFINITE = 0; | |
static libusb_device **stored = NULL; | |
static void release_stored_devices(void); | |
static void store_devices(libusb_device **devs, int cnt) | |
{ | |
int i =0; | |
if(stored) | |
release_stored_devices(); | |
stored = calloc(cnt+1, sizeof(libusb_device *)); | |
fprintf(stderr, "storing references to device list...\n"); | |
for(i = 0; devs[i]; i++) { | |
stored[i] = devs[i]; | |
libusb_ref_device(stored[i]); | |
} | |
fprintf(stderr, "stored %d device references\n", i); | |
} | |
static void release_stored_devices(void) | |
{ | |
int i = 0; | |
if(!stored) | |
return; /* nothing stored */ | |
fprintf(stderr, "dropping references to previously stored stored device refs...\n"); | |
for(i = 0; stored[i]; i++) | |
libusb_unref_device(stored[i]); | |
fprintf(stderr, "dropped %d stored refs\n", i); | |
free(stored); | |
stored = 0; | |
} | |
int main(void) | |
{ | |
libusb_device **devs; | |
int r; | |
ssize_t cnt; | |
r = libusb_init(NULL); | |
if (r < 0) { | |
fprintf(stderr, "libusb_init failed %d\n", r); | |
return r; | |
} | |
libusb_set_debug(NULL, 4); | |
/* First, read one list of devices and store referenced | |
pointers to them before freeing the device list itself. | |
*/ | |
cnt = libusb_get_device_list(NULL, &devs); | |
assert(cnt >= 0); | |
store_devices(devs, cnt); | |
libusb_free_device_list(devs, 1); | |
/* Now, loop around getting and freeing subsequent device lists */ | |
int loops = 0; | |
while(RUN_INFINITE || loops < 100) { | |
cnt = libusb_get_device_list(NULL, &devs); | |
assert(cnt >= 0); | |
libusb_free_device_list(devs, 1); | |
fprintf(stderr, "Completed %d loops\n", ++loops); | |
} | |
fprintf(stderr, "dropping stored devices before stopping (all devices should be freed)\n"); | |
release_stored_devices(); | |
libusb_exit(NULL); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment