碰到一个dangling pointer导致进程core的问题,此类问题很常见,从上图m_vRelativePosition.y
和z
的异常值可以猜测,m_targetDomArea
指向的内存被踩坏了,或是m_targetDomArea
指向的对象已被销毁,其内存可能已被重新分配。
这里不去讨论m_targetDomArea
野的原因(熟悉这块逻辑的同事已经在上图指出具体原因),只去研究导致core的直接原因是什么。
There is no audience.
碰到一个dangling pointer导致进程core的问题,此类问题很常见,从上图m_vRelativePosition.y
和z
的异常值可以猜测,m_targetDomArea
指向的内存被踩坏了,或是m_targetDomArea
指向的对象已被销毁,其内存可能已被重新分配。
这里不去讨论m_targetDomArea
野的原因(熟悉这块逻辑的同事已经在上图指出具体原因),只去研究导致core的直接原因是什么。
近期用gdb调试coredump文件时发现会有warning:
warning: Unexpected size of section `.reg-xstate/13997' in core file.
起初以为是core文件有问题,后发现其实是低版本gdb(8.0版本)无法识别CPU的某些寄存器而做出的提示。
如果CPU支持Intel MPX技术,则会有几个额外的寄存器,而低版本的gdb无法识别这些寄存器,因此提示warning。
可以通过以下命令确定CPU是否支持MPX:
$ grep mpx /proc/cpuinfo flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 arat avx512_vnni
更换高版本(10.0版本)的gdb后,warning消失,且通过gdb命令info all-registers
也确实可以查看到MPX相关的几个寄存器:
(gdb) info all-registers bndcfgu {raw = 0x0, config = {base = 0x0, reserved = 0x0, preserved = 0x0, enabled = 0x0}} {raw = 0x0, config = {base = 0, reserved = 0, preserved = 0, enabl--Type <RET> for more, q to quit, c to continue without paging-- ed = 0}} bndstatus {raw = 0x0, status = {bde = 0x0, error = 0x0}} {raw = 0x0, status = {bde = 0, error = 0}} bnd0 {lbound = 0x0, ubound = 0xffffffffffffffff} : size -1 {lbound = 0x0, ubound = 0xffffffffffffffff} : size -1 bnd1 {lbound = 0x0, ubound = 0xffffffffffffffff} : size -1 {lbound = 0x0, ubound = 0xffffffffffffffff} : size -1 bnd2 {lbound = 0x0, ubound = 0xffffffffffffffff} : size -1 {lbound = 0x0, ubound = 0xffffffffffffffff} : size -1 bnd3 {lbound = 0x0, ubound = 0xffffffffffffffff} : size -1 {lbound = 0x0, ubound = 0xffffffffffffffff} : size -1
std::string str = NULL; 为什么会导致coredump
在C++中,std::string
是一个类,用于表示字符串。当您试图将NULL
分配给std::string
对象时,会引发未定义行为,因为std::string
不应该接受NULL
作为其值。在这种情况下,未定义行为可能导致coredump,因为您试图将一个空指针赋值给std::string
对象。
如果您想要创建一个空的std::string
,您可以简单地使用如下方法:
std::string str; // 创建一个空的 std::string
或者,如果您想要创建一个包含特定内容的std::string
,您可以这样做:
std::string str("some content");
总之,避免将NULL
分配给std::string
对象,以避免未定义行为和潜在的coredump。
为什么编译可以通过
我之前的回答可能有误,导致您的困惑。实际上,将NULL
分配给std::string
在某些编译器和情况下可能会通过编译。原因是NULL
在C++中通常定义为整数零,而不是一个真正的空指针。因此,将NULL
分配给std::string
时,编译器可能会尝试将整数零转换为std::string
。
然而,即使编译通过,这种用法仍然是不正确的,并可能导致运行时错误,如coredump。这是因为std::string
并不期望接收整数值作为其构造函数的参数,尤其是一个零值。
为了避免这种问题,您应该遵循正确的初始化方法,如我之前所示。在C++11及更高版本中,您还可以使用nullptr
来表示真正的空指针,而不是使用NULL
。这将有助于避免类型混淆和相关的问题。
总之,虽然在某些情况下,将NULL
分配给std::string
可能会通过编译,但这仍然是错误的用法,可能导致运行时错误。您应该遵循正确的std::string
初始化方法,以避免此类问题。
本文首先简单介绍TCMalloc及其使用方法,然后解释TCMalloc替代系统的内存分配函数的原理,再从宏观上讨论其内存分配的策略,在此之后再深入讨论实现细节。
有几点需要说明:
IncServer最核心的部分,自然是网络库了。
本文旨在分析IncServer网络库(以下称IncNet)的实现,进以总结一个网络库应当具备的基本功能以及常见做法,为以后手撸一个全新的网络库打下基础。
IncNet的实现依赖:
阅读此文请先对以上知识有所了解。
(更多…)在此推荐一本书,《The Linux Programming Interface——A Linux and UNIX System Programming Handbook》,简称TLPI,中文译名《Linux系统编程手册》,分上下两册,作者是目前Linux manpage的维护者Michael Kerrisk。
强烈建议阅读英文版,并结合官方勘误表。中译本上册翻译尚可,下册机翻痕迹明显,有多处意思完全相反。至少要中英结合看,感觉译文不对可以看下原文是怎么写的,还感觉不对就去看勘误表。