最近在写一个内存泄露和死锁检测的检测SDK项目,写下日志简单记录一下。
用的方案是 plt hook 和 epbf。

2026-02-04

写项目最开始呢就先配了一下 clangd, clang-tidy, clang-format,谷歌的代码风格和规范除个别几条还是挺好用的。

先是实现了一下 hook 模块,然后写了一个例子,测试如下:

2026-02-05

添加了分配释放函数的记录模块,不过还有一些遗漏。
添加了检测结果的调用栈,行号的命令行和日志输出。
添加了测试文件。

测试文件输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
Successfully hooked functions: malloc, free, calloc, operator new, operator new[]
Skipped functions (not in PLT): realloc, operator delete, operator delete[]


=== Memory Tracker Status ===
Total allocated: 1424 bytes
Total freed: 640 bytes
Active allocations: 6
Potential leaks: 6

Detailed leak information:

Leak at 0x5afb0c3a9d30 (size: 256 bytes)
Callstack:
[0] Absolute: 0x5afaf15de488, Relative: 0x1488
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: TestPartialFreeLeak() at /home/test/projects/nv detector/examples/memory_leak_test.cpp:83
[1] Absolute: 0x5afaf15de681, Relative: 0x1681
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: main at /home/test/projects/nv detector/examples/memory_leak_test.cpp:157
[2] Absolute: 0x77308782a578, Relative: 0x2a578
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: __libc_start_call_main at ./csu/../sysdeps/nptl/libc_start_call_main.h:74
[3] Absolute: 0x77308782a63b, Relative: 0x2a63b
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: call_init at ./csu/../csu/libc-start.c:128
[4] Absolute: 0x5afaf15de205, Relative: 0x1205
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: _start at ??:?

Leak at 0x5afb0c3a9c50 (size: 64 bytes)
Callstack:
[0] Absolute: 0x5afaf15de46c, Relative: 0x146c
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: TestPartialFreeLeak() at /home/test/projects/nv detector/examples/memory_leak_test.cpp:81
[1] Absolute: 0x5afaf15de681, Relative: 0x1681
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: main at /home/test/projects/nv detector/examples/memory_leak_test.cpp:157
[2] Absolute: 0x77308782a578, Relative: 0x2a578
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: __libc_start_call_main at ./csu/../sysdeps/nptl/libc_start_call_main.h:74
[3] Absolute: 0x77308782a63b, Relative: 0x2a63b
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: call_init at ./csu/../csu/libc-start.c:128
[4] Absolute: 0x5afaf15de205, Relative: 0x1205
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: _start at ??:?

Leak at 0x5afb0c3ab9e0 (size: 160 bytes)
Callstack:
[0] Absolute: 0x5afaf15de41e, Relative: 0x141e
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: TestCallocLeak() at /home/test/projects/nv detector/examples/memory_leak_test.cpp:66
[1] Absolute: 0x5afaf15de67c, Relative: 0x167c
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: main at /home/test/projects/nv detector/examples/memory_leak_test.cpp:156
[2] Absolute: 0x77308782a578, Relative: 0x2a578
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: __libc_start_call_main at ./csu/../sysdeps/nptl/libc_start_call_main.h:74
[3] Absolute: 0x77308782a63b, Relative: 0x2a63b
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: call_init at ./csu/../csu/libc-start.c:128
[4] Absolute: 0x5afaf15de205, Relative: 0x1205
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: _start at ??:?

Leak at 0x5afb0c3a90d0 (size: 200 bytes)
Callstack:
[0] Absolute: 0x5afaf15de3a5, Relative: 0x13a5
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: TestNewArrayLeak() at /home/test/projects/nv detector/examples/memory_leak_test.cpp:48 (discriminator 1)
[1] Absolute: 0x5afaf15de677, Relative: 0x1677
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: main at /home/test/projects/nv detector/examples/memory_leak_test.cpp:155
[2] Absolute: 0x77308782a578, Relative: 0x2a578
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: __libc_start_call_main at ./csu/../sysdeps/nptl/libc_start_call_main.h:74
[3] Absolute: 0x77308782a63b, Relative: 0x2a63b
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: call_init at ./csu/../csu/libc-start.c:128
[4] Absolute: 0x5afaf15de205, Relative: 0x1205
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: _start at ??:?

