Right free of memory while using libudev - c++

I use libudev to detect usb devices.
Initialise monitor and filter:
struct udev* udev = udev_new();
if (udev == nullptr) { /* error handling */ }
struct udev_monitor* usb = udev_monitor_new_from_netlink(udev, "udev");
udev_monitor_filter_add_match_subsystem_devtype(usb, "usb", NULL);
udev_monitor_enable_receiving(usb);
while(! canceled) { /* setup fd, poll fd, process result */ }
Then I release the allocated ressources with:
udev_monitor_unref(usb);
udev_unref(udev);
But sometimes I get
* glibc detected * ./usbtest: corrupted double-linked list: 0x084cc5d0 ***
I tried to use:
free(usb);
free(udev);
But then valgrind complaint about memory leaks.
What the right way to release the memory in this case?

According to the documentation it should be sufficient to use:
udev_unref(udev);
and here says:
udev_monitor_unref(usb);
should free that resource. If that gives you a double free, then something is not right, and you really need to debug that issue, not try to work around it by other means.

Related

FFMPEG, C++, Memory leak, what am I doing wrong?

So I've built this app that consumes an IP cameras rtsp feed and does fun things with it, however I have a small memory leak that I have only just now pinned down.
If I just run this
while (av_read_frame(input_format_context, &input_packet) >= 0) {}
It will just grow'n grow'n grow ... So what am I missing?
Am using a windows port of ffmpeg and my version is 58.9.100.0
Could it be a leak in FFMPEG itself?
From documentation:
If pkt->buf is NULL, then the packet is valid until the next
av_read_frame() or until avformat_close_input(). Otherwise the packet
is valid indefinitely. In both cases the packet must be freed with
av_packet_unref when it is no longer needed.
Something like this?
AVPacket *pPacket = av_packet_alloc();
if (!pPacket)
{
logging("failed to allocated memory for AVPacket");
return -1;
}
while (av_read_frame(pFormatContext, pPacket) >= 0)
{
auto response = decode_packet(pPacket, pCodecContext, pFrame);
if (response < 0)
break;
}
av_packet_unref(pPacket);
}
PS: Don't be a victim of cargo cult, research the source code. this is in no way a complete example. There are working projects that use ffmpeg.

VIDIOC_DQBUF hangs on camera disconnection

