mtrace输出结果分析
时间:2007-04-04 来源:loughsky
做了一个很简单的测试程序,来分析mtrace的输出结果。
#include <stdio.h>
#include <stdlib.h>
#include <mcheck.h> int main(void)
{
mtrace();
char *p=malloc(10);
return 0;
} 输出结果为 = Start
@ ./t2:(mtrace+0xdb)[0x8048397] + 0x8b333c8 0xa
输出结果显示,我们是在执行0x8048397指令时,进行内存分配的。 mtrace,为一个库函数,它在elf文件中的symbol中,需要进行动态链接。 我们可以通过readelf -a 来查看elf文件的内容。 Relocation section '.rel.plt' at offset 0x25c contains 3 entries:
Offset Info Type Sym.Value Sym. Name
08049570 00000107 R_386_JUMP_SLOT 0804829c malloc
08049574 00000207 R_386_JUMP_SLOT 080482ac __libc_start_main
08049578 00000407 R_386_JUMP_SLOT 080482bc mtrace
注意这里mtrace的value为080482bc,080482bc+0xdb=0x8048397。 mtrace的这个输出结果是通过_dl_addr函数来实现的。具体含义,还不是很清楚。 其实这里的输出结果并不理想,如果能够打印出char *p=malloc(10);对于我们编程将更加有力。 elf文件的调试信息是通过dwarf格式,保存在文件的某些section中的,具体的可以参见我博客中,关于dwarf格式的一些文档。 在elf文件中,没有保存源文件的源码,它只是保存了机器代码与源文件行号的一个对应关系。在elf文件中,给出了源码的绝对地址,这样gdb在调试的时候,就可以通过这个路径找到对应的源文件。 我们可以做一个实验,在通过gcc -g编译出一个执行文件后,将执行文件拷贝到其他路径后,仍然可以通过gdb调试。但是如果你把源文件改名后,在通过gdb调试原来编译出来的执行文件会报错。 我们可以通过readelf --debug-dump 来读取debug信息。 这里我们只关注如下部分: Line Number Statements:
Extended opcode 2: set Address to 0x8048378
Special opcode 10: advance Address by 0 to 0x8048378 and Line by 5 to 6
Special opcode 230: advance Address by 16 to 0x8048388 and Line by 1 to 7
Special opcode 77: advance Address by 5 to 0x804838d and Line by 2 to 9
Special opcode 230: advance Address by 16 to 0x804839d and Line by 1 to 10
Special opcode 76: advance Address by 5 to 0x80483a2 and Line by 1 to 11
Advance PC by 2 to 80483a4
Extended opcode 1: End of Sequence
我们再来将0x8048397进行查找,应该对应: Special opcode 77: advance Address by 5 to 0x804838d and Line by 2 to 9 也就是char *p=malloc(10);
关于elf文件中dwarf格式的操作,有一个开发包libdwarf,我还在继续研究。
#include <stdlib.h>
#include <mcheck.h> int main(void)
{
mtrace();
char *p=malloc(10);
return 0;
} 输出结果为 = Start
@ ./t2:(mtrace+0xdb)[0x8048397] + 0x8b333c8 0xa
输出结果显示,我们是在执行0x8048397指令时,进行内存分配的。 mtrace,为一个库函数,它在elf文件中的symbol中,需要进行动态链接。 我们可以通过readelf -a 来查看elf文件的内容。 Relocation section '.rel.plt' at offset 0x25c contains 3 entries:
Offset Info Type Sym.Value Sym. Name
08049570 00000107 R_386_JUMP_SLOT 0804829c malloc
08049574 00000207 R_386_JUMP_SLOT 080482ac __libc_start_main
08049578 00000407 R_386_JUMP_SLOT 080482bc mtrace
注意这里mtrace的value为080482bc,080482bc+0xdb=0x8048397。 mtrace的这个输出结果是通过_dl_addr函数来实现的。具体含义,还不是很清楚。 其实这里的输出结果并不理想,如果能够打印出char *p=malloc(10);对于我们编程将更加有力。 elf文件的调试信息是通过dwarf格式,保存在文件的某些section中的,具体的可以参见我博客中,关于dwarf格式的一些文档。 在elf文件中,没有保存源文件的源码,它只是保存了机器代码与源文件行号的一个对应关系。在elf文件中,给出了源码的绝对地址,这样gdb在调试的时候,就可以通过这个路径找到对应的源文件。 我们可以做一个实验,在通过gcc -g编译出一个执行文件后,将执行文件拷贝到其他路径后,仍然可以通过gdb调试。但是如果你把源文件改名后,在通过gdb调试原来编译出来的执行文件会报错。 我们可以通过readelf --debug-dump 来读取debug信息。 这里我们只关注如下部分: Line Number Statements:
Extended opcode 2: set Address to 0x8048378
Special opcode 10: advance Address by 0 to 0x8048378 and Line by 5 to 6
Special opcode 230: advance Address by 16 to 0x8048388 and Line by 1 to 7
Special opcode 77: advance Address by 5 to 0x804838d and Line by 2 to 9
Special opcode 230: advance Address by 16 to 0x804839d and Line by 1 to 10
Special opcode 76: advance Address by 5 to 0x80483a2 and Line by 1 to 11
Advance PC by 2 to 80483a4
Extended opcode 1: End of Sequence
我们再来将0x8048397进行查找,应该对应: Special opcode 77: advance Address by 5 to 0x804838d and Line by 2 to 9 也就是char *p=malloc(10);
关于elf文件中dwarf格式的操作,有一个开发包libdwarf,我还在继续研究。
相关阅读 更多 +