How to avoid a set of values /collected in .so callback calls/ from
pointing to same address?
Hi all.
It seems that here's a problem with a pointer constantly bound to some
fixed address.
// compile with: g++ 1.cc -o test -Wall `pkg-config --cflags --libs
glib-2.0` -lgthread-2.0
// or g++ 1.cc -o testq -lglib-2.0 -I/usr/include/glib-2.0 -I/usr/
lib64/glib-2.0/include/ -lgthread-2.0c
#include <glib.h>
#include <iostream>
#include <string.h>
int counter;
GAsyncQueue *q;
typedef struct MyStruct {
int foo;
char *data;
} *MyStructPtr;
gpointer looper(gpointer data) {
g_thread_init(NULL);
while (1) {
while (g_async_queue_length(q) > 0) {
MyStructPtr xtransport;
xtransport = new struct MyStruct;
xtransport = (MyStructPtr)g_async_queue_try_pop(q);
// The actual code is acting as weird, as if we have here, xtransport-
data = last_text_value_ever_received;
std::cout << "str # " << xtransport->foo << ":" << xtransport-
data << ":str\n";
}
}
}
void adder(char *data) {
char *processedData;
// someExternalAPICallToprocessData(data, &processeddata);
processedData = (char *)data;
MyStructPtr dtransport;
dtransport = new struct MyStruct;
dtransport->data = processedData;//processeddata;
dtransport->foo = ++counter;
g_async_queue_push(q, (gpointer*) dtransport);
}
int main() {
GThread *l;
g_thread_init(NULL);
q = g_async_queue_new();
l = g_thread_create(looper, NULL, FALSE, NULL);
sleep(2);
char *t;
t = strdupa("1111");
adder(t);
t = strdupa("222");
adder(t);
sleep (5);
}
This is a working lab mockup of some larger project. On the project, a
strange behavior is noticed;
instead of main(), we're sitting in a callback function, that gets
some data from a system component. Trying to print (e.g. cout) that
data before putting to queues, can get something like:
N1 (in Callback): aaaabbbbcccc
N2 (in Callback): bbbbaaaacccc.
Same, if the access to (newly set pointer ) dtransport->data is made
in a same code where it was created (mainloop/callback function)t;
that's fine.
But can't get the correct value of the first elements in the queue!
Data fields is always the same - accessing the collected data via
queue, can get only the value that was set in last callback; evil
pointer hell supposed!
str #1: bbbbaaaacccc.
str #2: bbbbaaaacccc.
The question is, **would that
someExternalAPICallTOprocessData() fill &processeddata with a pointer
to a fixed address storing only the data of last call**?
How to get a copy of char* being returned and safely put it into
MyStruct ?Note, that a next function uses offsets...
process(dequeued->data);
void process(char *data) {
my *ptr = NULL;
ptr = data + SOME_SIZE_CONST
...
}
And somehow, memcpy'ng the content of processedData seems to segfault
the .so library which contains someExternalAPICallTOprocessData(). In
the mockup context, it is the end of adder(); in the real context it
is end of callback function to kernel networking stuff; so funny.
gcc 4.4.5.
cheers,