导读:

题外话,在我看来 Debug 涉及三个能力:对问题现象的认知程度,对代码的熟悉程度,以及对系统知识的掌握程度。三者侧重不同方向而又互补,缺一不可。
而调查内存问题的难处在于:首先在于能否描述清楚问题的现象,什么情况下出现,进而找到怀疑对象,最终看能否顺藤摸瓜,检查怀疑有问题的代码和现象是否匹配。这个过程不仅仅是技术上的困难,更考验人的细心和耐心程度。
扫描堆并报告内存损坏和内存使用统计信息。 显示给定地址周围的内存块布局。 显示包含给定地址的内存块状态。 显示最大的堆内存块(潜在的内存占用大户)。
查找与给定地址相关联的内存对象的大小、类型和符号。 搜索并报告所有对给定对象的所有间接级别的引用。
查找给定 C++ 类的所有对象实例。 显示被选定或所有线程共享的对象。 显示带有数据对象上下文注释的反汇编指令。 内存区域内的数据模式。 包括所有段及其属性的详细进程映射。
build_gdb.sh本质上就是替换了一些 gdb 源文件,然后编译 gdb(可能需要在这个脚本中修改 gdb 相关编译参数)# 最终使用的如下编译参数
../configure --prefix=/usr/local --disable-binutils --with-python --disable-ld --disable-gold --disable-gas --disable-sim --disable-gprof --disable-source-highlight CXXFLAGS='-g' CFLAGS='-g' LDFLAGS="-static-libstdc++ -static-libgcc"
gdb a.out core.1234
打印堆相关信息 检查特定内存地址的相关信息(包括在哪个 segment、block,直接引用和间接引用,以及内存 layout 等) 其他辅助命令
(gdb) heap
jemalloc 5.3.0
arena[0]: inuse_blks=8981 inuse_bytes=1825672 free_blks=1788 free_bytes=2835576
arena[1]: inuse_blks=1 inuse_bytes=16 free_blks=256 free_bytes=2097136
arena[2]: inuse_blks=124 inuse_bytes=16392 free_blks=2341 free_bytes=2080760
There are 3 arenas Total 8MB
Total 9106 blocks in-use of 1MB
Total 4385 blocks free of 6MB
(gdb) heap v
jemalloc 5.3.0
arena[0]: inuse_blks=8981 inuse_bytes=1825672 free_blks=1788 free_bytes=2835576
bin[0]: curslabs=1 nonfull_slabs=0
bin[1]: curslabs=2 nonfull_slabs=0
bin[2]: curslabs=38 nonfull_slabs=0
bin[3]: curslabs=2 nonfull_slabs=0
bin[4]: curslabs=38 nonfull_slabs=0
bin[5]: curslabs=1 nonfull_slabs=0
bin[6]: curslabs=2 nonfull_slabs=1
bin[7]: curslabs=1 nonfull_slabs=0
bin[8]: curslabs=1 nonfull_slabs=0
bin[9]: curslabs=1 nonfull_slabs=0
bin[10]: curslabs=1 nonfull_slabs=0
bin[11]: curslabs=1 nonfull_slabs=0
bin[12]: curslabs=6 nonfull_slabs=5
bin[13]: curslabs=1 nonfull_slabs=0
bin[14]: curslabs=1 nonfull_slabs=0
bin[15]: curslabs=1 nonfull_slabs=0
bin[16]: curslabs=6 nonfull_slabs=1
bin[17]: curslabs=1 nonfull_slabs=0
bin[18]: curslabs=1 nonfull_slabs=0
bin[19]: curslabs=3 nonfull_slabs=0
bin[20]: curslabs=5 nonfull_slabs=0
bin[21]: curslabs=3 nonfull_slabs=0
bin[22]: curslabs=1 nonfull_slabs=0
bin[23]: curslabs=8 nonfull_slabs=0
bin[24]: curslabs=2 nonfull_slabs=0
bin[25]: curslabs=2 nonfull_slabs=0
bin[26]: curslabs=1 nonfull_slabs=0
bin[27]: curslabs=10 nonfull_slabs=0
bin[28]: curslabs=4 nonfull_slabs=0
bin[30]: curslabs=2 nonfull_slabs=0
bin[31]: curslabs=1 nonfull_slabs=0
bin[32]: curslabs=4 nonfull_slabs=0
bin[35]: curslabs=5 nonfull_slabs=0
arena[1]: inuse_blks=1 inuse_bytes=16 free_blks=256 free_bytes=2097136
bin[1]: curslabs=1 nonfull_slabs=0
arena[2]: inuse_blks=124 inuse_bytes=16392 free_blks=2341 free_bytes=2080760
bin[0]: curslabs=1 nonfull_slabs=0
bin[1]: curslabs=1 nonfull_slabs=0
bin[2]: curslabs=1 nonfull_slabs=0
bin[3]: curslabs=1 nonfull_slabs=0
bin[4]: curslabs=2 nonfull_slabs=0
bin[5]: curslabs=1 nonfull_slabs=0
bin[6]: curslabs=1 nonfull_slabs=0
bin[7]: curslabs=1 nonfull_slabs=0
bin[8]: curslabs=1 nonfull_slabs=0
bin[9]: curslabs=1 nonfull_slabs=0
bin[10]: curslabs=2 nonfull_slabs=0
bin[12]: curslabs=2 nonfull_slabs=0
bin[13]: curslabs=2 nonfull_slabs=0
bin[14]: curslabs=1 nonfull_slabs=0
bin[17]: curslabs=1 nonfull_slabs=0
bin[21]: curslabs=1 nonfull_slabs=0
bin[23]: curslabs=1 nonfull_slabs=0
There are 3 arenas Total 8MB
Total 9106 blocks in-use of 1MB
Total 4385 blocks free of 6MB
========== In-use Memory Histogram ==========
Size-Range Count Total-Bytes
0 - 16 806(8%) 9KB(0%)
16 - 32 4747(52%) 148KB(8%)
32 - 64 2788(30%) 168KB(9%)
64 - 128 99(1%) 9KB(0%)
128 - 256 168(1%) 36KB(2%)
256 - 512 113(1%) 45KB(2%)
512 - 1024 114(1%) 100KB(5%)
1024 - 2KB 163(1%) 264KB(14%)
2KB - 4KB 93(1%) 315KB(17%)
4KB - 8KB 2(0%) 14KB(0%)
8KB - 16KB 5(0%) 76KB(4%)
16KB - 32KB 4(0%) 108KB(6%)
--Type <RET> for more, q to quit, c to continue without paging--c
32KB - 64KB 2(0%) 104KB(5%)
64KB - 128KB 1(0%) 80KB(4%)
256KB - 512KB 1(0%) 320KB(17%)
Total 9106 1MB
========== Free Memory Histogram ==========
Size-Range Count Total-Bytes
0 - 16 1242(28%) 14KB(0%)
16 - 32 245(5%) 7KB(0%)
32 - 64 540(12%) 27KB(0%)
64 - 128 1373(31%) 130KB(1%)
128 - 256 536(12%) 99KB(1%)
256 - 512 255(5%) 90KB(1%)
512 - 1024 82(1%) 56KB(0%)
1024 - 2KB 57(1%) 88KB(1%)
2KB - 4KB 20(0%) 69KB(1%)
4KB - 8KB 11(0%) 78KB(1%)
8KB - 16KB 14(0%) 184KB(2%)
16KB - 32KB 6(0%) 144KB(2%)
256KB - 512KB 1(0%) 484KB(7%)
512KB - 3(0%) 5MB(78%)
Total 4385 6MB
(gdb) heap leak
Potentially leaked heap memory blocks:
[1] addr=0x7ffff001e040 size=32
Total 1 (32) leak candidates out of 9106 (1MB) in-use memory blocks
(gdb) heap tb 8
Top 8 biggest in-use heap memory blocks:
addr=0x7fffee801000 size=2093056 (1MB)
addr=0x7fffeda43000 size=1822720 (1MB)
addr=0x7fffed87c000 size=1589248 (1MB)
addr=0x7fffed7b2000 size=495616 (484KB)
addr=0x7fffed82b200 size=327680 (320KB)
addr=0x7ffff0008e00 size=81920 (80KB)
addr=0x7ffff01c4b00 size=65536 (64KB)
addr=0x7ffff00aa300 size=40960 (40KB)
(gdb) heap tu 8
[1] [heap block] 0x7ffff01bd7c0--0x7ffff01c37c0 size=24576
|--> 674KB (842 blocks)
[2] [heap block] 0x7ffff0025320--0x7ffff00253c0 size=160
|--> 360KB (5 blocks)
[3] [heap block] 0x7fffed82b200--0x7fffed87b200 size=327680
|--> 320KB (1 blocks)
[4] [heap block] 0x7ffff0000000--0x7ffff0007000 size=28672
|--> 298KB (732 blocks)
[5] [heap block] 0x7ffff0024860--0x7ffff0024870 size=16
|--> 80KB (2 blocks)
[6] [.data/.bss] home/doodle.wang/Git/nebula-ng/build/bin/test/../3rd/libstdc++.so.6 Unknown global 0x7ffff5a5c268: 0x7ffff0008e00
|--> 80KB (1 blocks)
[7] [heap block] 0x7ffff0008e00--0x7ffff001ce00 size=81920
|--> 80KB (1 blocks)
[8] [heap block] 0x7ffff00740e0--0x7ffff0074140 size=96
|--> 64KB (2 blocks)
打印 0x7ffff001e040 这个地址所在 segment
(gdb) heap c 0x7ffff001e040
jemalloc 5.3.0
arena[0]: inuse_blks=8981 inuse_bytes=1825672 free_blks=1788 free_bytes=2835576
arena[1]: inuse_blks=1 inuse_bytes=16 free_blks=256 free_bytes=2097136
arena[2]: inuse_blks=124 inuse_bytes=16392 free_blks=2341 free_bytes=2080760
There are 3 arenas Total 8MB
Total 9106 blocks in-use of 1MB
Total 4385 blocks free of 6MB
(gdb) heap b 0x7ffff001e040
[In-use]
[Address] 0x7ffff001e040
[Size] 32
[Offset] 0
从该对象开始,经过若干层直接引用或间接引用,最终能触及的所有变量使用的内存。 该对象能直接应用的其他对象所使用的内存
打印 executionPlan
这个对象的统计信息,它直接引用 448 个子节,能触及 731 个 block,总计 179KB 大小的内存地址
(gdb) heap u executionPlan
Heap memory consumed by [stack] thread 1 frame 0 executionPlan @0x7fffffffdd30
All reachable:
|--> 179KB (731 blocks)
Directly referenced:
|--> 448 (1 blocks)
4. 检查特定内存地址被哪些对象所引用
有一个shared_ptr<PlanNode>, 其对象地址在0x7ffff0025d30,检查这个地址被谁所引用
(gdb) p plan
$4 = {<std::__shared_ptr<nebula::PlanNode, __gnu_cxx::_S_atomic>> = {<std::__shared_ptr_access<nebula::PlanNode, __gnu_cxx::_S_atomic, false, false>> = {<No data fields>}, _M_ptr = 0x7ffff0025d30,
_M_refcount = {_M_pi = 0x7ffff0025d20}}, <No data fields>}
(gdb) ref 0x7ffff0025d30
Search for object type associated with 0x7ffff0025d30
Address 0x7ffff0025d30 belongs to heap block [0x7ffff0025d20, 0x7ffff0025dc0] size=160
------------------------- 1 -------------------------
[heap block] 0x7ffff0025d20--0x7ffff0025dc0 size=160 (type="std::_Sp_counted_ptr_inplace<nebula::InsertNode, std::allocator<nebula::InsertNode>, (__gnu_cxx::_Lock_policy)2>") @+16
5. 检查特定范围的内存地址被哪些对象直接和间接引用
进而检查 0x7ffff0025d30
这个地址如何被直接和间接引用
(gdb) ref 0x7ffff0025d30 8 2
Search for references to 0x7ffff0025d30 size 8 up to 2 levels of indirection
------------------------- Level 2 -------------------------
[stack] thread 4 frame 7 rsp+1304 @0x7fffee7ed068: 0x7ffff00861c4
[stack] thread 4 frame 9 guard.executionPlan_ @0x7fffee7ee520: 0x7ffff00860d0
[heap block] 0x7ffff007cc00--0x7ffff007d200 size=1536 (type="std::_Sp_counted_ptr_inplace<nebula::exec::ExecutionContext, std::allocator<nebula::exec::ExecutionContext>, (__gnu_cxx::_Lock_policy)2>") @+104: 0x7ffff00860d0
[heap block] 0x7ffff008bd80--0x7ffff008be60 size=224 (type="std::_Sp_counted_ptr_inplace<nebula::exec::Pipeline, std::allocator<nebula::exec::Pipeline>, (__gnu_cxx::_Lock_policy)2>") @+72: 0x7ffff00860c0
[stack] thread 1 frame 0 executionPlan::"std::__shared_ptr<nebula::exec::ExecutionPlan, __gnu_cxx::_S_atomic>"._M_ptr @0x7fffffffdd30: 0x7ffff00860d0
[stack] thread 1 frame 0 executionPlan::"std::__shared_ptr<nebula::exec::ExecutionPlan, __gnu_cxx::_S_atomic>"._M_refcount._M_pi @0x7fffffffdd38: 0x7ffff00860c0
|--> [heap block] 0x7ffff00860c0--0x7ffff0086280 size=448
[stack] thread 4 frame 6 rsp+40 @0x7fffee7eca58: 0x7ffff00a16c0
[stack] thread 4 frame 6 this @0x7fffee7ecb38: 0x7ffff00a16c0
[stack] thread 4 frame 7 rsp+296 @0x7fffee7ecc78: 0x7ffff00a16c0
[stack] thread 4 frame 7 rsp+344 @0x7fffee7ecca8: 0x7ffff00a16c0
[stack] thread 4 frame 7 rsp+352 @0x7fffee7eccb0: 0x7ffff00a16c0
[stack] thread 4 frame 7 memGraphInsertNodes.this @0x7fffee7ecd28: 0x7ffff00a16c0
[stack] thread 4 frame 7 this @0x7fffee7ed0d0: 0x7ffff00a16c0
[stack] thread 4 frame 8 rsp+8 @0x7fffee7ed0e8: 0x7ffff00a16c0
[stack] thread 4 frame 8 this @0x7fffee7ed0f8: 0x7ffff00a16c0
[stack] thread 4 frame 9 op @0x7fffee7ee500: 0x7ffff00a16c0
[heap block] 0x7ffff0000000--0x7ffff0007000 size=28672 @+17992: 0x7ffff00a16c0
[heap block] 0x7ffff0034c98--0x7ffff0034ca0 size=8 @+0: 0x7ffff00a16c0
|--> [heap block] 0x7ffff00a16c0--0x7ffff00a1800 size=320
------------------------- Level 1 -------------------------
[heap block] 0x7ffff00860c0--0x7ffff0086280 size=448 (type="struct nebula::exec::ExecutionPlan").logicPlan_::"std::__shared_ptr<nebula::PlanNode, __gnu_cxx::_S_atomic>"._M_ptr @+40: 0x7ffff0025d30
[heap block] 0x7ffff00a16c0--0x7ffff00a1800 size=320 (type="struct nebula::exec::InsertNode").planNode_::"std::__shared_ptr<nebula::InsertNode const, __gnu_cxx::_S_atomic>"._M_ptr @+272: 0x7ffff0025d30
[stack] thread 1 frame 0 rsp+3128 @0x7fffffffdd48: 0x7ffff0025d30
[stack] thread 1 frame 0 plan::"std::__shared_ptr<nebula::PlanNode, __gnu_cxx::_S_atomic>"._M_ptr @0x7fffffffdd58: 0x7ffff0025d30
|--> searched target [0x7ffff0025d30, 0x7ffff0025d38)
(gdb) pattern <start> <end>
(gdb) pattern 0x7ffff0025d20 0x7ffff0025d40
memory pattern [0x7ffff0025d20, 0x7ffff0025d40]:
0x7ffff0025d20: 0x7ffff6ff4350 => [.text/.rodata] home/doodle.wang/Git/nebula-ng/build/bin/test/../lib/libnb-plan.so vtable for std::_Sp_counted_ptr_inplace<nebula::InsertNode, std::allocator<nebula::InsertNode>, (__gnu_cxx::_Lock_policy)2> (0x7ffff6ff4340--0x7ffff6ff4378)
0x7ffff0025d28: 0x100000004
0x7ffff0025d30: 0x7ffff6ff85c0 => [.text/.rodata] home/doodle.wang/Git/nebula-ng/build/bin/test/../lib/libnb-plan.so vtable for nebula::InsertNode (0x7ffff6ff85b0--0x7ffff6ff8648)
0x7ffff0025d38: 0
(gdb) obj <expression>
(gdb) dt <expression>
(gdb) dt ExecutionPlan
type=nebula::exec::ExecutionPlan size=376
{
+0 (base) struct std::enable_shared_from_this<nebula::exec::ExecutionPlan> size=16
{
+0 struct std::weak_ptr<nebula::exec::ExecutionPlan> _M_weak_this size=16
}
+16 struct nebula::gql::RequestContext* rctx_ size=8
+24 struct std::shared_ptr<nebula::PlanNode> logicPlan_ size=16
+40 struct nebula::exec::ConsumerSupplier consumerSupplier_ size=32
+72 struct folly::Executor* executor_ size=8
+80 struct std::shared_ptr<nebula::exec::ExecutionContext> executionContext_ size=16
+96 struct std::vector<std::shared_ptr<nebula::exec::Pipeline>, std::allocator<std::shared_ptr<nebula::exec::Pipeline> > > pipelines_ size=24
+120 struct size_t numTotalPipelines_ size=8
+128 struct size_t numRunningPipelines_ size=8
+136 struct size_t numFinishPipelines_ size=8
+144 struct std::unordered_map<long, nebula::exec::Operator*, std::hash<long>, std::equal_to<long>, std::allocator<std::pair<long const, nebula::exec::Operator*> > > consumerOperators_ size=56
+200 struct std::mutex mutex_ size=40
+240 struct std::atomic<bool> terminateRequested_ size=1
+241 struct std::atomic<bool> pauseRequested_ size=1
+244 struct std::atomic<int> toYield_ size=4
+248 struct int32_t numRunningThreads_ size=4
+252 struct nebula::exec::ExecutionState state_ size=4
+256 struct std::vector<nebula::exec::NPromise<folly::Unit>, std::allocator<nebula::exec::NPromise<folly::Unit> > > threadFinishPromises_ size=24
+280 struct std::vector<folly::SemiFuture<folly::Unit>, std::allocator<folly::SemiFuture<folly::Unit> > > completeFutures_ size=24
+304 struct nebula::Status result_ size=40
+344 struct std::function<folly::Future<folly::Unit> ()> killQuery_ size=32
};
✦
如果你觉得 NebulaGraph能帮到你,或者你只是单纯支持开源精神,可以在 GitHub 上为 NebulaGraph 点个 Star!每一个 Star 都是对我们的支持和鼓励✨
https://github.com/vesoft-inc/nebula
✦
✦

扫码添加
可爱星云
技术交流
资料分享
NebulaGraph 用户案例
✦
风控场景:携程|Airwallex|众安保险|中国移动|Akulaku|邦盛科技|360数科|BOSS直聘|金蝶征信|快手|青藤云安全
平台建设:博睿数据|携程|众安科技|微信|OPPO|vivo|美团|百度爱番番|携程金融|普适智能|BIGO
✦
✦



文章转载自NebulaGraph 技术社区,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




