当前位置: 首页 > 科技观察

一次在linux下定位运行异常的c++程序的心得

时间:2023-03-20 10:13:32 科技观察

今天下午遇到了一些棘手的问题,因为在mips64上编译程序时,程序经常编译失败或者运行异常,而且定位时间比较长。最后和同事一起解决了一些问题。下面分享一下我提取出来的一些核心定位问题的步骤。不能创建子线程猜测:Go程序可以创建子线程,C++程序不能创建子线程,但在x86中可以。是linux系统限制吗?NormalperformanceandabnormalperformanceSolution:adderrorlogsfordebugging(mostlower办法)找到报错点:错误日志内容查询man手册,看看是不是能找到有帮助的东西:manpthread_attr_setstacksize打印出解释:ERRORSpthread_attr_setstacksize()canfailwiththefollowingerror:EINVALThestacksizeislessthanPTHREAD_STACK_MIN(16384)bytes.Onsomesystems,pthread_attr_setstacksize()canfailwiththeerrorEINVALifstacksizeisnotamultipleofthesystempagesize.翻译上面,可能会产生这个错误:EINVALstacksizeislessthanPTHREAD_STACK_MIN(16384)bytes。在某些系统上,如果堆栈大小不是系统页面大小的倍数,pthread_attr_setstacksize()可能会失败并显示错误EINVAL。查询linux中错误码的含义,得到错误码22,和man手册上说的一致,是参数有问题。.错误码对比第一次尝试:将线程栈扩展到上面提到的16384,但还是报错日志内容根据经验,查看最小页面大小,发现是16k,而x86架构是4K,原来是20K没有对齐,难怪不能创建线程。查看系统页面大小依次尝试,最后发现10*16K个子线程创建成功。但它并不准确。按照它的说法,应该是PAGESIZE的整数倍。怀疑是对最小值有要求。c++的头文件在/usr/include目录下,PTHREAD_STACK_MIN是个常量,估计里面会有定义,试试找$grep-rlPTHREAD_STACK_MIN*bits/local_lim.hpthread.h真让我找到它,根据英文注释,至少要用两个64K作为线程栈来运行一个线程。系统c++头文件中的提示信息现已解决。一些线程被卡住了。我发现虽然程序运行正常,但是有些功能不正常。查看日志发现有一个线程执行到一半就卡住了。通过查看日志可以知道是哪个线程卡住了。从日志里看不出来也没关系。您可以使用pstack进程ID查看一些进程堆栈。查看进程pid:ps-ef|grep进程名使用gdb查看是否有问题,两个重要的命令:gdbattach{pid}#查看运行程序的堆栈infothread#进入后查看线程信息找到错误的位置,fgets出现()和read()函数,怀疑是这里有问题。gdbattach命令结果错误代码位置怀疑1:_LINE_LENGTH1024长度太短,接受命令后返回值超过数组本身的长度,覆盖未知内存。我以前遇到过这种情况,表现应该是程序直接崩溃了。疑点二:在执行命令的时候卡住了,导致后面的程序无法执行。根据gdb打印出来的参数,执行linux命令测试,果然卡在这里了!再次使用pstree-p{pid}查看,确实是主线程,调用linux命令就卡住了。检查此进程的线程树,以便接下来对卡住的命令进行故障排除。方案一:添加超时处理空返回。以下是示例命令,不是我使用的命令。timeout5ls-al表示超过5秒后返回。解决方案2:找到此linux命令会卡住的原因。stracels-al直到解决。这是我今晚加班到10:30的问题,又花了一个小时总结了整个过程的备忘录,希望对你也有帮助。