Dbus application consumes full cache memory , during Tx and Rx of message using Dbus API- Memory leak

deepak jewargi djewargi at gmail.com
Mon Aug 14 10:46:25 UTC 2023


Hi All,


I have implemented a dbus application using dbus-1 API's on the linux
platform.

Facing issues ,when we run continuously in a loop. dbsu Tx (public)and
dbus Rx (subscribe)  runs out of cache memory  and  both Tx and Rx getting
terminated  attached source and header files,

[image: image.png]



*1. Publish functions : Tx dbus application *

/*

* method: method name

* payload: data that needs to be sent/published.

* payloadlen: length of payload in bytes.

* return: 0 on success, -1 on failure.

*/

/*

* method: method name

* payload: data that needs to be sent/published.

* payloadlen: length of payload in bytes.

* return: 0 on success, -1 on failure.

*/

int dbus_client_publish (char *method, void *payload, int payloadlen)

{

DBusMessage *msg;

DBusMessageIter args;

DBusMessageIter subiter;

DBusError err;


int returnValue = -1;

int SignalRetryCount = 0;

int SendRetryCount = 0;

int maxRetries = 3;

int successConnect = 0;

int successSend = 0;


char *pload = (char*) payload;


if(pload != NULL)

{

// initialize the errors

dbus_error_init (&err);


while (SignalRetryCount < maxRetries && !successConnect)

{


// create a new method call and check for errors

msg = dbus_message_new_signal (DBUS_OBJECT_NAME, // object name of the
signal

DBUS_INTERFACE_NAME, // interface name of the signal

method); // name of the signal


if(NULL == msg)

{

dbus_error_free (&err);


SignalRetryCount++;

}

else

{

// append arguments

dbus_message_iter_init_append (msg, &args);


// For appending args, doc says to use the following 3 for container types.

// We can view the cmd buffer as a char buffer and send

dbus_message_iter_open_container (&args, DBUS_TYPE_ARRAY, "y", &subiter);

dbus_message_iter_append_fixed_array (&subiter, DBUS_TYPE_BYTE, &pload,
payloadlen);


dbus_message_iter_2. Rx application with multiple functions

close_container (&args, &subiter);


// We probably don't need a reply

flogv("dbustest.log","%s:%d dbus_connection_send called",__func__,__LINE__);


while (SendRetryCount < maxRetries && !successSend)

{

if(!dbus_connection_send (txconn, msg, NULL))

{

flogd("dbustest.log","%s:%d Out Of Memory!",__func__,__LINE__);

SendRetryCount++;

}

else

{

successConnect = 1;

successSend = 1;

returnValue = 0;

break;

}

}

}

}


dbus_connection_flush (txconn);


// free message

dbus_message_unref (msg);

dbus_error_free (&err);


//flogd("dbustest.log","%s:%d Exit (no errors)",__func__,__LINE__);

}


// print ( dbus_client_publish, returnValue)


return returnValue;

}





*2. Rx application - with multiple functions *


/* This API subscribes for a particular busname/interface/method. The
callback would

* be called once the subscribed information is available.

*Note: subscribe = listen => server bus name (e.g.,).

*

* method: method name you want to listen to.

* cb: callback to be called once the subscribed information is available.

* return: 0 on success, -1 on failure.

*/

int dbus_client_subscribe (int num_pairs, ...)

