存档

Linux Coredump 核心转储

2019/10/14 8

什么是 Coredump

coredump 核心转储 ,也称为 核心文件(core file) 是操作系统在进程收到某些 信号 而终止运行时,将此进程的地址空间以内容以及有关进程状态的其他信息写出的一个文件。这种信息往往用于调试。
程序员可以通过工具来分析程序运行过程中哪里出错了:Windows 平台用 userdump 和 WinDBG ,Linux 平台使用gdb, elfdump, objdump 等

Windows WinDBG

关于 windbg, 可以参考以下资料

Linux GDB

有些时候进程在crash的时候会产生 core 文件, 但我们却找不到 core 文件,我们需要使用 ulimit 进行一些设置, 这个命令是用来限制系统用户对shell资源的访问的。
ulimit -a 可以查看当前的设置
ulimit -c 可以设置 core 文件的上限,单位为区块(一般 1 block = 512 bytes) .其值为 0 时不写入 core, 为 unlimited 时不限制 core 文件大小。
需要注意, ulimit 只对当前会话有效。若想对所有会话生效, 需要在 /etc/profile 中进行配置。

源文件如下 test_vec.cpp :

编译运行时可能出现如下现象:

使用 gdb 打开来看:

从 gdb显示的栈信息来看,崩溃发生在 main 函数内的 vector::at 函数内,由 _M_range_check raise 。
如果我们在编译时使用了 -g 选项, 会得到更详细的信息

阅读全文…

GDB 常用调试技巧

2019/10/12 19

1. 调试宏

宏是预编译的,无法 print 宏的定义。但是如果配合 gcc, 我们还是可以有限地调试宏。
在 GCC 编译程序的时候,加上 -g3 参数,就可以调试宏了。

  • info macro mac_name 可查看宏定义,及位置
  • macro expand mac_expr 可查看宏展开的样子

示例:

调试现场如下:

2. 修改变量

两种方法:

  1. print var_name=x
  2. set var var_name=x

示例:

阅读全文…

GDB 常用命令一览

2019/10/11 16

命令

GDB 是 Linux 下的命令行调试工具。
启动 GDB 有如下几种方式:

  1. gdb <program> 直接启动执行程序
  2. gdb <program> core 用gdb 同时调试一个可执行程序和core文件。core 是程序非法执行后 core dump 产生的文件
  3. gdb <program> <PID> 指定进程, gdb会自动 attach 上去。program 应该在 PATH 环境变量中可以搜索得到。

常用的 gdb 命令如下

信息 info

info 可以简写成 i

  • info args 列出参数
  • info breakpoints info break i b 列出所有断点
  • info break number i b number 列出序号为 number 的的断点
  • info watchpoints i watchpoints 列出所在 watchpoints
  • info threads 列出所有线程
  • inifo registers 列出寄存器的值
  • info set 列出当前 gdb的所的设置
  • i frame
  • i stack
  • i locals
  • i catch

断点和监视 break & watch

阅读全文…

关于 enable_shared_from_this

2019/05/16 399

一. 引入

简单地说: enable_shared_from_this 是为了解决 在类的内部获取自己的 shared_ptr 这件事情而存在的。

众所周知, 每一个对象都能通过this 指针来访问自己的地址。this 指针也是所有成员函数的隐含参数。然而有些时候,我们需要的不仅是 this,而是一个 “this的智能指针”。

这里有一个常见的场景:

代码如上:在异步方法 DoSth_Async() 中调用了成员方法 OnDo(bool) . 这里存在一个问题: 当 OnDo() 被调用的时候,该类的是否还在生存中:

智能指针 ptr 在出作用域后立即被释放。所以当 OnDo() 被调用的时候,其所在的对象实际已经被释放了。如果确保在 OnDo() 被调用的时候,该对象仍然在生命周期内呢?一个方便的方法便上在构建线程的时候,将该对象的 shared_ptr 传入到线程。在该线程的生命周期内,该对象就会一直存在。这是一种利用 shared_ptr 的 保活机制

阅读全文…

TCP 的状态(二) : TCP 常见错误码

2019/04/01 217

TCP 协议错综复杂, 很容易出现错误,错误码非常之多。这里探究一些在编程中比较常见的错误码。tcp 错误码 在不同的操作系统中的值不同。这里取用 Linux 与 Windows 两种,如 connection_refused 在windows  中的值为10054, 在 Linux 中为54 .

eof :

  • 2 : End of file

eof 标志着流的结束。当对端关闭连接(调用了 shutdownclose) 后,处于 CLOSE_WAIT 状态。 本端会收到 FIN, ACK 。此时如果本端再试图 read ,则会读到 eof

connection_refused

  • 61 : Connection refused
  • 10061 : No connection could be made because the target machine actively refused it . 由于目标计算机积极拒绝,无法连接

在客户端试图与服务端建立连接的时候发生。一般是服务端没有处于监听状态。 客户端发送发 SYN , 但是收到了 RST, ACK

connection_reset

  • 54 : Connection reset by peer
  • 10054 : An existing connection was forcibly closed by the remote host . 远程主机强迫关闭了一个现有的连接。

对端对处于连接状态的socket 进行了异常断开, 如进程中断等。此时如果本端进行读操作,可能会得到此错误。 阅读全文…

TCP 的状态(一): TCP有限状态机 (FSM)

2019/03/14 555

最近一段时间在解决一个网络方面的 BUG,发现自己对 TCP 的状态了解得不够,于是复习了一遍 TCP 的各种状态与状态间的转换,并做了一个整理,以加深自己的理解。

网络上的两台设备想要一起工作,就必须使用相同的网络协议。像 TCP 这种复杂的协议,我们很难简洁地描述其各种确切的操作。所以我们试图使用有限状态机来解释这个复杂的协议。

一. 有限状态机

有限状态机 (FSM : Finite State Machine) 又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。FSM 的四个基本概念如下:

  1. 状态 state: 描述机器在特定时间上处于的 环境(circumstance)或状况(status)
  2. 转换 Transition: 从一种状态到另一种状态的行为(act)
  3. 事件 Event: 导致状态发生变化的事情
  4. 动作 Action: 机器从一种状态转换之前对事件所做的响应

FSM通过解释协议可以处于的所有不同状态、可以在每个状态中发生的事件、针对事件采取的操作以及结果发生的转换来描述协议。协议通常在第一次运行时以特定的开始状态启动。尔后,它遵循一系列步骤使其进入常规操作状态,并根据特定类型的输入或其他情况移动到其他状态。状态机之所以称为有限状态机,是因为只有有限数量的状态。

二. TCP 的操作与状态

对于 TCP 来说,可以使用 FSM 来描述一个连接的生命周期 : 一个 TCP 设备和另一个 TCP 设备之间的每个连接,都从一个空状态(null state) 开始,经过一系列的状态变化,直到建立了(established)连接。然后它将保持这种状态,直到遇到某种事件,它将进行一系列状态直到回到关闭状态。
我们使用三个缩写词来表示状态间转换的三种类型消息,它们对应于 TCP 头的标志。(关于 TCP 头的内容可以参见我之前的博客 《TCP 协议概述》) :

阅读全文…