gdb在Alpine Linux上调试OpenJDK java失败;线程接收信号?,未知信号“;
我在尝试使用gdb在Alpine Linux上调试OpenJDK java时遇到了困难——有人成功地做到了吗 当尝试在gdb中调试java时,例如,gdb在Alpine Linux上调试OpenJDK java失败;线程接收信号?,未知信号“;,java,gdb,signals,alpine,musl,Java,Gdb,Signals,Alpine,Musl,我在尝试使用gdb在Alpine Linux上调试OpenJDK java时遇到了困难——有人成功地做到了吗 当尝试在gdb中调试java时,例如,gdb java和r-version,它会立即失败: Thread 1 "java" recieved signal ?, Unknown signal. __cp_end () at src/thread/x86_64/syscall_cp.s:29 我搜索了又搜索,但找不到任何关于Alpine上OpenJDK调试的参考或解决方案 在其他平台(m
gdb java
和r-version
,它会立即失败:
Thread 1 "java" recieved signal ?, Unknown signal.
__cp_end () at src/thread/x86_64/syscall_cp.s:29
我搜索了又搜索,但找不到任何关于Alpine上OpenJDK调试的参考或解决方案
在其他平台(macOS Sierra,MinGW)上看到的处理相同gdb错误的其他线程表明,接收到的信号?、未知信号
可能由各种原因造成,包括、、和其他应用程序错误
外部GDB,java工作没有任何问题,GDB对调试C++程序很有效。我正在运行Alpine V3.8
我尝试过的事情:- 不同的gdb版本(
,8.0.1-r6
,8.0.1-r3
)7.12.1-r1
- 不同的OpenJDK版本(
,1.8.0_171
)1.7.0_181
- 从不同的shell(
,/bin/ash
)运行,有和没有/bin/bash
sudo
- 在
中禁用信号停止功能:.gdbinit
,对于处理SIGSEGV nostop noprint pass
,SIGPPIPE
,SIGHUP
,SIGFPE
也一样SIG34
- 将
添加到在shell关闭时设置启动
.gdbinit
(gdb)r-版本
启动程序:/usr/lib/jvm/java-1.8-openjdk/bin/java-version
进程16214正在执行新程序:/usr/lib/jvm/java-1.8-openjdk/bin/java
[新LWP 16219]
线程1“java”接收到信号?,未知信号。
__位于src/thread/x86\u 64/syscall\u cp.s:29的cp\u end()
29 src/thread/x86_64/syscall_cp.s:没有这样的文件或目录。
(gdb)信息线程
Id目标Id帧
*src/thread/x86\u 64/syscall\u cp.s:29处的1 LWP 16214“java”\u cp\u end()
2 LWP 16219“java”同步调用(func=func@entry=0x7ffff7da2662,ctx=ctx@entry=0x7ffff7ff4720)
在src/thread/synccall.c:143
(gdb)在哪里
#src/thread/x86\u 64/syscall\u cp.s:29处的0\uu cp\u end()
#系统调用中的1 0x00007ffff7dbed2d(nr=202,u=,v=,w=,x=,
y=,z=0)在src/thread/pthread_cancel.c:35
#2 0x00007FF7DBE350英寸时间等待cp(地址=addr@entry=0x7ffff7ff4b20,val=16219,时钟=clk@entry=0,在=at@entry=0x0,priv=priv@entry=0)
在src/thread/_timedwait.c:31
#3 0x00007FF7FF7DBFDC4在线程时间连接np中(t=0x7ffff7ff4ae8,res=res@entry=0x7FFFFFA348,在=at@entry=0x0)
在src/thread/pthread_join.c处:16
#4 0x00007FF7DBFE02在线程连接中(t=,res=res@entry=0x7FFFFFA348)位于src/thread/pthread_join.c:27
#5 0x00007FF7B6695E在ContinueInNewThread0(continuence)中=continuation@entry=0x7ffff7b61a60,堆栈大小=1048576,
args=args@entry=0x7FFFFFA3E0)
在/home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/jdk/src/solaris/bin/java_md_solinux.c:1046
#6 0x00007FF7B634A4连续连接线程(ifn=ifn@entry=0x7FFFFFA4F0,threadStackSize=,argc=1,
argv=,模式=mode@entry=841574793,什么=what@entry=0x0,ret=0)
在/home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/jdk/src/share/bin/java.c:2024
#JVMInit中的7 0x00007FF7B66A08(ifn=ifn@entry=0x7FFFFFA4F0,threadStackSize=,argc=,
argv=,mode=841574793,mode@entry=0,什么=what@entry=0x0,ret=)
在/home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/jdk/src/solaris/bin/java_md_solinux.c:1093
#JLI_发布中的8 0x00007FF7B63E30(argc=,argv=,jargc=,jargv=,
appclassc=1,appclassv=0x0,fullversion=0x554843“1.8.0_171-b11”,dotversion=0x55483F“1.8”,pname=0x55483A“java”,
lname=0x554832“openjdk”,javaargs=0'\000',cpwildcard=1'\001',javaw=0'\000',ergo=0)
在/home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/jdk/src/share/bin/java.c:304
#main中的9 0x0000554691(argc=,argv=)
at/home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/jdk/src/share/bin/main.c:125
(gdb)
与此堆栈跟踪匹配的musl源文件:
#0 __synccall (func=func@entry=0x7ffff7da2662 <do_setrlimit>, ctx=ctx@entry=0x7ffff7ff4720) at src/thread/synccall.c:48
#1 0x00007ffff7da26a1 in setrlimit (resource=resource@entry=7, rlim=rlim@entry=0x7ffff7ff4750) at src/misc/setrlimit.c:42
#2 0x00007ffff73bd1fe in os::init_2 ()
at /home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/hotspot/src/os/linux/vm/os_linux.cpp:5096
#3 0x00007ffff746177d in Threads::create_vm (args=0x7ffff7ff4a20, canTryAgain=canTryAgain@entry=0x7ffff7ff4987)
at /home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/hotspot/src/share/vm/runtime/thread.cpp:3361
#4 0x00007ffff729cd48 in JNI_CreateJavaVM (vm=0x7ffff7ff4a10, penv=0x7ffff7ff4a18, args=<optimized out>)
at /home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/hotspot/src/share/vm/prims/jni.cpp:5221
#5 0x00007ffff7b61b0b in InitializeJVM (ifn=<synthetic pointer>, penv=0x7ffff7ff4a18, pvm=0x7ffff7ff4a10)
at /home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/jdk/src/share/bin/java.c:1231
#6 JavaMain (_args=<optimized out>)
- 1:
- 2:
- 3、4:
- 7:
JVMInit
通过调用ContinueInNewThread
尝试创建JavaMain
本机线程,该线程调用ContinueInNewThread0(JavaMain,threadStackSize,(void*)和args)
,并在那里爆炸;DR:问题在于GDB缺乏对内部musl信号的支持,如本文所述。
这里提供了一个快速、脏补丁的GDB:补丁提交: 使用补丁,信号正确识别为SIGSYNCCALL。
然后,可以使用
handle SIGSYNCCALL nostop noprint pass将其屏蔽
谢天谢地,我想出了一个解决办法
调试Alpine OpenJDK java时的gdb崩溃可以通过以下方式进行:
- 启动gdb
break os::init_2
- 使用所需的命令行参数运行java
- 当到达断点时,
设置MaxFDLimit=0
- 继续,并正常调试
- 它只在JDK有调试符号的情况下工作——无论是本地调试OpenJDK构建还是使用
debug symbols包openjdk8 dbg
- 它只适用于命令行gdb,不适用于CLion和eclipsecdt等gdb前端
#0 __synccall (func=func@entry=0x7ffff7da2662 <do_setrlimit>, ctx=ctx@entry=0x7ffff7ff4720) at src/thread/synccall.c:48
#1 0x00007ffff7da26a1 in setrlimit (resource=resource@entry=7, rlim=rlim@entry=0x7ffff7ff4750) at src/misc/setrlimit.c:42
#2 0x00007ffff73bd1fe in os::init_2 ()
at /home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/hotspot/src/os/linux/vm/os_linux.cpp:5096
#3 0x00007ffff746177d in Threads::create_vm (args=0x7ffff7ff4a20, canTryAgain=canTryAgain@entry=0x7ffff7ff4987)
at /home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/hotspot/src/share/vm/runtime/thread.cpp:3361
#4 0x00007ffff729cd48 in JNI_CreateJavaVM (vm=0x7ffff7ff4a10, penv=0x7ffff7ff4a18, args=<optimized out>)
at /home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/hotspot/src/share/vm/prims/jni.cpp:5221
#5 0x00007ffff7b61b0b in InitializeJVM (ifn=<synthetic pointer>, penv=0x7ffff7ff4a18, pvm=0x7ffff7ff4a10)
at /home/buildozer/aports/community/openjdk8/src/icedtea-3.8.0/openjdk/jdk/src/share/bin/java.c:1231
#6 JavaMain (_args=<optimized out>)
int setrlimit(int resource, const struct rlimit *rlim)
{
struct ctx c = { .res = resource, .rlim = rlim, .err = -1 };
__synccall(do_setrlimit, &c);
if (c.err) {
if (c.err>0) errno = c.err;
return -1;
}
return 0;
}
r = -__syscall(SYS_tgkill, pid, tid, SIGSYNCCALL);
if (MaxFDLimit) {
// set the number of file descriptors to max. print out error
// if getrlimit/setrlimit fails but continue regardless.
struct rlimit nbr_files;
int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode))
perror("os::init_2 getrlimit failed");
} else {
nbr_files.rlim_cur = nbr_files.rlim_max;
status = setrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode))
perror("os::init_2 setrlimit failed");
}
}
}