KEMBAR78
musl may relocates pointers in the dynamic section of /lib/ld-musl-x86_64.so by yanglong1010 · Pull Request #717 · async-profiler/async-profiler · GitHub
Skip to content

Conversation

@yanglong1010
Copy link
Contributor

@yanglong1010 yanglong1010 commented Feb 23, 2023

hi,
We recently had a crash, musl could relocate pointers in the dynamic section of /lib/ld-musl-x86_64.so.1

      #0  0x00007ffff741246b in raise () from /usr/glibc-compat/lib/libc.so.6
      #1  0x00007ffff7413791 in abort () from /usr/glibc-compat/lib/libc.so.6
      #2  0x00007ffff6d02709 in os::abort(bool) () from /opt/jdk1.8.0_202/jre/lib/amd64/server/libjvm.so
      #3  0x00007ffff6ec7683 in VMError::report_and_die() () from /opt/jdk1.8.0_202/jre/lib/amd64/server/libjvm.so
      #4  0x00007ffff6d0c995 in JVM_handle_linux_signal () from /opt/jdk1.8.0_202/jre/lib/amd64/server/libjvm.so
      #5  0x00007ffff6cff858 in signalHandler(int, siginfo*, void*) () from /opt/jdk1.8.0_202/jre/lib/amd64/server/libjvm.so
      #6  <signal handler called>
----> #7  ElfParser::parseDynamicSection (this=<synthetic pointer>) at src/symbols_linux.cpp:327
      #8  ElfParser::parseProgramHeaders (end=<optimized out>, base=0x7fffb00f7000 "\177ELF\002\001\001", cc=0x7fff74009cc0) at src/symbols_linux.cpp:259
      #9  Symbols::parseLibraries(CodeCacheArray*, bool) () at src/symbols_linux.cpp:612
      #10 0x00007fffc8091ae9 in Profiler::updateSymbols (kernel_symbols=false, this=0x7fff7402c550) at src/profiler.cpp:192
      #11 VM::init(JavaVM_*, bool) [clone .part.0] () at src/vmEntry.cpp:137
      #12 0x00007fffc80a43ba in VM::init (attach=true, vm=0x7ffff73813e0 <main_vm>) at src/arguments.h:112
      #13 Agent_OnAttach () at src/vmEntry.cpp:408
      #14 0x00007ffff6b71ecb in JvmtiExport::load_agent_library(AttachOperation*, outputStream*) () from /opt/jdk1.8.0_202/jre/lib/amd64/server/libjvm.so
      #15 0x00007ffff66e5c22 in attach_listener_thread_entry(JavaThread*, Thread*) () from /opt/jdk1.8.0_202/jre/lib/amd64/server/libjvm.so
      #16 0x00007ffff6e6f9eb in JavaThread::thread_main_inner() () from /opt/jdk1.8.0_202/jre/lib/amd64/server/libjvm.so
      #17 0x00007ffff6e6fcf1 in JavaThread::run() () from /opt/jdk1.8.0_202/jre/lib/amd64/server/libjvm.so
      #18 0x00007ffff6d018c2 in java_start(Thread*) () from /opt/jdk1.8.0_202/jre/lib/amd64/server/libjvm.so
      #19 0x00007ffff7bbecf8 in ?? () from /usr/glibc-compat/lib/libpthread.so.0
      #20 0x00007ffff74d40df in clone () from /usr/glibc-compat/lib/libc.so.6

hs_err_pid115.log

