linux死循环动态分配内存,Linux多线程死循环、死锁时调试方法

pstack命令可显示每个进程的栈跟踪,pstack $pid即可,pstack命令须由$pid进程的属主或者root运行。

有时候进程会cpu一直100%,或者内存满了,都可以用这个方法来排查。

要么是死循环,要么是for的判断条件出错了,变成了一个超级大的循环,然后循环里还有内存申请,循环出来才释放内存。

1、首先用   ps -aux | grep 查出进程号

2、然后    pstack   $pid

打印出进程下所有的线程栈信息。

b8c2a0ab421b3202eb67253d3207ff29.png

3. strace -o output.txt -T -tt -e trace=all -p 171264

进程中的171264线程进行系统调用跟踪, 将输出的信息保存在output.txt中

0d1f40561238dc183fa33850ae874421.jpg

4、pstree

pstree以树结构显示进程,不过没有线程号

pstree -c

5、strace  和 ltrace

早些年,如果你知道有个 strace 命令,就很牛了,而现在大家基本都知道 strace 了,如果你遇到性能问题求助别人,十有八九会建议你用 strace 挂上去看看,不过当你挂上去了,看着满屏翻滚的字符,却十有八九看不出个所以然。本文通过一个简单的案例,向你展示一下在用 strace 诊断问题时的一些套路。

如下真实案例,如有雷同,实属必然!让我们看一台高负载服务器的 top 结果:

0f0d0181ff38baa3b5909d415bdd1ef0.png

top

技巧:运行 top 时,按「1」打开 CPU 列表,按「shift+p」以 CPU 排序。

在本例中大家很容易发现 CPU 主要是被若干个 PHP 进程占用了,同时 PHP 进程占用的比较多的内存,不过系统内存尚有结余,SWAP 也不严重,这并不是问题主因。

不过在 CPU 列表中能看到 CPU 主要消耗在内核态「sy」,而不是用户态「us」,和我们的经验不符。Linux 操作系统有很多用来跟踪程序行为的工具,内核态的函数调用跟踪用「strace」,用户态的函数调用跟踪用「ltrace」,所以这里我们应该用「strace」:shell> strace -p

不过如果直接用 strace 跟踪某个进程的话,那么等待你的往往是满屏翻滚的字符,想从这里看出问题的症结并不是一件容易的事情,好在 strace  可以按操作汇总时间:shell> strace -cp

通过「c」选项用来汇总各个操作的总耗时,运行后的结果大概如下图所示:

1ff366e0bf827cdd02118ad4226803b9.jpg

strace -cp

很明显,我们能看到 CPU 主要被 clone 操作消耗了,还可以单独跟踪一下 clone:shell> strace -T -e clone -p

通过「T」选项可以获取操作实际消耗的时间,通过「e」选项可以跟踪某个操作:

50d72002c836aee021c42171f1ae5370.jpg

strace -T -e clone -p

很明显,一个 clone 操作需要几百毫秒,至于 clone 的含义,参考 man 文档:

简单来说,就是创建一个新进程。那么在 PHP 里什么时候会出现此类系统调用呢?查询业务代码看到了 exec 函数,通过如下命令验证它确实会导致 clone 系统调用:shell> strace -eclone php -r 'exec("ls");'

最后再考大家一个题:如果我们用 strace 跟踪一个进程,输出结果很少,是不是说明进程很空闲?其实试试 ltrace,可能会发现别有洞天。记住有内核态和用户态之分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值