-
Notifications
You must be signed in to change notification settings - Fork 403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
__data_start/_end mismatch with -Bsymbolic-functions #321
Comments
Could you please try with passing -DIGNORE_PROG_DATA_START to CFLAGS, e.g. gcc -DIGNORE_PROG_DATA_START -I/usr/include -L/usr/lib/x86_64-linux-gnu loop.c -lgc -o loop |
|
Related issue (for Android): #259 |
|
Unfortunately, running It does fix it if compiling libgc with -DIGNORE_PROG_DATA_START |
Sorry, I meant compiling of libgc.so with the -D option.
Good. Could you please check if it works for the Inkscape appimage? |
|
Yup, confirmed that compiling with -DIGNORE_PROG_DATA_START, Inkscape runs successfully. Digging into it a tiny bit more, the Inkscape appimage (and normal Inkscape build) passes through Lines 456 to 461 in 4d1a516
loop skips that early return. When run inside gdb, loop has a segfault in |
Issue #321 (bdwgc). If garbage collector code is compiled with -Wl,-Bsymbolic-functions option and put into a shared library on Linux, then __data_start may belong to the client executable file while _end belongs to the shared library. Thus, the fast approach of detecting data region boundaries using [__]data_start and _end values directly is not reliable. This commit disables this approach on Linux (and Hurd) unless -D USE_PROG_DATA_START is passed to CFLAGS during libgc build (i.e., the client guarantees that either -Bsymbolic-functions is not passed and/or libgc code is linked statically into the client binary). * os_dep.c [(LINUX || HURD) && !USE_PROG_DATA_START] (GC_init_linux_data_start): Skip use of [__]data_start (regardless of IGNORE_PROG_DATA_START); add comment.
|
I have created the patch (f9b288c) but it causes fails of ASan builds and a build with -D GC_NO_SIGSETJMP |
|
I've fixed ASan builds fail. |
|
Thanks for looking into this and patching this up! How'd you fix the ASan builds? |
|
By adding an attribute to suppress ASan warnings (I don't think there's a better way because of the nature of the function): I have this patch locally, I will push it along with the fix for GC_NO_SISETJMP issue. |
(a cherry-pick of commits f9b288c, b6173fd, 1465f95 from 'master') Issue #321 (bdwgc). If garbage collector code is compiled with -Wl,-Bsymbolic-functions option and put into a shared library on Linux, then __data_start may belong to the client executable file while _end belongs to the shared library. Thus, the fast approach of detecting data region boundaries using [__]data_start and _end values directly is not reliable. This commit disables this approach on Linux (and Hurd) unless -D USE_PROG_DATA_START is passed to CFLAGS during libgc build (i.e., the client guarantees that either -Bsymbolic-functions is not passed and/or libgc code is linked statically into the client binary). * include/private/gcconfig.h [GC_NO_SIGSETJMP && MPROTECT_VDB && !DARWIN && !MSWIN32 && !MSWINCE] (MPROTECT_VDB): Undefine macro. * os_dep.c [(LINUX || HURD) && !USE_PROG_DATA_START] (GC_init_linux_data_start): Skip use of [__]data_start (regardless of IGNORE_PROG_DATA_START); add comment. * os_dep.c [NEED_FIND_LIMIT || USE_PROC_FOR_LIBRARIES && THREADS] (GC_find_limit_with_bound): Add GC_ATTR_NO_SANITIZE_ADDR attribute.
|
Is there a quick test one can do in |
What do you mean? Do you want your project configure to detect whether the above fix is applied or not? |
yes, exactly this. |
|
I think you could detect the absence of the fix by e.g.: grep "Wrong __data_start/_end pair" libgc.so |
|
Well, #include <stdio.h>
#define __USE_GNU
#include <dlfcn.h>
#ifdef __APPLE__
#define EXT "dylib"
#else
#define EXT "so"
#endif
int main() {
void *z;
Dl_info info;
int res;
void *ha;
z = dlopen("libz."EXT, RTLD_LAZY); /* load zlib */
ha = dlsym(z, "inflateEnd"); /* get address of inflateEnd in libz */
res = dladdr(ha, &info); /* get info for the function */
printf("%s\n", info.dli_fname);
return res;
}and then indeed, I can grep, the |
|
You can also write some test code using libgc.so and call GC_init, and then check the failure reason. |
|
Sure, I can probably do this, except that I don't quite see what to check for. Something with the values of |
I mean libgc.so should crash in certain scenario (if linked with -Bsymbolic-functions). But this might be not guaranteed. |
You mean load libgc.do to memory and search there using some public function address as a hint. Yes, possible. |
Unfortunately this appears to reject all the 8.0.4 installations of libgc, whether they are broken as in Ubuntu, or not. |
Maybe you could make a small reproducible test case and then insert it to configure? |
|
I'll see what I can do. |
I'm not sure this is fixable outside of disabling -Bsymbolic-functions (i.e. adding
export DEB_LDFLAGS_MAINT_STRIP=-Wl,-Bsymbolic-functionsto debian/rules, as suggested for grpc/grpc#11195 (comment)), but thought I'd ask here first before opening a report in https://bugs.launchpad.net/ubuntu/+source/libgc.In Ubuntu 20.04, libgc is compiled with
-Wl,-Bsymbolic-functions. Compiling the example file (loop.c) from https://www.hboehm.info/gc/simple_example.html with a dynamically linked libgc will have mismatch__data_start/_end.GC_data_startwill be in loop, butdata_endwill be inlibgc.so. This is noticable if you modify os_dep.c soGC_init_linux_data_startprints out these values before comparing them.apt source libgcprintf("__data_start %p _end %p\n", (void *)GC_data_start, (void *)data_end);debuild -i -us -ucdpkg -i ../libgc*.debgcc -I/usr/include -L/usr/lib/x86_64-linux-gnu loop.c -lgc -o loopexitand examininginfo proc mappings)I'm not familiar with libgc, I imagine this might also cause problems as porting.md mentions that the collector will trace all memory between DATASTART and DATAEND for root pointers.
In a real world case: for the Inkscape appimage, libgc is mapped in an address before libinkscape_base.so , resulting in a crash at startup in GC_init_linux_data_start (
ABORT_ARG2("Wrong __data_start/_end pair"...) if libgc is enabled, downstream issue: https://gitlab.com/inkscape/inkscape/-/issues/1637Edit: fixed steps to replicate. Previously suggested
self proc mappingsinstead ofinfo proc mappingsUpdate: also simpler steps to replicate are the install instructions in the readme, but replace configure with
./configure --prefix=/home/USER/gc --disable-threads CFLAGS="-Wl,-Bsymbolic-functions", w/ appropriate modifications to compiling/running loopThe text was updated successfully, but these errors were encountered: