Ich entdeckte ein Speicherleck lesen Daten über USB-Interrupt-Transfer mit libUSB synchron. Mein einfaches Benutzerprogramm verwendet keine dynamische Speicherzuordnung selbst. Intern verwendet libusb die dynamische Speicherzuweisung übermäßig. Der Kommunikationsfluss funktioniert wie erwartet. Gibt es eine spezielle Funktion, um einen internen dynamischen Speicher nach der Verwendung von libusb_interrupt_transfer freizugeben? Hat jemand eine Idee, was den kontinuierlichen Speicheranstieg während der Laufzeit verursacht?Speicherleck synchronen Lese-Interrupt-Übertragung Daten über libUSB
Mein Protokoll implementiert einen Zwei-Wege-Handshake. Aus diesem Grund verursacht ein einfacher Datenaustausch eine Übertragung von OUT (Anforderung), IN (Ack/Nack), IN (Antwort) und OUT (Ack/Nack). Die Berichtsgröße beträgt 32 Bytes, der outEndpointAddr ist 1, der inEndpointAddr ist 129, Hier sind die relevanten Code-Schnipsel.
int main (void)
{
uint32_t devFound = 0;
uint32_t devErrors = 0;
...
int libUsbErr = 0;
if(!findSensor(&devFound, &devErrors, &libUsbErr, foundCB))
printf("finding sensor failed %d\n", libUsbErr);
if(!openSensor(mySensor, &libUsbErr))
printf("open sensor failed %d\n", libUsbErr);
int i = 0;
while(1)
{
printf("[%06d] Int Temp %f C\n",i++, readIntTemper());
Delay(0.5);
}
closeSensor(&mySensor, NULL);
closeSensorContext();
return 0;
}
float readIntTemper()
{
static uint8_t tmp[32];
static uint8_t response[32];
...//Prepare request frame
int libUsbErr = 0;
if(!HID_Write(mySensor, tmp, &written, 4000, &libUsbErr))
{
printf("write request failed %d\n", libUsbErr);
return 0;
}
//Read Ack/Nack
if(!HID_Read(mySensor, tmp, &read, 4000, &libUsbErr))
{
printf("Read ACK NACK failed %d\n", libUsbErr);
return 0;
}
...//Test if Ack/Nack
if(!HID_Read(mySensor, response, &read, 4000, &libUsbErr))
{
printf("Read response failed %d\n", libUsbErr);
return 0;
}
... //Prepare ACK
if(!HID_Write(mySensor, tmp, &written, 4000, &libUsbErr))
{
printf("Ack response failed %d\n", libUsbErr);
return 0;
}
...
float* temper = (float*)&response[8];
return *temper;
}
bool HID_Write(const Sensor* sens, uint8_t* repBuf, int* transferred, uint32_t timeout, int* libUsbErr)
{
if(sens == NULL || repBuf == NULL || transferred == NULL)
return returnlibUSBErr(libUsbErr, -1008); ///TODO nice error codes;
if(!sens->claimed)
return returnlibUSBErr(libUsbErr, -1012); ///TODO nice error codes;
int r = libusb_interrupt_transfer(sens->devHandle, sens->outEndpointAddr,
repBuf, sens->outRepSize, transferred, timeout);
if (r < 0)
return returnlibUSBErr(libUsbErr, r);
return returnlibUSBErr(libUsbErr, LIB_USB_OK);
}
bool HID_Read(const Sensor* sens, uint8_t* repBuf, int* read, uint32_t timeout, int* libUsbErr)
{
if(sens == NULL || read == NULL)
return returnlibUSBErr(libUsbErr, -1008); ///TODO nice error codes;
if(!sens->claimed)
return returnlibUSBErr(libUsbErr, -1012); ///TODO nice error codes;
int r = libusb_interrupt_transfer(sens->devHandle, sens->inEndpointAddr, repBuf,sens->inRepSize, read, timeout);
if (r < 0)
return returnlibUSBErr(libUsbErr, r);
return returnlibUSBErr(libUsbErr, LIB_USB_OK);
}
EDIT
Wenn diese Anweisung gefolgt Speichernutzung zu überwachen:
das Leck zu finden habe ich UMDH Windows-Tool wie hier erwähnt:
Das Problem ist, dass ich CVI NI-Kompilierer verwenden muss, um meine Anwendung zu erstellen. Ich konnte die Symboltabelle nicht aus diesem Compiler holen. Mein Heap Dump Diff zeigt also nur Adressen an.
// Each log entry has the following syntax:
//
// + BYTES_DELTA (NEW_BYTES - OLD_BYTES) NEW_COUNT allocs BackTrace TRACEID
// + COUNT_DELTA (NEW_COUNT - OLD_COUNT) BackTrace TRACEID allocations
// ... stack trace ...
//
// where:
//
// BYTES_DELTA - increase in bytes between before and after log
// NEW_BYTES - bytes in after log
// OLD_BYTES - bytes in before log
// COUNT_DELTA - increase in allocations between before and after log
// NEW_COUNT - number of allocations in after log
// OLD_COUNT - number of allocations in before log
// TRACEID - decimal index of the stack trace in the trace database
// (can be used to search for allocation instances in the original
// UMDH logs).
//
+ 80000 (80000 - 0) 1 allocs BackTrace4920B3C
+ 1 ( 1 - 0) BackTrace4920B3C allocations
ntdll!RtlAllocateHeap+274
cvirte!LoadExternalModule+291EC
cvirte!CVIDynamicMemoryInfo+12B6
cvirte!CVIDynamicMemoryInfo+1528
cvirte!CVIDynamicMemoryInfo+1AF9
cvirte!mblen+84D
cvirte!_CVI_Resource_Acquire+116
cvirte!malloc+68
libUSB_HID!???+0 : 41DCE8
libUSB_HID!???+0 : 4E95C7
libUSB_HID!???+0 : 4C13BE
libUSB_HID!???+0 : 4BA09D
libUSB_HID!???+0 : 4C7ABA
libUSB_HID!???+0 : 4F92F0
libUSB_HID!???+0 : 4FB3BD
libUSB_HID!???+0 : 4FC50E
libUSB_HID!???+0 : 415C31
libUSB_HID!???+0 : 408847
libUSB_HID!???+0 : 402967
libUSB_HID!???+0 : 41B51E
libUSB_HID!???+0 : 41A021
kernel32!BaseThreadInitThunk+E
ntdll!__RtlUserThreadStart+70
I ersetzt auch alle frei, alloc, calloc und realloc cmds innerhalb LibUSB mit meinem eine eigene Implementierung Anfrage jeden einzelnen Speicher-Tracking. Diese Verfolgung zeigt kein Speicherleck. Die Menge der zugewiesenen Bytes bleibt zur Laufzeit wie erwartet konstant. Wie auch immer, die UMDH-Tools zeigen eine Heap-Allokationsdifferenz. Ich habe also keine Ideen, was ich als nächstes testen soll.
Ist es C oder C++? Löschen Sie unpassende Tags. – tilz0R
Und was ist deine Frage? Kannst du [mcve] und [ask] lesen? – Stargateur
Ich habe das unpassende Tag entfernt.Fragen: Gibt es eine spezielle Funktion, um einen internen dynamischen Speicher nach der Verwendung von libusb_interrupt_transfer freizugeben? Hat jemand eine Idee, was den kontinuierlichen Speicheranstieg während der Laufzeit verursacht? –