如何调试ld.so

2785阅读 1评论2010-10-18 qtdszws
分类:LINUX

如何调试ld.so
想要更好地分析ld.so源码,使用gdb调试ld.so是必要的。
但直接调试会失败。
[zws@mail ~/glibc-2.3/build/elf]$gdb -v ld.so
GNU gdb (GDB) 7.0
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<>.
[zws@mail ~/glibc-2.3/build/elf]$gdb ld.so  
GNU gdb (GDB) 7.0
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<>...
warning: The current binary is a PIE (Position Independent Executable),
which
GDB does NOT currently support.  Most debugger features will fail if used
in this session.
Reading symbols from /home/zws/glibc-2.3/build/elf/ld.so...done.
(gdb) r
Starting program: /home/zws/glibc-2.3/build/elf/ld.so
Cannot access memory at address 0x126fc
(gdb) c
Continuing.
Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
You have invoked `ld.so', the helper program for shared library executables.
This program usually lives in the file `/lib/ld.so', and special directives
in executable files using ELF shared libraries tell the system's program
loader to load the helper program from this file.  This helper program loads
the shared libraries needed by the program executable, prepares the program
to run, and runs it.  You may invoke this helper program directly from the
command line to load and run an ELF executable file; this is like executing
that file itself, but always uses this helper program from the file you
specified, instead of the helper program file specified in the executable
file you run.  This is mostly of use for maintainers to test new versions
of this helper program; chances are you did not intend to run this program.
  --list                list all dependencies and how they are resolved
  --verify              verify that given object really is a dynamically
linked
                        object we can handle
  --library-path PATH   use given PATH instead of content of the environment
                        variable LD_LIBRARY_PATH
  --inhibit-rpath LIST  ignore RUNPATH and RPATH information in object names
                        in LIST
Program exited with code 0177.
(gdb) b dl_main
Breakpoint 1 at 0xfb0: file rtld.c, line 595.
(gdb) r
Starting program: /home/zws/glibc-2.3/build/elf/ld.so
Cannot access memory at address 0x126fc
(gdb) c
Continuing.
Warning:
Cannot insert breakpoint 1.
Error accessing memory address 0xfb0: Input/output error.
(gdb)
那么可以试试通过调试程序来调试ld.so
这之前还要准备一番
[zws@mail ~/glibc-2.3/build/elf]$cat 1.c
#include
int main(){printf("Hello World!\n");return 0;}
[zws@mail ~/glibc-2.3/build/elf]$gcc -v 1.c -o 1
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-
checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/cc1 -lang-c -v -D__GNUC__=3 -
D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=2 -D__GXX_ABI_VERSION=102 -D__ELF__
-Dunix -D__gnu_linux__ -Dlinux -D__ELF__ -D__unix__ -D__gnu_linux__ -
D__linux__ -D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -
D__STDC_HOSTED__=1 -Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -
D__tune_i386__ 1.c -quiet -dumpbase 1.c -version -o /tmp/ccvFDt1S.s
GNU CPP version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) (cpplib) (i386
Linux/ELF)
GNU C version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) (i386-redhat-linux)
        compiled by GNU C version 3.2.2 20030222 (Red Hat Linux 3.2.2-5).
ignoring nonexistent directory "/usr/i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include
 /usr/include
End of search list.
 as -V -Qy -o /tmp/ccuHlFoF.o /tmp/ccvFDt1S.s
GNU assembler version 2.18 (i686-pc-linux-gnu) using BFD version (GNU
Binutils) 2.18
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/collect2 --eh-frame-hdr -m
elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o 1 /usr/lib/gcc-lib/i386-
redhat-linux/3.2.2/../../../crt1.o /usr/lib/gcc-lib/i386-redhat-
linux/3.2.2/../../../crti.o /usr/lib/gcc-lib/i386-redhat-
linux/3.2.2/crtbegin.o -L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2 -
L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../.. /tmp/ccuHlFoF.o -lgcc -
lgcc_eh -lc -lgcc -lgcc_eh /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtend.o
/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crtn.o
将后面的连接命令改一下
-dynamic-linker /lib/ld-linux.so.2改成 -dnamic-linker /home/zws/glibc-
2.3/build/elf/ld.so
/tmp/ccuH1FoF.o改成 1.o
重新连接一下,然后启动调试器
[zws@mail ~/glibc-2.3/build/elf]$gdb 1
GNU gdb (GDB) 7.0
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu".
For bug reporting instructions, please see:
<>...
Reading symbols from /home/zws/glibc-2.3/build/elf/1...done.
(gdb) b dl_main
Function "dl_main" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (dl_main) pending.
(gdb) r
Starting program: /home/zws/glibc-2.3/build/elf/1
Breakpoint 1, dl_main (phdr=0x8048034, phnum=6, user_entry=0xbfffe2bc) at
rtld.c:595
595       bool has_interp = false;
(gdb)
这样就可以了
但是还有一个问题,就是调试ld.so时不能单步进入,必须下断点进入函数
Program exited normally.
(gdb) r
Starting program: /home/zws/glibc-2.3/build/elf/1
Breakpoint 1, dl_main (phdr=0x8048034, phnum=6, user_entry=0xbfffe53c) at
rtld.c:595
595       bool has_interp = false;
(gdb) n
597       bool prelinked = false;
(gdb)
598       bool rtld_is_main = false;
(gdb)
609       process_envvars (&mode);
(gdb) s
init (argc=1073818872, argv=0x40012710, envp=0x40012cf8)
    at ../sysdeps/unix/sysv/linux/init-first.c:53
53      {
(gdb)
直接执行到init了,因此想要进入一个函数,先下断点吧
(gdb) r
Starting program: /home/zws/glibc-2.3/build/elf/1
Breakpoint 1, dl_main (phdr=0x8048034, phnum=6, user_entry=0xbffff53c) at
rtld.c:595
595       bool has_interp = false;
(gdb) c
Continuing.
Breakpoint 2, process_envvars (modep=0xbffff504) at rtld.c:1749
1749      char **runp = _environ;
(gdb)

 
上一篇:破解microsoft outlook express压缩邮件检查
下一篇:系统启动(3)Grub

文章评论