一次Linux中定位c++程序运行异常的经历

系统 Linux
今天下午我遇到了一些棘手的问题,因为在mips64上编译程序,经常出现程序编译不出来,或者运行不正常,花了很长的时间定位,最后和同事一些解决了,下面分享出来我提炼出来的一些核心定位问题的步骤。

今天下午我遇到了一些棘手的问题,因为在mips64上编译程序,经常出现程序编译不出来,或者运行不正常,花了很长的时间定位,最后和同事一些解决了,下面分享出来我提炼出来的一些核心定位问题的步骤。

子线程创建不出来

猜测:go的程序都能创建出子线程,但是c++的创建不出来,但是在 x86 可以,是不是什么 linux 系统限制?

正常表现

异常表现

解决方法:加错误日志进行调试(最 lower 办法)

找到报错点:

错误日志内容

查询 man 手册,看看是不是能找到有帮助的东西:

  1. man pthread_attr_setstacksize 

打印出解释:

  1. ERRORS 
  2.        pthread_attr_setstacksize() can fail with the following error: 
  3.  
  4.        EINVAL The stack size is less than PTHREAD_STACK_MIN (16384) bytes. 
  5.  
  6.        On some systems, pthread_attr_setstacksize() can fail with the error EINVAL if stacksize is not a multiple of the system page size. 

翻译上面的话,可能会产生这个错误:

  • EINVAL 堆栈大小小于 PTHREAD_STACK_MIN(16384) 字节。
  • 在某些系统上,如果 stacksize 不是系统页面大小的倍数, pthread_attr_setstacksize() 可能会失败,并显示错误 EINVAL

查询 linux 报错码含义, 得知错误码 22 果然和 man 手册中说的一致,是参数有问题。

错误码对照

第一次尝试:扩大线程栈到上面说的 16384 ,但还是报错

错误日志内容

根据经验,查看最小页大小,发现是 16k , 而 x86 架构是 4K ,原来用的 20K 是不对齐的,怪不得创建不出来线程。

查看系统页大小

依次尝试, 最终发现 10*16K 子线程成功创建。

但是不准确,按其说法,应该是设置 PAGESIZE 的整数倍都行,怀疑其对最小值有要求。c++ 的头文件在 /usr/include 目录下面, PTHREAD_STACK_MIN 是一个常量,估计里面会有定义,尝试查找

  1. $ grep -rl PTHREAD_STACK_MIN * 
  2. bits/local_lim.h 
  3. pthread.h 

还真让我找到了, 根据英文注释,至少要两个 64K 作为线程栈,才能跑起一个线程。

系统c++头文件中的提示信息

至此问题解决。

部分线程卡住

我发现程序虽然正常运行,但是部分功能不正常,经过查看日志发现,有一个线程只执行了一半就卡住了。

经过查看日志可以定位出是哪个线程卡住,如果从日志看不出来也没关系。可以使用 pstack 进程号 看一些进程堆栈。

查看进程 pid:

  1. ps -ef |grep 进程名 

使用 gdb 查看是否出现问题,两个重要命令:

  1. gdb attach {pid} #查看正在运行程序的栈 
  2. info thread #进入以后使用,查看线程信息 

找到错误位置,出现了 fgets() 和 read() 函数,怀疑是此处出现问题。

gdb attach命令结果

错误代码位置

怀疑 1:_LINE_LENGTH 1024 长度太短,接受命令返回值后超过了数组本身的长度,覆盖了未知的内存。

这种情况我以前遇到过,表现应该是程序直接就崩溃了。

怀疑 2:执行命令的时候卡了,导致后面的程序没有执行。

根据 gdb 打印出来的参数,执行 linux 命令进行测试,果然是卡在这了!

再次使用 pstree -p {pid} 查看,确实主线程,调用了 linux 命令卡住。

查看此进程的线程树

接下来解决卡命令的问题。

解决 1:加 timeout 处理空返回。下面是示例命令,并不是我使用的命令。

  1. timeout 5 ls -al 

代表超过 5 秒返回。

解决 2:定位为什么这个 linux 命令会卡住。

  1. strace ls -al 

直到解决为止。这就是今晚我加班到 10 点 30 解决的问题,我又用了一个小时总结下整个过程备忘,希望对你也有帮助。

 

责任编辑:赵宁宁 来源: 编程三分钟
相关推荐

2012-08-28 09:21:59

Ajax查错经历Web

2011-08-19 15:05:29

异常处理

2023-03-29 09:36:32

2021-12-06 19:29:17

LRU内存算法

2013-04-01 10:27:37

程序员失业

2011-04-13 09:21:30

死锁SQL Server

2016-12-06 09:34:33

线程框架经历

2013-01-17 10:31:13

JavaScriptWeb开发firebug

2021-04-13 18:17:48

Hbase集群配置

2020-11-02 09:48:35

C++泄漏代码

2021-01-22 05:35:19

Lvm模块Multipath

2011-06-16 08:58:57

软考程序员

2012-07-12 14:35:31

面试经历

2022-06-10 11:06:23

服务下线

2015-04-28 15:31:09

2018-09-14 10:48:45

Java内存泄漏

2014-07-17 13:14:11

Linux服务器网卡

2017-11-09 09:06:29

流量暴增优化

2020-11-23 07:13:13

Nodejs源码

2011-01-14 13:01:33

Linux PPCEclipseC
点赞
收藏

51CTO技术栈公众号