{

flogd("dbustest.log","%s:%d Entry",__func__,__LINE__);

int i;

va_list vargs;

rx_thread_args_t *args;


if (num_pairs > 32)

return -1;


args = (rx_thread_args_t *) malloc (sizeof(rx_thread_args_t));

if (args == NULL)

return -1;


args->num_pairs = num_pairs;

va_start(vargs, num_pairs);

for (i = 0; i < num_pairs; i++)

{

char *m = va_arg(vargs, char *);

sprintf (args->mthod_cb[i].method, "%s", m);

args->mthod_cb[i].cb = va_arg(vargs, void *);

}

va_end(vargs);


if (pthread_create (&dbus_client_rx_thread, NULL,
dbus_client_receive_thread, (void *)args) != 0)

{

floge("dbustest.log","%s:%d Client Error: Rx Thread creation failed; errno
= %d (%s)",__func__,__LINE__, errno, strerror(errno));

return -1;

}


// free(args);


flogd("dbustest.log","%s:%d exit",__func__,__LINE__);

return 0;

}


* Receive thread */

static void *dbus_client_receive_thread (void *arg)

{

flogd("dbustest.log","%s:%d Entry",__func__,__LINE__);


rx_thread_args_t *args = (rx_thread_args_t *) arg;


DBusError err;

int rc;

dbus_ctx_t *lctx;


flogd("dbustest.log","%s:%d Entry",__func__,__LINE__);

ev_base = event_base_new ();


// initialise the error

dbus_error_init(&err);


lctx = dbus_init(ev_base);

lctx->args = args;

rc = event_base_dispatch(ev_base);

if (rc == -1)

{

flogd("dbustest.log","%s:%d %s: Exit (rc = %d)\n",__func__,__LINE__, rc);

}

else

{

dbus_error_free(&err);

}




return 0;

}


static dbus_ctx_t *dbus_init(struct event_base *eb)

{

flogd("dbustest.log","%s:%d Entry",__func__,__LINE__);

DBusConnection *conn = rxconn;

DBusError err;

dbus_ctx_t *ctx = &gctx;

char match_buffer[255];

int len1;


flogd("dbustest.log","%s:%d Entry",__func__,__LINE__);


dbus_connection_set_exit_on_disconnect(conn, FALSE);


ctx->conn = conn;

ctx->evbase = eb;

event_assign(&ctx->dispatch_ev, eb, -1, EV_TIMEOUT, dispatch, ctx);


if (!dbus_connection_set_watch_functions(conn, add_watch, remove_watch,

toggle_watch, ctx, NULL)) {

flogd("dbustest.log","%s:%ddbus_connection_set_watch_functions() failed"
,__func__,__LINE__);

goto out;

}


dbus_connection_set_dispatch_status_function(conn, handle_dispatch_status,

ctx, NULL);


// add a rule for which messages we want to see

len1 = strlen("type='signal',interface='");

sprintf (match_buffer, "%s", "type='signal',interface='");

sprintf (match_buffer+len1, "%s", DBUS_INTERFACE_NAME);

sprintf(match_buffer+len1+strlen(DBUS_INTERFACE_NAME), "%s", "'");

dbus_error_init(&err);

dbus_bus_add_match(conn, match_buffer, &err); // see signals from the given
interface

dbus_connection_flush(conn);

if (dbus_error_is_set(&err)) {

flogd("dbustest.log","%s:%d Match Error (%s)",__func__,__LINE__, err.message
);

dbus_error_free(&err);

goto out;

}

dbus_error_free(&err);


if (dbus_connection_register_object_path(conn, DBUS_OBJECT_NAME,
&dbus_vtable,

ctx) != TRUE) {

flogd("dbustest.log","%s:%d failed to register object path\n"
,__func__,__LINE__);

goto out;

}



dbus_connection_unref(conn);


return ctx;


out:

if (conn) {

dbus_connection_close(conn);

dbus_connection_unref(conn);

}

flogd("dbustest.log","%s:%d Exit",__func__,__LINE__);

return NULL;

}



Please suggest to me, Is any dbus API  to avoid the above application
consuming lots of system cache memory ?

Regards,
Deepak Jewargi

-------------------------------------------------------------------------------------------------------------------------------------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/dbus/attachments/20230814/b18c9f0b/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 388381 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/dbus/attachments/20230814/b18c9f0b/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dbus-client.c
Type: text/x-csrc
Size: 24975 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/dbus/attachments/20230814/b18c9f0b/attachment-0001.c>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: dbus-client.h
Type: text/x-chdr
Size: 2259 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/dbus/attachments/20230814/b18c9f0b/attachment-0001.h>


More information about the dbus mailing list