Leak at 0x5afb0c3a9000 (size: 4 bytes)
Callstack:
[0] Absolute: 0x5afaf15de33c, Relative: 0x133c
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: TestNewLeak() at /home/test/projects/nv detector/examples/memory_leak_test.cpp:35 (discriminator 1)
[1] Absolute: 0x5afaf15de672, Relative: 0x1672
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: main at /home/test/projects/nv detector/examples/memory_leak_test.cpp:154
[2] Absolute: 0x77308782a578, Relative: 0x2a578
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: __libc_start_call_main at ./csu/../sysdeps/nptl/libc_start_call_main.h:74
[3] Absolute: 0x77308782a63b, Relative: 0x2a63b
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: call_init at ./csu/../csu/libc-start.c:128
[4] Absolute: 0x5afaf15de205, Relative: 0x1205
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: _start at ??:?

Leak at 0x5afb0c3a9060 (size: 100 bytes)
Callstack:
[0] Absolute: 0x5afaf15de2ee, Relative: 0x12ee
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: TestMallocLeak() at /home/test/projects/nv detector/examples/memory_leak_test.cpp:21
[1] Absolute: 0x5afaf15de66d, Relative: 0x166d
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: main at /home/test/projects/nv detector/examples/memory_leak_test.cpp:153
[2] Absolute: 0x77308782a578, Relative: 0x2a578
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: __libc_start_call_main at ./csu/../sysdeps/nptl/libc_start_call_main.h:74
[3] Absolute: 0x77308782a63b, Relative: 0x2a63b
Module: /lib/x86_64-linux-gnu/libc.so.6
Source: call_init at ./csu/../csu/libc-start.c:128
[4] Absolute: 0x5afaf15de205, Relative: 0x1205
Module: /home/test/projects/nv detector/build/examples/memory_leak_test
Source: _start at ??:?

===========================

2026-02-06

今天加入了死锁检测模块,遇到一个递归 hook 的 bug,调试解决了一下,详见:PLT Hook 的死锁递归 bug 排查

死锁检测模块检测结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
WARNING: Note: pthread_mutex_trylock not found in PLT
=== Potential Deadlock Detected! ===
Lock chain:
Lock 0x646bfadcb080 (Mutex) held by thread 128660625417920
Acquired at:
[0] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0xaa79) [0x750423d79a79]
[1] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0xa5b9) [0x750423d795b9]
[2] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0x9726) [0x750423d78726]
[3] ./deadlock_test(+0x17d1) [0x646bfadc67d1]
[4] ./deadlock_test(+0x1826) [0x646bfadc6826]
[5] ./deadlock_test(+0x1488) [0x646bfadc6488]
[6] ./deadlock_test(+0x2805) [0x646bfadc7805]
[7] ./deadlock_test(+0x27b1) [0x646bfadc77b1]
[8] ./deadlock_test(+0x2752) [0x646bfadc7752]
[9] ./deadlock_test(+0x2722) [0x646bfadc7722]
[10] ./deadlock_test(+0x2702) [0x646bfadc7702]
[11] /lib/x86_64-linux-gnu/libstdc++.so.6(+0xf2324) [0x750423af2324]
[12] /lib/x86_64-linux-gnu/libc.so.6(+0xa27f1) [0x7504236a27f1]
[13] /lib/x86_64-linux-gnu/libc.so.6(+0x133b5c) [0x750423733b5c]
Waiting for locks: 0x646bfadcb040 (held by thread 128660633810624)

