C 内存泄漏同步读取中断通过libUSB传输数据

C 内存泄漏同步读取中断通过libUSB传输数据,c,windows,memory-leaks,usb,libusb,C,Windows,Memory Leaks,Usb,Libusb,我发现了一个内存泄漏,使用libUSB同步通过USB中断传输读取数据。我的简单用户程序本身不使用任何动态内存分配。在内部,libusb过度使用动态内存分配。通信流按预期工作。在使用libusb\u中断\u传输后,是否有特殊功能来释放任何内部动态内存?有人知道是什么导致运行时内存不断增加吗 我的协议实现了双向握手。因此,一个简单的数据交换会导致OUT(请求)、IN(Ack/Nack)、IN(响应)和OUT(Ack/Nack)传输。报告大小为32字节,outEndpointAddr为1,inEnd

我发现了一个内存泄漏,使用libUSB同步通过USB中断传输读取数据。我的简单用户程序本身不使用任何动态内存分配。在内部,libusb过度使用动态内存分配。通信流按预期工作。在使用libusb\u中断\u传输后,是否有特殊功能来释放任何内部动态内存?有人知道是什么导致运行时内存不断增加吗

我的协议实现了双向握手。因此,一个简单的数据交换会导致OUT(请求)、IN(Ack/Nack)、IN(响应)和OUT(Ack/Nack)传输。报告大小为32字节,outEndpointAddr为1,inEndpointAddr为129,下面是相关的代码片段

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);
}
我还将libUSB中所有的free、alloc、calloc和realloc cmd替换为我自己的实现,跟踪每个内存请求。此跟踪未显示任何内存泄漏。正如预期的那样,在运行时分配的字节量保持不变。无论如何,UMDH工具显示了堆分配的差异。所以我完全不知道下一台atm机要测试什么

我的简单用户程序不使用任何动态内存分配

不幸的是,那些
libusb\u xxx\u transfer
函数在内部使用
malloc()。但也支持在退出调用方之前执行相应的
free()

该内存通常不会返回到操作系统,而是保留在应用程序中,以便在下一次
malloc()
调用中使用。因此,您将在任务管理器中看到一些内存使用情况


这就是为什么你需要更好的工具来检测实际的内存泄漏,比如valgrind。

对不起,伙计们,我把我的程序移植到了minGW gcc,所有的链接都按预期工作。我对libusb for CVI编译器的移植并不完全正确。现在我使用标准dll,内存泄漏消失了// 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