My application is using v4l2 running in a separate thread. If a camera gets disconnected then the user is given an appropriate message before terminating the thread cleanly. This works in the vast majority of cases. However, if the execution is inside the VIDIOC_DQBUF ioctl when the camera is disconnected then the ioctl doesn't return causing the entire thread to lock up.
My system is as follows:
Linux Kernel: 4.12.0
OS: Fedora 25
Compiler: gcc-7.1
The following is a simplified example of the problem function.
// Get Raw Buffer from the camera
void v4l2_Processor::get_Raw_Frame(void* buffer)
{
struct v4l2_buffer buf;
memset(&buf, 0, sizeof (buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
// Grab next frame
if (ioctl(m_FD, VIDIOC_DQBUF, &buf) < 0)
{ // If the camera becomes disconnected when the execution is
// in the above ioctl, then the ioctl never returns.
std::cerr << "Error in DQBUF\n";
}
// Queue for next frame
if (ioctl(m_FD, VIDIOC_QBUF, &buf) < 0)
{
std::cerr << "Error in QBUF\n";
}
memcpy(buffer, m_Buffers[buf.index].buff,
m_Buffers[buf.index].buf_length);
}
Can anybody shed any light on why this ioctl locks up and what I might do to solve this problem?
I appreciate any help offered.
Amanda
I am currently having the same issue. However, my entire thread doesn't lock up. The ioctl times out (15s) but thats way too long.
Is there a what to query V4L2 (that wont hang) if video is streaming? or at least change the ioctl timeout ?
UPDATE:
#Amanda you can change the timeout of the dequeue in the v4l2_capture driver source & rebuild the kernel/kernel module
modify the timeout in the dqueue function:
if (!wait_event_interruptible_timeout(cam->enc_queue,
cam->enc_counter != 0,
50 * HZ)) // Modify this constant
Best of luck!

reasons MmMapLockedPagesSpecifyCache throwing exception

I am a total newbie windows drivers so there may be obvious mistakes in the code.
My code allocates user space dma buffer which work fine accept when a lot of
buffers are allocated (not necessarily large buffers) on that case
MmMapLockedPagesSpecifyCache throws an exception.
The code stages that fails is as followed:
1. Use MmMapIoSpace to map physical address to kernel mode virtual address,
driver can access this virtual address, but its not accessible in user mode.
2. Use IoAllocateMdl and MmBuildMdlForNonPagedPool to build an MDL for the
mapped physical address.
3. Use MmMapLockedPagesSpecifyCache to map the physical pages described by MDL
to user mode virtual address.
Since our driver will always be the topmost driver, and run in the context of
the current process, this user mode virtual address is valid to the caller.
code snippet:
phy_buf->kernel_addr = MmMapIoSpace(phy_buf->phy_addr, phy_buf->size, MmNonCached);
phy_buf->user_mdl = IoAllocateMdl(
phy_buf->kernel_addr,
phy_buf->size,
FALSE,
FALSE,
NULL);
if(phy_buf->user_mdl)
{
MmBuildMdlForNonPagedPool(phy_buf->user_mdl);
__try{
phy_buf->user_addr = MmMapLockedPagesSpecifyCache(
phy_buf->user_mdl,
UserMode,
MmNonCached,
NULL,
FALSE,
NormalPagePriority) ;
}__except(EXCEPTION_EXECUTE_HANDLER) {
IoFreeMdl(phy_buf->user_mdl);
phy_buf->user_mdl = NULL;
DbgMessage(FATAL, "MmMapLockedPagesSpecifyCache failed on EXCEPTION_EXECUTE_HANDLER\n");
return NULL;
}
if (phy_buf->user_addr == NULL)
{
IoFreeMdl(phy_buf->user_mdl);
phy_buf->user_mdl = NULL;
DbgMessage(FATAL, "MmMapLockedPagesSpecifyCache failed\n");
}
Also how can I get (or print) exact exception that is thrown.

winsock and new thread does not release memory

I have a really strange problem. Looking for the cause on the web and try everything. Nothing helps.
First case:
(This works exactly as expected. Windows task manager shows the constant memory size, and does not increase.)
unsigned long WINAPI thfun(void * arg)
{
::Sleep(50);
::ExitThread(0);
return 0;
}
int main(int argc, const wchar_t ** argv)
{
HANDLE th = 0;
DWORD thid, err;
while (true)
{
th = ::CreateThread(0, 0, thfun, 0, 0, &thid);
if (!th)
{
err = ::GetLastError();
}
::WaitForSingleObject(th, INFINITE);
}
return 0;
}
Second case:
unsigned long WINAPI thfun(void * arg)
{
::Sleep(50);
::ExitThread(0);
return 0;
}
int main(int argc, const wchar_t ** argv)
{
WORD ver;
WSADATA wsadata;
ver = MAKEWORD(2, 2);
if (WSAStartup(ver, &wsadata)) return 1;
::Sleep(50);
HANDLE th = 0;
DWORD thid, err;
while (true)
{
th = ::CreateThread(0, 0, thfun, 0, 0, &thid);
if (!th)
{
err = ::GetLastError();
}
::WaitForSingleObject(th, INFINITE);
}
return 0;
}
If I call any function from winsock least once created threads do not release memory.
Windows task manager shows ever-growing memory of my application.
What should I do so that I achieve the same behavior as in the first case when I use winsock?
I use visual studio 2013
Thank you very much for any help
You do not close your thread handles. A common error.
Your core loop should look like that:
while (true)
{
th = ::CreateThread(0, 0, thfun, 0, 0, &thid);
if (!th)
{
err = ::GetLastError();
}
::WaitForSingleObject(th, INFINITE);
CloseHandle(th);
}
That problem exists in both of your examples. That memory grow of the second sample can be a side effect.
ExitThread(0) is never a good idea and I do not understand why Microsoft recommand it for C. As the Winsock API should not have any destructor, it should not be a problem. Nevertheless, do not use it.
UPDATE
I tested your code as release on a Windows 7 64bit SP1 System with Antivira personal installed (my gaming machine). Also on my Windows 8 VM (parallels). Both system did not show the problems you described and show in your video. This is IMHO good news for you, because it seems a problem of your installation and not a general problem.
The video shows a leak of only a few bytes per ended thread and strict linear growing per thread. This looks for me like thread associated information, usually stored nowadays in TLS (Thread Local Storage). Also it only appears when you init The WSASocket system. If the WSASocket system itself would be the problem, we would found reports of it for sure(but I didn't). I believe a hook DLL is causing that problem, a DLL is informed over the DllMain of any started or ended thread of the process. Any virus scanner or keyboard addon(!) can cause such a problem as they usually use hook DLLs and manipulate IOs like pipes and sockets.
Unfortunatly I only know one way to find out:
Make a release canditate of your sample. Make sure the problem exist.
Make a clean install of Windows 7
Install step by step the environment you use on your produktive system. Make sure you restart the Computer after every step.
Hopefully find the culprit.
Deactivating or uninstall hooks may help but need not. Unfortunately installing programs on windows system is maximal inversive.
Sorry for not heaving the easy answer.

Segmentation fault when connecting to MySQL

I have this code in a big project that makes a connection to a MySQL database, and does not work:
boost::shared_ptr<sql::Connection> connection;
sql::Driver *driver = get_driver_instance();
assert(driver != 0);
std::string server = "servname", user = "pietro", password = "abc";
try
{
connection.reset(driver->connect(server, user, password));
assert(connection != 0);
if(connection->isClosed() == false) // <-- segmentation fault
{
}
}
I get a segmentation fault where indicated (all parameters are valid).
However, this same code works in a test project.
Going into the sql::Connection::isClosed() member function with a debugger, I obtain no information about the possible cause; here is where I get:
mysql-connector-c++-1.0.5/driver/mysql_connection.cpp - line 430
/* {{{ MySQL_Connection::checkClosed() -I- */
void
MySQL_Connection::checkClosed()
{
CPP_ENTER_WL(intern->logger, "MySQL_Connection::checkClosed");
if (!intern->is_valid) {
throw sql::SQLException("Connection has been closed");
}
}
This checkClosed() function is successfully executed seven times from connection.reset() just before. The value of the "intern" pointer does not change and is not null at this stage.
When I check if the connection is closed, the checkClosed() function is run again. Now the "intern" pointer value is 0x8, a location I cannot access.
Here I get a SIGSEGV, segmentation fault.
Let me know if you would like the disassembled code...
Platform:
MySQL 5.x
MySQL Connector/C++ 1.0.5
Linux - OpenSuse 11.4
P.S.:
I noticed that all the shared_ptr's member functions work as expected:
connection.get(); // = 0x8fb4a0
connection.use_count(); // = 1
connection.unique(); // = 1
while all the calls done on the pointed object cause the segmentation fault (SIGABRT):
connection->getClientInfo();
connection->isClosed();
either your connection deleted, or you have memory corruption. use valgrind to find answer