Lock 0x646bfadcb040 (Mutex) held by thread 128660633810624
Acquired at:
[0] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0xaa79) [0x750423d79a79]
[1] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0xa5b9) [0x750423d795b9]
[2] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0x9726) [0x750423d78726]
[3] ./deadlock_test(+0x17d1) [0x646bfadc67d1]
[4] ./deadlock_test(+0x1826) [0x646bfadc6826]
[5] ./deadlock_test(+0x13ad) [0x646bfadc63ad]
[6] ./deadlock_test(+0x2805) [0x646bfadc7805]
[7] ./deadlock_test(+0x27b1) [0x646bfadc77b1]
[8] ./deadlock_test(+0x2752) [0x646bfadc7752]
[9] ./deadlock_test(+0x2722) [0x646bfadc7722]
[10] ./deadlock_test(+0x2702) [0x646bfadc7702]
[11] /lib/x86_64-linux-gnu/libstdc++.so.6(+0xf2324) [0x750423af2324]
[12] /lib/x86_64-linux-gnu/libc.so.6(+0xa27f1) [0x7504236a27f1]
[13] /lib/x86_64-linux-gnu/libc.so.6(+0x133b5c) [0x750423733b5c]
Waiting for locks: 0x646bfadcb080 (held by thread 128660625417920)

=== Lock Detector Status ===
Active locks: 2
Active threads: 2

Detailed lock information:

Lock 0x646bfadcb080 (Mutex) held by thread 128660625417920
Acquired at:
[0] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0xaa79) [0x750423d79a79]
[1] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0xa5b9) [0x750423d795b9]
[2] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0x9726) [0x750423d78726]
[3] ./deadlock_test(+0x17d1) [0x646bfadc67d1]
[4] ./deadlock_test(+0x1826) [0x646bfadc6826]
[5] ./deadlock_test(+0x1488) [0x646bfadc6488]
[6] ./deadlock_test(+0x2805) [0x646bfadc7805]
[7] ./deadlock_test(+0x27b1) [0x646bfadc77b1]
[8] ./deadlock_test(+0x2752) [0x646bfadc7752]
[9] ./deadlock_test(+0x2722) [0x646bfadc7722]
[10] ./deadlock_test(+0x2702) [0x646bfadc7702]
[11] /lib/x86_64-linux-gnu/libstdc++.so.6(+0xf2324) [0x750423af2324]
[12] /lib/x86_64-linux-gnu/libc.so.6(+0xa27f1) [0x7504236a27f1]
[13] /lib/x86_64-linux-gnu/libc.so.6(+0x133b5c) [0x750423733b5c]
Waiting for locks: 0x646bfadcb040 (held by thread 128660633810624)

Lock 0x646bfadcb040 (Mutex) held by thread 128660633810624
Acquired at:
[0] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0xaa79) [0x750423d79a79]
[1] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0xa5b9) [0x750423d795b9]
[2] /home/test/projects/nv detector/build/bin/libnv_detector.so(+0x9726) [0x750423d78726]
[3] ./deadlock_test(+0x17d1) [0x646bfadc67d1]
[4] ./deadlock_test(+0x1826) [0x646bfadc6826]
[5] ./deadlock_test(+0x13ad) [0x646bfadc63ad]
[6] ./deadlock_test(+0x2805) [0x646bfadc7805]
[7] ./deadlock_test(+0x27b1) [0x646bfadc77b1]
[8] ./deadlock_test(+0x2752) [0x646bfadc7752]
[9] ./deadlock_test(+0x2722) [0x646bfadc7722]
[10] ./deadlock_test(+0x2702) [0x646bfadc7702]
[11] /lib/x86_64-linux-gnu/libstdc++.so.6(+0xf2324) [0x750423af2324]
[12] /lib/x86_64-linux-gnu/libc.so.6(+0xa27f1) [0x7504236a27f1]
[13] /lib/x86_64-linux-gnu/libc.so.6(+0x133b5c) [0x750423733b5c]
Waiting for locks: 0x646bfadcb080 (held by thread 128660625417920)

Thread Information:

Thread 128660625417920:
Held locks: 0x646bfadcb080
Waiting for locks: 0x646bfadcb040 (held by thread 128660633810624)

Thread 128660633810624:
Held locks: 0x646bfadcb040
Waiting for locks: 0x646bfadcb080 (held by thread 128660625417920)

===========================

2026-02-09

修复了realloc的检测逻辑问题