Valgrind检测到DBus应用存在内存泄漏的原因分析及修复方案咨询
From your Valgrind trace and the way you've structured your DBus threads, that growing memory leak stems from unprocessed messages stuck in the connection's internal queue or incomplete cleanup of resources from your send operation. Let's walk through the exact fixes you need to apply:
1. Fix the Read Thread: Dispatch Messages After Reading
Your read thread calls dbus_connection_read_write(connection, 0) to pull data into the buffer, but this only retrieves raw bytes—it doesn't parse or clean up the message objects. The leaked message headers (from dbus_message_new_empty_header) are lingering because they're never processed.
Update your read thread loop to include dispatch logic after every read:
while (/* your thread running flag */) { // Read available data (0 = non-blocking; use -1 for blocking wait if needed) dbus_connection_read_write(conn, 0); // Dispatch until all pending messages are handled DBusDispatchStatus status; do { status = dbus_connection_dispatch(conn); } while (status == DBUS_DISPATCH_DATA_REMAINS); // Add any thread-specific delay or logic here }
This ensures every message read from the bus is parsed, processed, and its associated memory is released immediately.
2. Clean Up Resources from dbus_connection_send_with_reply_and_block
Even though this is a blocking function, you must explicitly free the reply message and error object it returns:
DBusError err; dbus_error_init(&err); DBusMessage *reply = dbus_connection_send_with_reply_and_block( conn, your_outgoing_msg, YOUR_TIMEOUT_MS, &err ); // Process and free the reply if it exists if (reply != NULL) { // Handle reply content here dbus_message_unref(reply); // Critical: Don't skip this! } // Clean up error object if an error occurred if (dbus_error_is_set(&err)) { // Log or handle the error dbus_error_free(&err); }
Skipping dbus_message_unref will leave the reply message (and its internal headers) allocated forever.
3. Validate Connection Thread Safety and Lifecycle
Since you're sharing one DBus connection across two threads:
- Use connections created with
dbus_bus_getordbus_connection_open_private(both are thread-safe for concurrent send/read operations) - Manage the connection's reference count with
dbus_connection_ref/dbus_connection_unrefto avoid closing it while either thread is still active. Only calldbus_connection_closeonce both threads have finished using the connection.
4. Ensure All Incoming Messages Are Handled
If your app is receiving signals or unanticipated replies that aren't processed, they'll pile up in the connection's queue. Register message filters with dbus_connection_add_filter to handle all expected message types—this ensures those messages are consumed and their memory is freed.
内容的提问来源于stack exchange,提问作者narayan thakkar

