Wednesday, 15 January 2014

c++ - Shared library on Android: String assignments (=) to struct values cause segfault (dlfree) -



c++ - Shared library on Android: String assignments (=) to struct values cause segfault (dlfree) -

i developing shared library in c++ android devices.

while writing tests stumbled on unusual behaviour causes segfault (dlfree), when calling function in illustration code.

first of all:

the test calls library function links dynamically against library. i compiled library , test linux , windows desktops. there run without causing segfault. linking statically, segfault not appear on android.

example code

typedef unsigned int dbruleid; typedef std::string dbruletarget; struct dbrule { dbruleid id; //int dbruletarget target; //std::string }; //segfault variant bool getrule(dbruleid id, dbrule& rule) { rule.target = "i causing segfault!"; homecoming true; } //working variant bool getrule(dbruleid id, dbrule& rule) { //nothing set homecoming true; }

segmentation fault

build fingerprint: 'generic/sdk/generic:3.0/honeycomb/104254:eng/test-keys' pid: 525, tid: 525 >>> /data/local/testrulesdb <<< signal 11 (sigsegv), code 1 (segv_maperr), fault addr deadbaad r0 deadbaad r1 0000000c r2 00000027 r3 00000000 r4 00000080 r5 aff46658 r6 00013000 r7 00000004 r8 00000004 r9 00013d3c 10 00000000 fp bec61a14 ip ffffffff sp bec61950 lr aff193e9 pc aff15f58 cpsr 00000030 #00 pc 00015f58 /system/lib/libc.so #01 pc 00012d2a /system/lib/libc.so (dlfree)

edit - new findings

if dbrule struct, passed function, initialized values works fine, otherwise results in segmentation fault.

//works dbrule rule_1 = { 0, "target"}; //works not dbrule rule_1 = { 0, ""}; //works not dbrule rule_1;

could please explain me? , best way initialize default?

the questions are

what doing wrong, missing? is there mechanism tries delete allocated memory on heap more once?

i fired valgrind on desktop already, there no errors shown.

thanks in advance!

your issue empty std::string objects utilize same location internal storage: internal storage of empty std::string same static member. , stl uses location determine whether or not should deallocate std::string's internal storage.

this works statically compiled code, or when not passing empty strings across dynamic library boundaries; when dealing dynamic libraries, issues start crop up: both executable , each dynamic library have different storage locations empty std::string.

so here going on: when code executes:

rule.target = "i causing segfault!";

the first thing happens internal storage of rule.target deallocated. if rule.target empty std::string (regardless of how got way), point global empty std::string storage of code initialized. if did not happen within library, library conclude not empty string , seek deallocate storage. since statically allocated client code, segfault.

one way prepare link library statically (as discovered); utilize shared version of c++ runtime (and require clients same) exports internal symbol empty std::string. final solution avoid using std::string on library's interface, straight or indirectly, if there chance receive or send empty std::string.

android c++ string

No comments:

Post a Comment