有时信息转储文件在一个系统(核心主机)上创建,而您想在另一台计算机(dbx 主机)上装入该信息转储文件以进行调试。但这样做可能会引起两个与库有关的问题:
核心主机上的程序所使用的共享库与 dbx 主机上的共享库可能不相同。要获取该库相关的正确堆栈跟踪,需要在 dbx 主机上提供这些原始库。
dbx 使用 /usr/lib 中的系统库来帮助了解系统上运行时链接程序和线程库的实现详细信息。可能还需要通过核心主机提供这些系统库,以便 dbx 能够了解运行时链接程序数据结构和线程数据结构。
用户库和系统库可随着修补程序以及主要的 Oracle Solaris 操作系统升级而改变,因此如果在收集信息转储文件之后但在信息转储文件上运行 dbx 之前安装修补程序,此问题仍会出现在同一台主机上。
当装入不匹配的信息转储文件时,dbx 可能会显示以下一条或多条错误消息:
dbx: core file read error: address 0xff3dd1bc not available dbx: warning: could not initialize librtld_db.so.1 -- trying libDP_rtld_db.so dbx: cannot get thread info for 1 -- generic libthread_db.so error dbx: attempt to fetch registers failed - stack corrupted dbx: read of registers from (0xff363430) failed -- debugger service failed
调试不匹配的信息转储文件时应注意:
pathmap 命令不能识别 "/" 路径映射,因此不能使用以下命令:
pathmap / /net/core-host
pathmap 命令的单参数模式不能与装入对象路径名同时使用,因此请使用双参数(来源路径和目标路径)模式。
如果 dbx 主机使用的 Oracle Solaris 操作系统版本与核心主机相同或比它更新,那么调试信息转储文件时效果可能会更好,虽然这并不总是必要的。
可能需要的系统库如下:
对于运行时链接程序:
/usr/lib/ld.so.1
/usr/lib/librtld_db.so.1
/usr/lib/64/ld.so.1
/usr/lib/64/librtld_db.so.1
对于线程库,取决于您所使用的 libthread 执行:
/usr/lib/libthread_db.so.1
/usr/lib/64/libthread_db.so.1
如果 dbx 在支持 64 位的 Oracle Solaris OS 版本上运行,您将需要 64 位版本的 xxx_db.so 库,因为这些系统库是作为 dbx 的一部分(而不是目标程序的一部分)装入和使用的。
与 libc.so 或任何其他库一样,ld.so.1 库是信息转储文件映像的一部分,因此需要与创建信息转储文件的程序相匹配的 32 位 ld.so.1 库或 64 位 ld.so.1 库。
如果正在查看来自某个线程程序的信息转储文件,并且 where 命令未显示堆栈,请尝试使用 lwp 命令。例如:
(dbx) where current thread: t@0 [1] 0x0(), at 0xffffffff (dbx) lwps o>l@1 signal SIGSEGV in _sigfillset() (dbx) lwp l@1 (dbx) where =>[1] _sigfillset(), line 2 in "lo.c" [2] _liblwp_init(0xff36291c, 0xff2f9740, ... [3] _init(0x0, 0xff3e2658, 0x1, ... ...
如果 LWP 的帧指针 (fp) 被破坏,则 lwp 命令的 –setfp 和 –resetfp 选项会很有用。这些选项在调试信息转储文件时发挥作用,此时 assign $fp=... 不可用。
缺少线程堆栈表明 thread_db.so.1 有问题,因此,您可能还需要尝试从核心主机中复制适当的 libthread_db.so.1 库。
例如,假定核心主机的根分区已通过 NFS 导出,并且可以通过 dbx 主机上的 /net/core-host/ 访问,应使用以下命令装入 prog 程序和 prog.core 信息转储文件来进行调试:
(dbx) dbxenv core_lo_pathmap on (dbx) pathmap /usr /net/core-host/usr (dbx) pathmap /appstuff /net/core-host/appstuff (dbx) debug prog prog.core
如果没有导出核心主机的根分区,则必须手动复制这些库。不需要重新创建符号链接。(例如,您不必建立从 libc.so 到 libc.so.1 的链接,只需确保 libc.so.1 可用即可)。