Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1237638
  • 博文数量: 389
  • 博客积分: 2874
  • 博客等级: 少校
  • 技术积分: 3577
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 10:34
文章分类

全部博文(389)

文章存档

2020年(2)

2018年(39)

2017年(27)

2016年(3)

2015年(55)

2014年(92)

2013年(54)

2012年(53)

2011年(64)

分类: LINUX

2018-07-30 11:31:29

之前看centos的spec文件时记录过如何提取debuginfo的方法,今天想用又找不到了,好在网上有别的高手记录过直接摘过来如下:

转自:http://abcdxyzk.github.io/blog/2014/02/21/debug-base-objdump-apply/

这种将可执行程序与调试符号分离的方案好处多多。一方面,缩减了可执行程序的文件大小,在一定程度上提高了程序的执行性能,另一方面,对应的调试符号文件也方便了一些不时之需。本文就来看一下与此相关的两个问题。


一 如何给应用程序创建对应的调试符号文件?


这很简单,看个演示实例。有代码如下:

点击(此处)折叠或打开

  1. [root@lenky gdb]# cat t.c
  2. #include
  3. int main(int argc, char *argv[])
  4. {
  5.   printf("Hello world!\n");
  6.   return 0;
  7. }


依次执行命令如下:

点击(此处)折叠或打开

  1. [root@lenky gdb]# ls -l
  2. total 4
  3. -rw-r--r--. 1 root root 103 Mar 20 07:52 t.c
  4. [root@lenky gdb]# gcc -g t.c -o t
  5. [root@lenky gdb]# ls -l
  6. total 12
  7. -rwxr-xr-x. 1 root root 7717 Mar 20 07:58 t
  8. -rw-r--r--. 1 root root 103 Mar 20 07:52 t.c
  9. [root@lenky gdb]# objcopy --only-keep-debug t t.debuginfo
  10. [root@lenky gdb]# objcopy --strip-debug t
  11. [root@lenky gdb]# objcopy --add-gnu-debuglink=t.debuginfo t
  12. [root@lenky gdb]# ls -l
  13. total 20
  14. -rwxr-xr-x. 1 root root 6470 Mar 20 07:58 t
  15. -rw-r--r--. 1 root root 103 Mar 20 07:52 t.c
  16. -rwxr-xr-x. 1 root root 6109 Mar 20 07:58 t.debuginfo


OK,可执行程序t和对应的调试符号文件t.debuginfo就生成了。


几条命令,给以分别解释一下: 
1. gcc -g t.c -o t 
这个无需多说,值得注意的是,-g和-O2可以同时使用。 
2. objcopy –only-keep-debug t t.debuginfo 
将可执行程序文件t内的与调试相关的信息拷贝到文件t.debuginfo内。也可以这样:
cp t t.debuginfo
strip –only-keep-debug t.debuginfo
3. objcopy –strip-debug t 
删除可执行程序文件t内的调试相关信息。也可以直接使用strip命令,不过strip命令会把symtab也删除掉,导致在没有debuginfo文件的情况下,打印堆栈信息会受到影响,比如变得不那么清晰。 
4. objcopy –add-gnu-debuglink=t.debuginfo t 
在可执行程序文件t内添加一个名为.gnu_debuglink的section段,该段内包含有debuginfo文件的name名称和checksum校验和,以确保后续在进行实际调试时,可执行程序和对应的调试符号文件是一致的。


二 如何使用gdb调试带有调试符号文件的应用程序?


其实想想也知道,这只需解决一个问题,即如何把应用程序与调试符号文件关联起来。 
gdb会按照一定的规则去搜索对应路径,找寻应用程序的调试符号文件,比如gdb会自动查找可执行程序所在目录下的.debug文件夹:

点击(此处)折叠或打开

  1. [root@lenky ~]# pwd
  2. /root
  3. [root@lenky ~]# gdb /home/work/gdb/t -q
  4. Reading symbols from /home/work/gdb/t...Reading symbols from /home/work/gdb/.debug/t.debug...done.
  5. done.
  6. (gdb)


把调试符号文件放到同一个目录也可以:

点击(此处)折叠或打开

  1. [root@lenky ~]# rm -fr /tmp/.debug/
  2. [root@lenky ~]# cp /home/work/gdb/.debug/t.debug /tmp/
  3. [root@lenky ~]# gdb /tmp/t -q
  4. Reading symbols from /tmp/t...Reading symbols from /tmp/t.debug...done.
  5. done.
  6. (gdb)

下面再介绍另外几种主动设置方法:


1,通过gdb启动参数-s指定:

点击(此处)折叠或打开

  1. [root@lenky ~]# gdb -s /home/work/gdb/.debug/t.debug -e /tmp/t -q
  2. Reading symbols from /home/work/gdb/.debug/t.debug...done.
  3. (gdb)


注意:可执行程序必须通过-e指定,否则貌似gdb会拿它覆盖-s参数,比如如下:

点击(此处)折叠或打开

  1. [root@lenky ~]# gdb -s /home/work/gdb/.debug/t.debug /tmp/t -q
  2. Reading symbols from /tmp/t...Missing separate debuginfo for /tmp/t
  3. Try: yum --disablerepo='*' --enablerepo='*-debuginfo' install /usr/lib/debug/.build-id/01/f1df7f4971caacd934aca9523c4e4b5ae95332.debug
  4. (no debugging symbols found)...done.
  5. (gdb)


可以看到,gdb直接尝试从文件/tmp/t内读取符号了,而不是文件t.debug。


2,利用gdb的命令设置搜索路径:set debug-file-directory directories


这是gdb官方文档提到的,可以设置搜索路径的命令,但是貌似并没有起作用,或者是我漏掉了什么。具体不说了,请看参考5。


参考:


How to generate gcc debug symbol outside the build target? 

Creating separate debug info 
https://blogs.oracle.com/dbx/entry/creating_separate_debug_info
man objcopy
.gnu_debuglink or Debugging system libraries with source code 
https://blogs.oracle.com/dbx/entry/gnu_debuglink_or_debugging_system
18.2 Debugging Information in Separate Files 




#!/bin/sh
# 可以改成:将要提取的文件加到参数中


#set -x


objcopyout()
{
#       if [ -f `file -N $1 | sed -n -e 's/^\(.*\):[   ]*.*ELF.*, not stripped/\1/p'` ]; then
    val=`objdump -s -j .gnu_debuglink "$1" | grep 'Contents of section .gnu_debuglink:'`
    if [ -z "$val" ]; then
            #debug_out=".debug/$1.debug".`date +%s`
            tmp_name=`echo "$1" | awk -F/ '{ print $NF}'`
            debug_out=".debug/$tmp_name.debug".`date +%s`
            objcopy --only-keep-debug "$1" "$debug_out"
            objcopy --strip-debug "$1"
            objcopy --add-gnu-debuglink="$debug_out" "$1"
    fi
#       objdump -s -j .gnu_debuglink "$1"
}


mkdir -p .debug/


while [ $# -gt 0 ]; do
    if [ -f "$1" ]; then
            objcopyout "$1"
    fi
    shift
done


#find . -name *.ko -print |
#while read f
#do
#       objcopyout "$f"
#done
Posted by kk 2014-02-21 14:13:00   debug, base
阅读(2557) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~