给 release 程序添加 debug 信息来调试

release 的程序一般会 strip 掉多余的信息,调试信息更不会放在 release 程序中。但是有时候我们需要调试 release 程序,在一些情况下我们可能无法重新编译一个版本更换当前的版本,这时候可以考虑动态添加 debug 信息。

具体的过程

这个操作是通过 objcopy 程序来完成的。首先我们需要用相同的源代码编一个带调试信息的版本,然后使用 objcopy 程序来将 debug 信息导出到某个文件中,这之后再通过 objcopy 命令将导出到文件中的调试信息添加到 release 的程序中。

manual 中的相关说明

man objcopy 可以找到下面这些信息:

       --only-keep-debug
           Strip a file, removing contents of any sections that would not be stripped by --strip-debug and leaving the debugging sections intact.  In ELF files, this
           preserves all note sections in the output.

           Note - the section headers of the stripped sections are preserved, including their sizes, but the contents of the section are discarded.  The section headers
           are preserved so that other tools can match up the debuginfo file with the real executable, even if that executable has been relocated to a different address
           space.

           The intention is that this option will be used in conjunction with --add-gnu-debuglink to create a two part executable.  One a stripped binary which will
           occupy less space in RAM and in a distribution and the second a debugging information file which is only needed if debugging abilities are required.  The
           suggested procedure to create these files is as follows:

           1.<Link the executable as normal.  Assuming that it is called>
               "foo" then...

           1.<Run "objcopy --only-keep-debug foo foo.dbg" to>
               create a file containing the debugging info.

           1.<Run "objcopy --strip-debug foo" to create a>
               stripped executable.

           1.<Run "objcopy --add-gnu-debuglink=foo.dbg foo">
               to add a link to the debugging info into the stripped executable.

           Note---the choice of ".dbg" as an extension for the debug info file is arbitrary.  Also the "--only-keep-debug" step is optional.  You could instead do this:

           1.<Link the executable as normal.>
           1.<Copy "foo" to  "foo.full">
           1.<Run "objcopy --strip-debug foo">
           1.<Run "objcopy --add-gnu-debuglink=foo.full foo">

           i.e., the file pointed to by the --add-gnu-debuglink can be the full executable.  It does not have to be a file created by the --only-keep-debug switch.

           Note---this switch is only intended for use on fully linked files.  It does not make sense to use it on object files where the debugging information may be
           incomplete.  Besides the gnu_debuglink feature currently only supports the presence of one filename containing debugging information, not multiple filenames
           on a one-per-object-file basis.

一个具体的示例

这里我使用《CSAPP》中的一个测试代码来演示,代码内容如下:

#include <stdio.h>

typedef unsigned char *byte_pointer;
void show_bytes( byte_pointer start, int length );
void show_int( int x );
void show_float( float x );
void show_pointer( void *x );

void show_bytes( byte_pointer start, int length )
{
	int i;
	
	for (i = 0; i < length; i++)
		printf("%.2x", start[i] );
	printf("\n");
}

void show_int( int x )
{
	show_bytes( (byte_pointer) &x , sizeof(int) );
}

void show_float( float x )
{
	show_bytes( (byte_pointer) &x , sizeof(float) );
}
void show_pointer( void *x)
{
	show_bytes( (byte_pointer) &x, sizeof(void *) );
}

int main(void)
{
    show_pointer("test\n");
    
	return 0;
}

将上述代码保存为 show_byte.c,然后执行下面的操作:

[longyu@debian-10:22:15:08] CSAPP_develop $ gcc show_byte.c -o show_byte
[longyu@debian-10:22:15:19] CSAPP_develop $ gcc -g show_byte.c -o show_byte-debug
[longyu@debian-10:22:15:35] CSAPP_develop $ objcopy --only-keep-debug show_byte-debug show_byte.dbg
[longyu@debian-10:22:16:54] CSAPP_develop $ objcopy --add-gnu-debuglink=show_byte.dbg show_byte

上面的操作中,首先生成一个没有调试信息的 show_byte 程序,然后生成一个有调试信息的 show_byte-debug 程序。这之后,使用 objcopy 将调试信息从调试版程序中提取出来,导出到 show_byte.dbg 文件中,最后使用 objcopy 再将调试信息添加到不带调试信息的程序中。

下面使用 gdb 调试 show_byte 程序,可以看到 gdb 读取到了调试信息。

[longyu@debian-10:22:17:15] CSAPP_develop $ gdb show_byte
GNU gdb (Debian 8.2.1-2+b3) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
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 "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from show_byte...Reading symbols from /home/longyu/The_Programming_Language/The_C_Language/CSAPP_develop/show_byte.dbg...done.
done.
(gdb) l
20		show_bytes( (byte_pointer) &x , sizeof(int) );
21	}
22	
23	void show_float( float x )
24	{
25		show_bytes( (byte_pointer) &x , sizeof(float) );
26	}
27	void show_pointer( void *x)
28	{
29		show_bytes( (byte_pointer) &x, sizeof(void *) );
(gdb) 

参考链接

生成可调试的 Release 版本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值