Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1427826
  • 博文数量: 487
  • 博客积分: 161
  • 博客等级: 入伍新兵
  • 技术积分: 5064
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-01 07:37
个人简介

只有偏执狂才能生存

文章分类

全部博文(487)

文章存档

2016年(10)

2015年(111)

2014年(66)

2013年(272)

2012年(28)

分类: LINUX

2013-08-07 21:14:52

我在学习glibc 在main函数之前的时候,其实已经有类似的需求了,只不过当时不够激进,没有想到调试glibc 。 这两天在学习NPTL线程栈及TLS相关的东西,实在是比较复杂,才动了调试glibc,单步跟踪一窥究竟的念头。在网上找了一些资料,解决了这个问题。中间遇到的很有意思的东西比较有价值的东西我都记录下来了,这篇文章不能算原创,基本来源于参考文献的两篇文章。向这两位同学致谢。
  glibc 查看版本号
   1 ldd 某可执行程序 查看链接情况
   2 直接执行链接的libc.so文件 。

.
 
兄弟们可能会纳闷,SO文件怎么可以执行呢。 GLIBC耍了个trick。

01.#ifdef HAVE_ELF
02./* This function is the entry point for the shared object.
03.Running the library as a program will get here. */
04. 
05.extern void __libc_main (void) __attribute__ ((noreturn));
06.void
07.__libc_main (void)
08.{
09.__libc_print_version ();
10._exit (0);
11.}
12.#endif
01.static const char banner[] =
02."GNU C Library "PKGVERSION RELEASE" release version "VERSION", by Roland McGrath et al.\n\
03.Copyright (C) 2012 Free Software Foundation, Inc.\n\
04.This is free software; see the source for copying conditions.\n\
05.There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\
06.PARTICULAR PURPOSE.\n\
07.Compiled by GNU CC version "__VERSION__".\n"
08....
09. 
10.void
11.__libc_print_version (void)
12.{
13.__write (STDOUT_FILENO, banner, sizeof banner - 1);
14.}

    glibc应该是和Ubuntu没啥关系,可是我们从上图中居然看到Ubuntu EGLIBC的字样,原因很简单,Ubuntu发行给glibc-2.15打了patch。
   这个问题的解决,要感谢CSDN的blog of tony 。再次向这位前辈致敬。

   gdb调试glibc
   原本查看版本好的目的是为了下载对应源码,开始用gdb调试glibc,可是上面截图中的Ubuntu EGLIBC字样给我泼了一盆冷水。何哉?我虽然有glibc-2.15的source code,无奈Ubuntu给glibc打了patch。 继续找办法。
   在Ubuntu下,首先是安装符号表。 我们知道,大多数的动态库DSO ,都是strip过的,没有任何调试信息,第一步是要给glibc添加符号表。保存在/usr/lib/debug/对应目录下。
   第一步


sudo apt-get install libc6-dbg

安装完后,我们在可以看到如下:

01.root@manu:/usr/lib/debug/lib/i386-linux-gnu# ll
02.总用量 10268
03.drwxr-xr-x 3 root root 4096 5月 2 16:21 ./
04.drwxr-xr-x 4 root root 4096 12月 2 15:16 ../
05.-rwxr-xr-x 1 root root 555181 1月 28 20:30 ld-2.15.so*
06.-rw-r--r-- 1 root root 49332 1月 28 20:30 libanl-2.15.so
07.-rw-r--r-- 1 root root 13544 1月 28 20:30 libBrokenLocale-2.15.so
08.-rwxr-xr-x 1 root root 6963435 1月 28 20:30 libc-2.15.so*
09.-rw-r--r-- 1 root root 62923 1月 28 20:30 libcidn-2.15.so
10.-rw-r--r-- 1 root root 68453 1月 28 20:30 libcrypt-2.15.so
11....
12.-rw-r--r-- 1 root root 6149 1月 28 20:30 libpcprofile.so
13.-rwxr-xr-x 1 root root 565440 1月 28 20:30 libpthread-2.15.so*
14.-rw-r--r-- 1 root root 201563 1月 28 20:30 libresolv-2.15.so
15.-rw-r--r-- 1 root root 135143 1月 28 20:30 librt-2.15.so
16. 
17.....

    不太清楚为何某人安装/usr/lib/debug/lib/i386-linux-gnu的筒子可以阅读我的另一篇博文:程序减肥,strip,eu-strip 及其符号表
   这仅仅是有了符号表,但是看不到代码,调试的过程中,无法看到代码。很难受。www.it165.net

   第二步:安装源码:
   Ubuntu很贴心的提供了安装方法:

root@manu:~/code/c/classical# sudo apt-get source libc6-dev

    在我的当前路径下下载好了源码包,patch包,最终生成了eglibc-2.15路径。所有源码都在该目录下:

