Fix mem leak with libusb by introducing buses/usbbus.c
Now call only once usb_init(); usb_find_busses(); usb_find_devices() instead of multiple calls in several scan() then open() This fixes the following leaks: ==1159== 8 bytes in 1 blocks are definitely lost in loss record 9 of 102 ==1159== at 0x4C28BED: malloc (vg_replace_malloc.c:263) ==1159== by 0x53D9931: usb_parse_configuration (in /lib/x86_64-linux-gnu/libusb-0.1.so.4.4.4) ==1159== by 0x53DB8B1: usb_os_find_devices (in /lib/x86_64-linux-gnu/libusb-0.1.so.4.4.4) ==1159== by 0x53D8FDC: usb_find_devices (in /lib/x86_64-linux-gnu/libusb-0.1.so.4.4.4) ==1159== by 0x4E41D79: pn53x_usb_scan (in /usr/lib/x86_64-linux-gnu/libnfc.so.4.0.0) ==1159== ==1159== 8 bytes in 1 blocks are definitely lost in loss record 10 of 102 ==1159== at 0x4C28BED: malloc (vg_replace_malloc.c:263) ==1159== by 0x53D9931: usb_parse_configuration (in /lib/x86_64-linux-gnu/libusb-0.1.so.4.4.4) ==1159== by 0x53DB8B1: usb_os_find_devices (in /lib/x86_64-linux-gnu/libusb-0.1.so.4.4.4) ==1159== by 0x53D8FDC: usb_find_devices (in /lib/x86_64-linux-gnu/libusb-0.1.so.4.4.4) ==1159== by 0x4E42CC7: pn53x_usb_open (in /usr/lib/x86_64-linux-gnu/libnfc.so.4.0.0) ==1159== by 0x4E351E6: nfc_open (in /usr/lib/x86_64-linux-gnu/libnfc.so.4.0.0)
This commit is contained in:
parent
59227c3dd3
commit
9dcf7378b6
5 changed files with 120 additions and 97 deletions
|
@ -3,7 +3,7 @@
|
||||||
AM_CPPFLAGS = $(all_includes) $(LIBNFC_CFLAGS)
|
AM_CPPFLAGS = $(all_includes) $(LIBNFC_CFLAGS)
|
||||||
|
|
||||||
noinst_LTLIBRARIES = libnfcbuses.la
|
noinst_LTLIBRARIES = libnfcbuses.la
|
||||||
libnfcbuses_la_SOURCES = uart.c uart.h
|
libnfcbuses_la_SOURCES = uart.c uart.h usbbus.c usbbus.h
|
||||||
libnfcbuses_la_CFLAGS = -I$(top_srcdir)/libnfc
|
libnfcbuses_la_CFLAGS = -I$(top_srcdir)/libnfc
|
||||||
|
|
||||||
EXTRA_DIST = uart_posix.c uart_win32.c
|
EXTRA_DIST = uart_posix.c uart_win32.c
|
||||||
|
|
61
libnfc/buses/usbbus.c
Normal file
61
libnfc/buses/usbbus.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*-
|
||||||
|
* Public platform independent Near Field Communication (NFC) library
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013, Romuald Conty
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file usbbus.c
|
||||||
|
* @brief libusb 0.1 driver wrapper
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include "config.h"
|
||||||
|
#endif // HAVE_CONFIG_H
|
||||||
|
|
||||||
|
#include "usbbus.h"
|
||||||
|
#include "log.h"
|
||||||
|
#define LOG_CATEGORY "libnfc.buses.usbbus"
|
||||||
|
#define LOG_GROUP NFC_LOG_GROUP_DRIVER
|
||||||
|
|
||||||
|
// Global flag to know if usb_init() has already been called or not
|
||||||
|
bool usb_initialized=false;
|
||||||
|
|
||||||
|
int usb_prepare(void) {
|
||||||
|
if (usb_initialized)
|
||||||
|
return 0;
|
||||||
|
usb_init();
|
||||||
|
usb_initialized = true;
|
||||||
|
|
||||||
|
int res;
|
||||||
|
// usb_find_busses will find all of the busses on the system. Returns the
|
||||||
|
// number of changes since previous call to this function (total of new
|
||||||
|
// busses and busses removed).
|
||||||
|
if ((res = usb_find_busses()) < 0) {
|
||||||
|
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB busses (%s)", _usb_strerror(res));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// usb_find_devices will find all of the devices on each bus. This should be
|
||||||
|
// called after usb_find_busses. Returns the number of changes since the
|
||||||
|
// previous call to this function (total of new device and devices removed).
|
||||||
|
if ((res = usb_find_devices()) < 0) {
|
||||||
|
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB devices (%s)", _usb_strerror(res));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
49
libnfc/buses/usbbus.h
Normal file
49
libnfc/buses/usbbus.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*-
|
||||||
|
* Public platform independent Near Field Communication (NFC) library
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013, Romuald Conty
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file usbbus.h
|
||||||
|
* @brief libusb 0.1 driver header
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFC_BUS_USB_H__
|
||||||
|
# define __NFC_BUS_USB_H__
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
// Under POSIX system, we use libusb (>= 0.1.12)
|
||||||
|
#include <usb.h>
|
||||||
|
#define USB_TIMEDOUT ETIMEDOUT
|
||||||
|
#define _usb_strerror( X ) strerror(-X)
|
||||||
|
#else
|
||||||
|
// Under Windows we use libusb-win32 (>= 1.2.5)
|
||||||
|
#include <lusb0_usb.h>
|
||||||
|
#define USB_TIMEDOUT 116
|
||||||
|
#define _usb_strerror( X ) usb_strerror()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// Global flag to know if usb_init() has already been called or not
|
||||||
|
extern bool usb_initialized;
|
||||||
|
|
||||||
|
int usb_prepare(void);
|
||||||
|
|
||||||
|
#endif // __NFC_BUS_USB_H__
|
|
@ -54,24 +54,12 @@ Thanks to d18c7db and Okko for example code
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
// Under POSIX system, we use libusb (>= 0.1.12)
|
|
||||||
#include <usb.h>
|
|
||||||
#define USB_TIMEDOUT ETIMEDOUT
|
|
||||||
#define _usb_strerror( X ) strerror(-X)
|
|
||||||
#else
|
|
||||||
// Under Windows we use libusb-win32 (>= 1.2.5)
|
|
||||||
#include <lusb0_usb.h>
|
|
||||||
#define USB_TIMEDOUT 116
|
|
||||||
#define _usb_strerror( X ) usb_strerror()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
|
|
||||||
#include "nfc-internal.h"
|
#include "nfc-internal.h"
|
||||||
|
#include "buses/usbbus.h"
|
||||||
#include "chips/pn53x.h"
|
#include "chips/pn53x.h"
|
||||||
#include "chips/pn53x-internal.h"
|
#include "chips/pn53x-internal.h"
|
||||||
#include "drivers/acr122_usb.h"
|
#include "drivers/acr122_usb.h"
|
||||||
|
@ -309,23 +297,8 @@ static size_t
|
||||||
acr122_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
|
acr122_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
|
||||||
{
|
{
|
||||||
(void)context;
|
(void)context;
|
||||||
usb_init();
|
|
||||||
|
|
||||||
int res;
|
usb_prepare();
|
||||||
// usb_find_busses will find all of the busses on the system. Returns the
|
|
||||||
// number of changes since previous call to this function (total of new
|
|
||||||
// busses and busses removed).
|
|
||||||
if ((res = usb_find_busses()) < 0) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB busses (%s)", _usb_strerror(res));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// usb_find_devices will find all of the devices on each bus. This should be
|
|
||||||
// called after usb_find_busses. Returns the number of changes since the
|
|
||||||
// previous call to this function (total of new device and devices removed).
|
|
||||||
if ((res = usb_find_devices()) < 0) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB devices (%s)", _usb_strerror(res));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t device_found = 0;
|
size_t device_found = 0;
|
||||||
uint32_t uiBusIndex = 0;
|
uint32_t uiBusIndex = 0;
|
||||||
|
@ -446,23 +419,7 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
||||||
struct usb_bus *bus;
|
struct usb_bus *bus;
|
||||||
struct usb_device *dev;
|
struct usb_device *dev;
|
||||||
|
|
||||||
usb_init();
|
usb_prepare();
|
||||||
|
|
||||||
int res;
|
|
||||||
// usb_find_busses will find all of the busses on the system. Returns the
|
|
||||||
// number of changes since previous call to this function (total of new
|
|
||||||
// busses and busses removed).
|
|
||||||
if ((res = usb_find_busses()) < 0) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB busses (%s)", _usb_strerror(res));
|
|
||||||
goto free_mem;
|
|
||||||
}
|
|
||||||
// usb_find_devices will find all of the devices on each bus. This should be
|
|
||||||
// called after usb_find_busses. Returns the number of changes since the
|
|
||||||
// previous call to this function (total of new device and devices removed).
|
|
||||||
if ((res = usb_find_devices()) < 0) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB devices (%s)", _usb_strerror(res));
|
|
||||||
goto free_mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||||
if (connstring_decode_level > 1) {
|
if (connstring_decode_level > 1) {
|
||||||
|
@ -483,7 +440,7 @@ acr122_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
||||||
// Retrieve end points
|
// Retrieve end points
|
||||||
acr122_usb_get_end_points(dev, &data);
|
acr122_usb_get_end_points(dev, &data);
|
||||||
// Claim interface
|
// Claim interface
|
||||||
res = usb_claim_interface(data.pudh, 0);
|
int res = usb_claim_interface(data.pudh, 0);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to claim USB interface (%s)", _usb_strerror(res));
|
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to claim USB interface (%s)", _usb_strerror(res));
|
||||||
usb_close(data.pudh);
|
usb_close(data.pudh);
|
||||||
|
|
|
@ -37,24 +37,12 @@ Thanks to d18c7db and Okko for example code
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
// Under POSIX system, we use libusb (>= 0.1.12)
|
|
||||||
#include <usb.h>
|
|
||||||
#define USB_TIMEDOUT ETIMEDOUT
|
|
||||||
#define _usb_strerror( X ) strerror(-X)
|
|
||||||
#else
|
|
||||||
// Under Windows we use libusb-win32 (>= 1.2.5)
|
|
||||||
#include <lusb0_usb.h>
|
|
||||||
#define USB_TIMEDOUT 116
|
|
||||||
#define _usb_strerror( X ) usb_strerror()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
|
|
||||||
#include "nfc-internal.h"
|
#include "nfc-internal.h"
|
||||||
|
#include "buses/usbbus.h"
|
||||||
#include "chips/pn53x.h"
|
#include "chips/pn53x.h"
|
||||||
#include "chips/pn53x-internal.h"
|
#include "chips/pn53x-internal.h"
|
||||||
#include "drivers/pn53x_usb.h"
|
#include "drivers/pn53x_usb.h"
|
||||||
|
@ -186,23 +174,7 @@ static size_t
|
||||||
pn53x_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
|
pn53x_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const size_t connstrings_len)
|
||||||
{
|
{
|
||||||
(void)context;
|
(void)context;
|
||||||
usb_init();
|
usb_prepare();
|
||||||
int res;
|
|
||||||
// usb_find_busses will find all of the busses on the system. Returns the
|
|
||||||
// number of changes since previous call to this function (total of new
|
|
||||||
// busses and busses removed).
|
|
||||||
if ((res = usb_find_busses()) < 0) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB busses (%s)", _usb_strerror(res));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// usb_find_devices will find all of the devices on each bus. This should be
|
|
||||||
// called after usb_find_busses. Returns the number of changes since the
|
|
||||||
// previous call to this function (total of new device and devices removed).
|
|
||||||
if ((res = usb_find_devices()) < 0) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB devices (%s)", _usb_strerror(res));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t device_found = 0;
|
size_t device_found = 0;
|
||||||
uint32_t uiBusIndex = 0;
|
uint32_t uiBusIndex = 0;
|
||||||
struct usb_bus *bus;
|
struct usb_bus *bus;
|
||||||
|
@ -227,7 +199,7 @@ pn53x_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const s
|
||||||
usb_dev_handle *udev = usb_open(dev);
|
usb_dev_handle *udev = usb_open(dev);
|
||||||
|
|
||||||
// Set configuration
|
// Set configuration
|
||||||
res = usb_set_configuration(udev, 1);
|
int res = usb_set_configuration(udev, 1);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set USB configuration (%s)", _usb_strerror(res));
|
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set USB configuration (%s)", _usb_strerror(res));
|
||||||
usb_close(udev);
|
usb_close(udev);
|
||||||
|
@ -330,23 +302,7 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
||||||
struct usb_bus *bus;
|
struct usb_bus *bus;
|
||||||
struct usb_device *dev;
|
struct usb_device *dev;
|
||||||
|
|
||||||
usb_init();
|
usb_prepare();
|
||||||
|
|
||||||
int res;
|
|
||||||
// usb_find_busses will find all of the busses on the system. Returns the
|
|
||||||
// number of changes since previous call to this function (total of new
|
|
||||||
// busses and busses removed).
|
|
||||||
if ((res = usb_find_busses()) < 0) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB busses (%s)", _usb_strerror(res));
|
|
||||||
goto free_mem;
|
|
||||||
}
|
|
||||||
// usb_find_devices will find all of the devices on each bus. This should be
|
|
||||||
// called after usb_find_busses. Returns the number of changes since the
|
|
||||||
// previous call to this function (total of new device and devices removed).
|
|
||||||
if ((res = usb_find_devices()) < 0) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to find USB devices (%s)", _usb_strerror(res));
|
|
||||||
goto free_mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
for (bus = usb_get_busses(); bus; bus = bus->next) {
|
||||||
if (connstring_decode_level > 1) {
|
if (connstring_decode_level > 1) {
|
||||||
|
@ -365,7 +321,7 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring)
|
||||||
// Retrieve end points
|
// Retrieve end points
|
||||||
pn53x_usb_get_end_points(dev, &data);
|
pn53x_usb_get_end_points(dev, &data);
|
||||||
// Set configuration
|
// Set configuration
|
||||||
res = usb_set_configuration(data.pudh, 1);
|
int res = usb_set_configuration(data.pudh, 1);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set USB configuration (%s)", _usb_strerror(res));
|
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "Unable to set USB configuration (%s)", _usb_strerror(res));
|
||||||
if (EPERM == -res) {
|
if (EPERM == -res) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue