- 比如进程中指令地址为0x0000aaaad96c0828编译时必须带-g,而且没有strip
[root@user mnt]# touch /tmp/memleak_print
[root@user mnt]# stack_id=0xcc3 with outstanding allocations: total_size=16 nr_allocs=4
0000aaaad96c0828: alloc_v3 @ 0x814+0x14
0000aaaad96c084c: alloc_v2 @ 0x838+0x14
0000aaaad96c0870: alloc_v1 @ 0x85c+0x14
0000aaaad96c08ac: main @ 0x880+0x2c
0000ffffb5ba73fc: <no-symbol>
0000ffffb5ba74cc: __libc_start_main @ 0x27434+0x98
0000aaaad96c0730: _start @ 0x700+0x30
/// 116代表进程号
[root@user mnt]# cat /proc/116/maps
起始地址 结束地址 属性 偏移地址 主从设备号 inode编号 文件名
aaaad96c0000-aaaad96c1000 r-xp 00000000 00:19 689872 /mnt/test_memleak
aaaad96d0000-aaaad96d1000 r--p 00000000 00:19 689872 /mnt/test_memleak
aaaad96d1000-aaaad96d2000 rw-p 00001000 00:19 689872 /mnt/test_memleak
aaaae8803000-aaaae8824000 rw-p 00000000 00:00 0 [heap]
ffffb5b80000-ffffb5d09000 r-xp 00000000 fe:00 136 /lib/libc.so.6
ffffb5d09000-ffffb5d18000 ---p 00189000 fe:00 136 /lib/libc.so.6
ffffb5d18000-ffffb5d1c000 r--p 00188000 fe:00 136 /lib/libc.so.6
ffffb5d1c000-ffffb5d1e000 rw-p 0018c000 fe:00 136 /lib/libc.so.6
ffffb5d1e000-ffffb5d2a000 rw-p 00000000 00:00 0
ffffb5d36000-ffffb5d60000 r-xp 00000000 fe:00 120 /lib/ld-linux-aarch64.so.1
ffffb5d6a000-ffffb5d6c000 rw-p 00000000 00:00 0
ffffb5d6c000-ffffb5d6e000 r--p 00000000 00:00 0 [vvar]
ffffb5d6e000-ffffb5d6f000 r-xp 00000000 00:00 0 [vdso]
ffffb5d6f000-ffffb5d71000 r--p 00029000 fe:00 120 /lib/ld-linux-aarch64.so.1
ffffb5d71000-ffffb5d73000 rw-p 0002b000 fe:00 120 /lib/ld-linux-aarch64.so.1
ffffea6ca000-ffffea6eb000 rw-p 00000000 00:00 0 [stack]
fffffffff000-1000000000000 --xp 00000000 00:00 0 [uprobes]
找到属性里面有x可执行的这一条
aaaad96c0000-aaaad96c1000 r-xp 00000000 00:19 689872 /mnt/test_memleak
起始地址 = aaaad96c0000
结束地址 = aaaad96c1000
偏移地址 = 00000000
elf文件中的指令地址 = 进程中的指令地址 - 起始地址 + 偏移地址
= 0000aaaad96c0828 - aaaad96c0000 + 00000000
= 0x828
readelf -s test_memleak | grep FUNC
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (2)
5: 0000000000000000 0 FUNC WEAK DEFAULT UND _[...]@GLIBC_2.17 (3)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND malloc@GLIBC_2.17 (3)
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sleep@GLIBC_2.17 (3)
9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND abort@GLIBC_2.17 (3)
10: 0000000000000000 0 FUNC GLOBAL DEFAULT UND free@GLIBC_2.17 (3)
39: 0000000000000734 20 FUNC LOCAL DEFAULT 13 call_weak_fn
47: 0000000000000750 0 FUNC LOCAL DEFAULT 13 deregister_tm_clones
48: 0000000000000780 0 FUNC LOCAL DEFAULT 13 register_tm_clones
50: 00000000000007c0 0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux
54: 0000000000000810 0 FUNC LOCAL DEFAULT 13 frame_dummy
61: 0000000000000814 36 FUNC LOCAL DEFAULT 13 alloc_v3
62: 0000000000000838 36 FUNC LOCAL DEFAULT 13 alloc_v2
63: 000000000000085c 36 FUNC LOCAL DEFAULT 13 alloc_v1
73: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_mai[...]
77: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@G[...]
80: 00000000000008e0 0 FUNC GLOBAL HIDDEN 14 _fini
82: 0000000000000000 0 FUNC GLOBAL DEFAULT UND malloc@GLIBC_2.17
83: 0000000000000000 0 FUNC GLOBAL DEFAULT UND sleep@GLIBC_2.17
87: 0000000000000000 0 FUNC GLOBAL DEFAULT UND abort@GLIBC_2.17
90: 0000000000000000 0 FUNC GLOBAL DEFAULT UND free@GLIBC_2.17
91: 0000000000000700 52 FUNC GLOBAL DEFAULT 13 _start
94: 0000000000000880 96 FUNC GLOBAL DEFAULT 13 main
97: 0000000000000628 0 FUNC GLOBAL HIDDEN 11 _init
0x828 执行到了 alloc_v3 的函数内部
61: 0000000000000814 36 FUNC LOCAL DEFAULT 13 alloc_v3
62: 0000000000000838 36 FUNC LOCAL DEFAULT 13 alloc_v2
llvm-dwarfdump -i test_memleak | grep DW_TAG_subprogram -A11
0x00000098: DW_TAG_subprogram
DW_AT_external (true)
DW_AT_name ("free")
DW_AT_decl_file ("/usr/aarch64-linux-gnu/include/stdlib.h")
DW_AT_decl_line (555)
DW_AT_decl_column (0x0d)
DW_AT_prototyped (true)
DW_AT_declaration (true)
DW_AT_sibling (0x000000ab)
0x000000a5: DW_TAG_formal_parameter
DW_AT_type (0x00000041 "void *")
--
0x000000ab: DW_TAG_subprogram
DW_AT_external (true)
DW_AT_name ("sleep")
DW_AT_decl_file ("/usr/aarch64-linux-gnu/include/unistd.h")
DW_AT_decl_line (464)
DW_AT_decl_column (0x15)
DW_AT_prototyped (true)
DW_AT_type (0x0000005d "unsigned int")
DW_AT_declaration (true)
DW_AT_sibling (0x000000c2)
0x000000bc: DW_TAG_formal_parameter
--
0x000000c2: DW_TAG_subprogram
DW_AT_external (true)
DW_AT_name ("malloc")
DW_AT_decl_file ("/usr/aarch64-linux-gnu/include/stdlib.h")
DW_AT_decl_line (540)
DW_AT_decl_column (0x0e)
DW_AT_prototyped (true)
DW_AT_type (0x00000041 "void *")
DW_AT_declaration (true)
DW_AT_sibling (0x000000d9)
0x000000d3: DW_TAG_formal_parameter
--
0x000000d9: DW_TAG_subprogram
DW_AT_external (true)
DW_AT_name ("main")
DW_AT_decl_file ("/home/anlan/Desktop/perf/arm32/libbpf-bootstrap/examples/c/test_memleak.c")
DW_AT_decl_line (47)
DW_AT_decl_column (0x05)
DW_AT_prototyped (true)
DW_AT_type (0x00000043 "int")
DW_AT_low_pc (0x0000000000000880)
DW_AT_high_pc (0x00000000000008e0)
DW_AT_frame_base (DW_OP_call_frame_cfa)
DW_AT_call_all_tail_calls (true)
--
0x00000141: DW_TAG_subprogram
DW_AT_name ("alloc_v1")
DW_AT_decl_file ("/home/anlan/Desktop/perf/arm32/libbpf-bootstrap/examples/c/test_memleak.c")
DW_AT_decl_line (40)
DW_AT_decl_column (15)
DW_AT_prototyped (true)
DW_AT_type (0x00000041 "void *")
DW_AT_low_pc (0x000000000000085c)
DW_AT_high_pc (0x0000000000000880)
DW_AT_frame_base (DW_OP_call_frame_cfa)
DW_AT_call_all_tail_calls (true)
DW_AT_sibling (0x0000017e)
--
0x0000017e: DW_TAG_subprogram
DW_AT_name ("alloc_v2")
DW_AT_decl_file ("/home/anlan/Desktop/perf/arm32/libbpf-bootstrap/examples/c/test_memleak.c")
DW_AT_decl_line (33)
DW_AT_decl_column (15)
DW_AT_prototyped (true)
DW_AT_type (0x00000041 "void *")
DW_AT_low_pc (0x0000000000000838)
DW_AT_high_pc (0x000000000000085c)
DW_AT_frame_base (DW_OP_call_frame_cfa)
DW_AT_call_all_tail_calls (true)
DW_AT_sibling (0x000001bb)
--
0x000001bb: DW_TAG_subprogram
DW_AT_name ("alloc_v3")
DW_AT_decl_file ("/home/anlan/Desktop/perf/arm32/libbpf-bootstrap/examples/c/test_memleak.c")
DW_AT_decl_line (7)
DW_AT_decl_column (0x0f)
DW_AT_prototyped (true)
DW_AT_type (0x00000041 "void *")
DW_AT_low_pc (0x0000000000000814)
DW_AT_high_pc (0x0000000000000838)
DW_AT_frame_base (DW_OP_call_frame_cfa)
DW_AT_call_all_tail_calls (true)
alloc_v3 指令地址范围 DW_AT_low_pc ~ DW_AT_high_pc
0x828 属于 alloc_v3 内部的指令地址
0000aaaad96c0828 执行到了 alloc_v3 的函数内部 文件名是 test_memleak.c
dwarfdump -l test_memleak
.debug_line: line number info for a single cu
Source lines (from CU-DIE at .debug_info offset 0x0000000c):
NS new statement, BB new basic block, ET end of text sequence
PE prologue end, EB epilogue begin
IS=val ISA number, DI=val discriminator value
<pc> [lno,col] NS BB ET PE EB IS= DI= uri: "filepath"
0x00000814 [ 8, 1] NS uri: "/home/anlan/Desktop/perf/arm32/libbpf-bootstrap/examples/c/test_memleak.c"
0x00000820 [ 9,18] NS
0x0000082c [ 11,12] NS
0x00000830 [ 12, 1] NS
0x00000838 [ 34, 1] NS
0x00000844 [ 35,18] NS
0x00000850 [ 37,12] NS
0x00000854 [ 38, 1] NS
0x0000085c [ 41, 1] NS
0x00000868 [ 42,18] NS
0x00000874 [ 44,12] NS
0x00000878 [ 45, 1] NS
0x00000880 [ 48, 1] NS
0x00000890 [ 49,15] NS
0x00000898 [ 50,12] NS
0x0000089c [ 51, 9] NS
0x000008a0 [ 53,12] NS
0x000008a4 [ 55,15] NS
0x000008b0 [ 57, 9] NS
0x000008b8 [ 59,15] NS
0x000008c0 [ 59,12] NS
0x000008c8 [ 61,13] NS
0x000008d0 [ 53,20] NS
0x000008dc [ 55,13] NS
0x000008e0 [ 55,13] NS ET
0x828 在 0x00000820 与 0x0000082c 之间,所以行号为 9
addr2line -e test_memleak 0x828
/home/anlan/Desktop/perf/arm32/libbpf-bootstrap/examples/c/test_memleak.c:9