有时核心转储文件在一个系统(核心主机)上创建,而您想在另一台机器(dbx 主机)上装入该核心转储文件。但这样做可能会引起两个与库有关的问题:
核心主机上的程序所使用的共享库与 dbx 主机上的共享库可能不相同。要获取该库相关的正确栈跟踪,需要在 dbx 主机上提供这些原始库。
dbx 使用 /usr/lib 中的系统库来帮助了解系统内有关运行时链接程序和线程库实现的详细信息。可能还需要通过核心主机提供这些系统库,以便 dbx 能够了解运行时链接程序数据结构和线程数据结构。
用户库和系统库可随着修补程序以及主要的 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 |
将 dbx 环境变量 core_lo_pathmap 设置为 on。
使用 pathmap 命令告知 dbx 核心转储文件的正确库的位置。
使用 debug 命令装入程序和核心转储文件。
例如,假定核心主机的根分区已通过 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 可用即可)。
调试不匹配的核心转储文件时应注意:
pathmap 命令不能识别 "/" 路径映射,因此不能使用以下命令:
pathmap / /net/core-host
pathmap 命令的单参数模式不能与装入对象路径名同时使用,因此请使用双参数(来源路径和目标路径)模式。
如果 dbx 主机使用的 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 位的 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 库。