drwxr-xr-x 72 root root 4096 5月 2 17:05 eglibc-2.15/

    精确的源码我们也有了,现在可以用gdb来调试glibc了,终于走到了这一步:

    第三步:gdb 调试glibc
   我的目的是通过调试pthread_create创建过程,了解glibc和内核是如何实现NPTL线程的。 我的程序里面有pthread_create,我想单步跟踪glibc里面的__pthread_create_2_1函数。
   首先要告诉的gdb,源文件要去那个目录下寻找:

(gdb) directory /home/manu/code/c/classical/eglibc-2.15/nptl

    OK,我们可以看下截图:

.
 

    这部分代码,主要参考自用GDB追踪glibc代码执行过程。感谢作者的分享,让我可以继续我的NPTL 线程栈和TLS的分析。希望近期能完成这个NPTL的学习。
   值得一提的是,分析Ubuntu提供的patch,可以看到,glibc查看版本号一节中的输出中含有Ubuntu EGLIC的原因:

-rw-r--r-- 1 root root 10368576 1月 28 19:03 eglibc_2.15-0ubuntu10.4.diff

.


centos中默认情况下库函数是不带调试信息的,所以用gdb无法进入到printf()函数里。 

解决办法是: 

1.为libc安装调试信息 
a. 先要安装一个命令:sudo yum install /usr/bin/debuginfo-install 
b. 设置一下repos: vi /etc/yum.repos.d/CentOS-Debuginfo.repo, 把enabled设置为1 
c. 为标准库安装调试信息: sudo debuginfo-install glibc 

2.再来一次gdb并进入printf()函数即可. 我这里看到的第一行代码是
_IO_size_t len = strlen (str);



oot@localhost yum.repos.d]# ls
adobe-linux-i386.repo  CentOS-Debuginfo.repo  mirrors-rpmforge-extras
CentOS-Base-163.repo   CentOS-Media.repo      mirrors-rpmforge-testing
CentOS-Base.repo       CentOS-Vault.repo      rpmforge.repo
CentOS-Base.repo.bak   mirrors-rpmforge
[root@localhost yum.repos.d]# vi CentOS-Debuginfo.repo 
[root@localhost yum.repos.d]# cat CentOS-Debuginfo.repo 
# CentOS-Debuginfo.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client.  You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
 
# All debug packages from all the various CentOS-5 releases
# are merged into a single repo, split by BaseArch
#
# Note: packages in the debuginfo repo are currently not signed
#
 
[debug]
name=CentOS-5 - Debuginfo
baseurl=http://debuginfo.centos.org/5/$basearch/
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-5
enabled=1
[root@localhost yum.repos.d]# cd 
[root@localhost ~]# debuginfo-install glibc-2.5-107
Loaded plugins: fastestmirror
Repository base is listed more than once in the configuration
Repository updates is listed more than once in the configuration
Repository extras is listed more than once in the configuration
Repository centosplus is listed more than once in the configuration
Repository contrib is listed more than once in the configuration
Loading mirror speeds from cached hostfile
 * addons: mirror.bit.edu.cn
 * base: mirror.bit.edu.cn
 * extras: mirror.bit.edu.cn
 * rpmforge: mirror-fpt-telecom.fpt.net
 * updates: mirror.bit.edu.cn
debug                                                    | 1.9 kB     00:00     
debug/primary_db                                         | 2.8 MB     00:14     
Checking for new repos for mirrors
--> Running transaction check
---> Package glibc-debuginfo.i686 0:2.5-107 set to be updated
--> Processing Dependency: glibc-debuginfo-common = 2.5-107 for package: glibc-debuginfo
--> Running transaction check
---> Package glibc-debuginfo-common.i386 0:2.5-107 set to be updated
--> Finished Dependency Resolution
 
================================================================================
 Package                       Arch        Version           Repository    Size
================================================================================
Installing:
 glibc-debuginfo               i686        2.5-107           debug        6.2 M
Installing for dependencies:
 glibc-debuginfo-common        i386        2.5-107           debug         12 M
 
Transaction Summary
================================================================================
Install       2 Package(s)
Upgrade       0 Package(s)
 
Total download size: 18 M
Is this ok [y/N]: y
Downloading Packages:
(1/2): glibc-debuginfo-2.5-107.i686.rpm                  | 6.2 MB     00:26     
(2/2): glibc-debuginfo-common-2.5-107.i386.rpm           |  12 MB     00:33     
--------------------------------------------------------------------------------
Total                                           301 kB/s |  18 MB     01:02     
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing     : glibc-debuginfo-common                                   1/2 
  Installing     : glibc-debuginfo                                          2/2 
 
Installed:
  glibc-debuginfo.i686 0:2.5-107                                                
 
Dependency Installed:
  glibc-debuginfo-common.i386 0:2.5-107                                 



阅读(2027) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~