Oracle® Solaris 11.2 链接程序和库指南

退出打印视图

更新时间: 2014 年 7 月
 
 

调试器模块

调试器模块提供了一组可在 mdb(1) 下装入的 dcmdswalkers。此模块可用于检查运行时链接程序的各种内部数据结构。许多调试信息都要求您熟悉运行时链接程序的内部构造。并且该信息会随发行版的不同而有所变化。但是,这些数据结构中的某些元素显示了动态链接进程的基本组件,有助于进行一般调试。

以下示例显示了一些将 mdb(1) 与调试器模块一起使用的简单方案。

$ cat main.c
#include    <dlfnc.h>

int main()
{
        void *handle;
        void (*fptr)();

        if ((handle = dlopen("foo.so.1", RTLD_LAZY)) == NULL)
                return (1);

        if ((fptr = (void (*)())dlsym(handle, "foo")) == NULL)
                return (1);

        (*fptr)();
        return (0);
}
$ cc -o main main.c -R.

如果 mdb(1) 尚未自动装入调试器模块 ld.so,则显式装入该模块。之后可以检查调试器模块的功能。

$ mdb main
> ::load ld.so
> ::dmods -l ld.so

ld.so
-----------------------------------------------------------------
  dcmd Bind                 - Display a Binding descriptor
  dcmd Callers              - Display Rt_map CALLERS binding descriptors
  dcmd Depends              - Display Rt_map DEPENDS binding descriptors
  dcmd ElfDyn               - Display Elf_Dyn entry
  dcmd ElfEhdr              - Display Elf_Ehdr entry
  dcmd ElfPhdr              - Display Elf_Phdr entry
  dcmd Groups               - Display Rt_map GROUPS group handles
  dcmd GrpDesc              - Display a Group Descriptor
  dcmd GrpHdl               - Display a Group Handle
  dcmd Handles              - Display Rt_map HANDLES group descriptors
  ....
> ::bp main
> :r

进程中的每个动态目标文件都表示为链接映射 Rt_map,该映射在链接映射列表中对其进行维护。可使用 Rt_maps 显示进程的所有链接映射。

> ::Rt_maps
Link-map lists (dynlm_list): 0xffbfe0d0
----------------------------------------------
  Lm_list: 0xff3f6f60  (LM_ID_BASE)
  ----------------------------------------------
    lmco        rtmap       ADDR()     NAME()
    ----------------------------------------------
    [0xc]       0xff3f0fdc 0x00010000 main
    [0xc]       0xff3f1394 0xff280000 /lib/libc.so.1
  ----------------------------------------------
  Lm_list: 0xff3f6f88  (LM_ID_LDSO)
  ----------------------------------------------
    [0xc]       0xff3f0c78 0xff3b0000 /lib/ld.so.1

可使用 Rt_map 显示单个链接映射。

> 0xff3f9040::Rt_map
Rt_map located at: 0xff3f9040
     NAME: main
 PATHNAME: /export/home/user/main
     ADDR: 0x00010000         DYN: 0x000207bc
     NEXT: 0xff3f9460        PREV: 0x00000000
      FCT: 0xff3f6f18    TLSMODID:          0
     INIT: 0x00010710        FINI: 0x0001071c
   GROUPS: 0x00000000     HANDLES: 0x00000000
  DEPENDS: 0xff3f96e8     CALLERS: 0x00000000
....

可使用 ElfDyn dcmd 显示目标文件的 .dynamic 节。以下示例显示了前 4 项。

> 0x000207bc,4::ElfDyn
Elf_Dyn located at: 0x207bc
    0x207bc  NEEDED       0x0000010f
Elf_Dyn located at: 0x207c4
    0x207c4  NEEDED       0x00000124
Elf_Dyn located at: 0x207cc
    0x207cc  INIT         0x00010710
Elf_Dyn located at: 0x207d4
    0x207d4  FINI         0x0001071c

mdb(1) 在设置延迟断点时也很有用。在此示例中,函数 foo() 中的断点可能会很有用。但是,在对 foo.so.1 执行 dlopen(3C) 之前,调试器不知道此符号。延迟断点会指示调试器在装入动态目标文件时设置实际断点。

> ::bp foo.so.1`foo
> :c
> mdb: You've got symbols!
> mdb: stop at foo.so.1`foo
mdb: target stopped at:
foo.so.1`foo:   save      %sp, -0x68, %sp

此时,已经装入了新目标文件:

> *ld.so`lml_main::Rt_maps
lmco    rtmap       ADDR()     NAME()
----------------------------------------------
[0xc]   0xff3f0fdc 0x00010000 main
[0xc]   0xff3f1394 0xff280000 /lib/libc.so.1
[0xc]   0xff3f9ca4 0xff380000 ./foo.so.1
[0xc]   0xff37006c 0xff260000 ./bar.so.1

foo.so.1 的链接映射显示了 dlopen(3C) 返回的句柄。可使用 Handles 来扩展此结构。

> 0xff3f9ca4::Handles -v
HANDLES for ./foo.so.1
----------------------------------------------
  HANDLE: 0xff3f9f60 Alist[used 1: total 1]
  ----------------------------------------------
    Group Handle located at: 0xff3f9f28
    ----------------------------------------------
    owner:               ./foo.so.1
    flags: 0x00000000    [ 0 ]
   refcnt:          1    depends: 0xff3f9fa0 Alist[used 2: total 4]
    ----------------------------------------------
    Group Descriptor located at: 0xff3f9fac
       depend: 0xff3f9ca4    ./foo.so.1
        flags: 0x00000003    [ AVAIL-TO-DLSYM,ADD-DEPENDENCIES ]
    ----------------------------------------------
    Group Descriptor located at: 0xff3f9fd8
       depend: 0xff37006c    ./bar.so.1
        flags: 0x00000003    [ AVAIL-TO-DLSYM,ADD-DEPENDENCIES ]

句柄的依赖项由一组链接映射组成,这些链接映射表示可满足 dlsym(3C) 请求的句柄的目标文件。在此情况下,依赖项为 foo.so.1bar.so.1


注 - 前面的示例提供了调试器模块功能的基本指南,但确切的命令、用法和输出可能会随发行版的不同而有所变化。有关系统中可用的确切功能,请参阅 mdb(1) 用法和帮助信息。