分类: C/C++

深究一次常见的CoreDump问题

碰到一个dangling pointer导致进程core的问题,此类问题很常见,从上图m_vRelativePosition.yz的异常值可以猜测,m_targetDomArea指向的内存被踩坏了,或是m_targetDomArea指向的对象已被销毁,其内存可能已被重新分配。

这里不去讨论m_targetDomArea野的原因(熟悉这块逻辑的同事已经在上图指出具体原因),只去研究导致core的直接原因是什么。

GDB调试时遇到的寄存器识别问题——Unexpected size of section `.reg-xstate’

近期用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

利用ChatGPT搞懂std::string=NULL引发的coredump

You

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。

You

为什么编译可以通过

我之前的回答可能有误,导致您的困惑。实际上,将NULL分配给std::string在某些编译器和情况下可能会通过编译。原因是NULL在C++中通常定义为整数零,而不是一个真正的空指针。因此,将NULL分配给std::string时,编译器可能会尝试将整数零转换为std::string

然而,即使编译通过,这种用法仍然是不正确的,并可能导致运行时错误,如coredump。这是因为std::string并不期望接收整数值作为其构造函数的参数,尤其是一个零值。

为了避免这种问题,您应该遵循正确的初始化方法,如我之前所示。在C++11及更高版本中,您还可以使用nullptr来表示真正的空指针,而不是使用NULL。这将有助于避免类型混淆和相关的问题。

总之,虽然在某些情况下,将NULL分配给std::string可能会通过编译,但这仍然是错误的用法,可能导致运行时错误。您应该遵循正确的std::string初始化方法,以避免此类问题。

TCMalloc解密

Sticky post

写在前面

本文首先简单介绍TCMalloc及其使用方法,然后解释TCMalloc替代系统的内存分配函数的原理,再从宏观上讨论其内存分配的策略,在此之后再深入讨论实现细节。

有几点需要说明:

  • 本文只讨论gperftools中TCMalloc部分的代码,对应版本gperftools-2.7
  • 本文是根据TCMalloc源码以及简短的官方介绍作出的个人理解,难免有纰漏之处,且难以覆盖TCMalloc的方方面面,不足之处还请各位看官留言指正。
  • 除非特别说明,以下讨论均以32位系统、TCMalloc默认page大小(8KB)为基础,不同架构或不同page大小,有些相关数值可能不一样,但基本原理是相似的。
  • 为了控制篇幅,我会尽量少贴大段代码,只给出关键代码的位置或函数名,各位看官可自行参阅TCMalloc相关代码。

拆解IncServer网络库

IncServer最核心的部分,自然是网络库了。

本文旨在分析IncServer网络库(以下称IncNet)的实现,进以总结一个网络库应当具备的基本功能以及常见做法,为以后手撸一个全新的网络库打下基础。

IncNet的实现依赖:

  • Sockets API
  • I/O Multiplexing(select/poll)
  • epoll API
  • POSIX Threads API(Pthreads)
  • Reactor模式

阅读此文请先对以上知识有所了解。

在此推荐一本书,《The Linux Programming Interface——A Linux and UNIX System Programming Handbook》,简称TLPI,中文译名《Linux系统编程手册》,分上下两册,作者是目前Linux manpage的维护者Michael Kerrisk。
强烈建议阅读英文版,并结合官方勘误表。中译本上册翻译尚可,下册机翻痕迹明显,有多处意思完全相反。至少要中英结合看,感觉译文不对可以看下原文是怎么写的,还感觉不对就去看勘误表。

Powered by WordPress & Theme by Anders Norén

粤ICP备2021073162号-1