On Thu, 21 May 2026 06:42:00 GMT, Yasumasa Suenaga <[email protected]> wrote:

> `jhsdb jstack --mixed` would try to unwind all of native call frames. It will 
> reach `_start()` (startup routine by glibc), but it couldn't on the JDK built 
> by older glibc such as glibc-2.12 (used in devkit for Linux x86_64).
> 
> Expected:
> 
> 0x000055ad324dfadb main + 0x13b
> 0x00007f3df876c681 __libc_start_call_main + 0x81
> 0x00007f3df876c798 __libc_start_main_alias_2 + 0x88
> 0x000055ad324dfb79 _start + 0x25
> 
> 
> Actual (no `_start` in call stacks):
> 
> 0x000055ad324dfadb main + 0x13b
> 0x00007f3df876c681 __libc_start_call_main + 0x81
> 0x00007f3df876c798 __libc_start_main_alias_2 + 0x88
> 
> 
> Startup routine would be provided by crt1.o, and it would be linked into 
> `java`. `_start()` in crt1.o by glibc-2.12 does not have Frame Description 
> Entry (FDE) in DWARF. In DWARF parser in SA assumes native function has FDE, 
> thus unwinder in SA would stop if it cannot find appropriate DWARF 
> information.
> 
> I saw the problem on `_start()` only so far. This is not critical, but same 
> problem can happen on other places (functions / libraries). We cannot find 
> caller frame from DWARF-less function of course, but we should show the frame 
> even if it does not have DWARF.
> 
> ---------
> - [x] I confirm that I make this contribution in accordance with the [OpenJDK 
> Interim AI Policy](https://openjdk.org/legal/ai).

I think this is good, just wanted to mention that with the change I see (on 
x64) before main it does find a new frame, but no symbol:


----------------- 844607 -----------------
0x00007f512823938a      __futex_abstimed_wait_common + 0xca
0x00007f512823de34      __pthread_clockjoin_ex + 0x144
0x00007f51283cdd16      CallJavaMainInNewThread + 0xa6
0x00007f51283cadae      ContinueInNewThread + 0x6e
0x00007f51283cbafc      JLI_Launch + 0xb4c
0x000055fbde081ad4      main + 0x134
0x00007f51281db610      __libc_start_call_main + 0x80
0x00007f51281db6c0      __libc_start_main_alias_2 + 0x80
0x000055fbde081b71              ????????


And that last ??? frame is in _start, if I look in gdb:

...
   0x000055fbde081b57 <_start+15>:      lea    0x112(%rip),%r8        # 
0x55fbde081c70 <__libc_csu_fini>
   0x000055fbde081b5e <_start+22>:      lea    0x11b(%rip),%rcx        # 
0x55fbde081c80 <__libc_csu_init>
   0x000055fbde081b65 <_start+29>:      lea    -0x1cc(%rip),%rdi        # 
0x55fbde0819a0 <main>
   0x000055fbde081b6c <_start+36>:      call   0x55fbde0818e0 
<__libc_start_main@plt>
   0x000055fbde081b71 <_start+41>:      hlt
...


..so, it's right to include it, there is code there, in the java binary.  
Seeing what happens before main() is not a critical task for the JVM tools, we 
might say it's out of scope and we should be using a native debugger.  There 
may be other examples in odd libraries or JVM internals that could use this, so 
yes maybe we would rather have the ??? than terminate.



readelf says _start is the last item in the bin/java symtab:


Symbol table '.symtab' contains 45 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
    44: 0000000000000b48     0 FUNC    GLOBAL DEFAULT   13 _start

        
But it's size is zero.  There is no range we can match.  We have had that 
conversation before somewhere about matching a symbol on a specific match 
without needing a range, but we are not at the first byte of _start, so that's 
no help.  We probably are stuck for now with ???s where _start has size zero, 
it does not seem worth major effort to find out the size of the actual code 
there.

-------------

Marked as reviewed by kevinw (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/31230#pullrequestreview-4808308485

Reply via email to