(gdb) list
294	                case DT_PLTRELSZ:
295	                    pltrelsz = dyn->d_un.d_val;
296	                    break;
297	                case DT_RELA:
298	                case DT_REL:
299	                    rel = (char*)DYN_PTR(dyn->d_un.d_ptr); <--------- relocate the relocated address again
300	                    break;
301	                case DT_RELASZ:
302	                case DT_RELSZ:
303	                    relsz = dyn->d_un.d_val;
...
322	                // Find .got end from the highest relocation address.
323	                void** min_addr = (void**)-1;
324	                void** max_addr = (void**)0;
325	                for (size_t offs = relcount * relent; offs < relsz; offs += relent) {
326	                    ElfRelocation* r = (ElfRelocation*)(rel + offs);
327	                    if (ELF_R_TYPE(r->r_info) == R_GLOB_DAT) { <----------- crashed here
328	                        void** addr = (void**)(_base + r->r_offset);
329	                        if (addr < min_addr) min_addr = addr;
330	                        if (addr > max_addr) max_addr = addr;
331	                    }
cat /proc/version
Linux version 3.10.0-1160.80.1.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Tue Nov 8 15:48:59 UTC 2022

ldd --version
musl libc (x86_64)
Version 1.1.19
Dynamic Program Loader
Usage: ldd [options] [--] pathname

ls -rtl /lib/ld-musl-x86_64.so.1
-rwxr-xr-x    1 root     root        584168 Jun 19  2018 /lib/ld-musl-x86_64.so.1
(gdb) p dyn->d_tag
$36 = 7
(gdb) p/x dyn->d_un.d_ptr
$37 = 0x7fffb010ccd8 <------ This is the address after relocation, 
0x7fffb010ccd8 (d_un.d_ptr) - 0x15cd8 (RELA) = 0x7fffb00f7000 (_base),
details below
readelf -d /lib/ld-musl-x86_64.so.1

Dynamic section at offset 0x8dd98 contains 16 entries:
  Tag        Type                         Name/Value
 0x000000000000000e (SONAME)             Library soname: [libc.musl-x86_64.so.1]
 0x000000000000000c (INIT)               0x1d928
 0x000000000000000d (FINI)               0x1e1e4
 0x0000000000000004 (HASH)               0x190
 0x000000006ffffef5 (GNU_HASH)           0x2f78
 0x0000000000000005 (STRTAB)             0x117e0
 0x0000000000000006 (SYMTAB)             0x6560
 0x000000000000000a (STRSZ)              17649 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000007 (RELA)               0x15cd8       <---------
 0x0000000000000008 (RELASZ)             2136 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x0000000000000018 (BIND_NOW)
 0x000000006ffffffb (FLAGS_1)            Flags: NOW
 0x000000006ffffff9 (RELACOUNT)          55
 0x0000000000000000 (NULL)               0x0

(gdb) p/x 0x7fffb010ccd8 - 0x15cd8
$41 = 0x7fffb00f7000

cat /proc/725/maps |grep /lib/ld-musl-x86_64.so.1
------->7fffb00f7000-7fffb0184000 r-xp 00000000 fd:01 3027783                    /lib/ld-musl-x86_64.so.1
        7fffb0184000-7fffb0384000 ---p 0008d000 fd:01 3027783                    /lib/ld-musl-x86_64.so.1
        7fffb0384000-7fffb0385000 r--p 0008d000 fd:01 3027783                    /lib/ld-musl-x86_64.so.1
        7fffb0385000-7fffb0386000 rw-p 0008e000 fd:01 3027783                    /lib/ld-musl-x86_64.so.1

(gdb) n
(gdb) p rel
$38 = 0xffff60203cd8 <error: Cannot access memory at address 0xffff60203cd8>
(gdb) p/x 0xffff60203cd8 - 0x7fffb010ccd8
$40 = 0x7fffb00f7000

@yanglong1010 yanglong1010 changed the title musl relocates pointers in the dynamic section of /lib/ld-musl-x86_64.so musl may relocates pointers in the dynamic section of /lib/ld-musl-x86_64.so Feb 23, 2023
@apangin
Copy link
Member

apangin commented Feb 23, 2023

As the crash log indicates, you're running glibc version of JRE, therefore, you need to use glibc build of async-profiler for that.

7ffff7dd6000-7ffff7dfd000 r-xp 00000000 fd:01 3411262                    /usr/glibc-compat/lib/ld-2.29.so
...
libc:glibc 2.29 NPTL 2.29 

@apangin apangin closed this Feb 23, 2023
@apangin
Copy link
Member

apangin commented Feb 23, 2023

What your PR actually does is making #ifdef __musl__ and #else branches indentical, meaning that you turn musl-specific version of the profiler into generic version. So why not taking generic version in the first place?

@yanglong1010
Copy link
Contributor Author

What your PR actually does is making #ifdef __musl__ and #else branches indentical, meaning that you turn musl-specific version of the profiler into generic version. So why not taking generic version in the first place?

Andrei, Thanks for the correction, it was indeed my mistake.

One of our customers runs Oracle JDK8 in the anapsix/alpine-java docker image.
Before, we simply thought that the loader on alpine is always musl, so we used the musl version of async-profiler.
In fact, in this customer's scenario, the loader is glibc, which will relocate the ld-musl-x86_64.so that async-profiler depends on.
We should really use the glibc version of async-profiler.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants