一、Top+pstack+gdb的组合拳

闲言少述,先直接上操作实例,再做原理讲解。

1.1 用top命令找到最占CPU的进程

>top

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND

22688 root      20   0 1842m 136m  13m S 110.0  0.9   1568:44 test-program

1.2 使用pstack跟踪进程栈

此命令可显示每个进程的栈跟踪。

pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack 来确定进程挂起的位置。

此命令允许使用的唯一选项是要检查的进程的 PID。

这个命令在排查进程问题时非常有用,

比如我们发现一个服务一直处于work状态(如假死状态,好似死循环),

使用这个命令就能轻松定位问题所在;

可以在一段时间内,多执行几次pstack,若发现代码栈总是停在同一个位置,

那个位置就需要重点关注,很可能就是出问题的地方;

>pstack 22688

Thread 44 (Thread 0x7fa97035f700 (LWP 22689)):

#0  0x00007fa96f386a00 in sem_wait () from /lib64/libpthread.so.0

#1  0x0000000000dfef12 in uv_sem_wait ()

#2  0x0000000000d67832 in node::DebugSignalThreadMain(void*) ()

#3  0x00007fa96f380aa1 in start_thread () from /lib64/libpthread.so.0

#4  0x00007fa96f0cdaad in clone () from /lib64/libc.so.6

Thread 43 (Thread 0x7fa96efe4700 (LWP 22690)):

#0  0x00007fa96f386a00 in sem_wait () from /lib64/libpthread.so.0

#1  0x0000000000e08a38 in v8::base::Semaphore::Wait() ()

#2  0x0000000000dddde9 in v8::platform::TaskQueue::GetNext() ()

#3  0x0000000000dddf3c in v8::platform::WorkerThread::Run() ()

#4  0x0000000000e099c0 in v8::base::ThreadEntry(void*) ()

#5  0x00007fa96f380aa1 in start_thread () from /lib64/libpthread.so.0

#6  0x00007fa96f0cdaad in clone () from /lib64/libc.so.6

Thread 42 (Thread 0x7fa96e5e3700 (LWP 22691)):

#0  0x00007fa96f386a00 in sem_wait () from /lib64/libpthread.so.0

#1  0x0000000000e08a38 in v8::base::Semaphore::Wait() ()

#2  0x0000000000dddde9 in v8::platform::TaskQueue::GetNext() ()

#3  0x0000000000dddf3c in v8::platform::WorkerThread::Run() ()

#4  0x0000000000e099c0 in v8::base::ThreadEntry(void*) ()

#5  0x00007fa96f380aa1 in start_thread () from /lib64/libpthread.so.0

#6  0x00007fa96f0cdaad in clone () from /lib64/libc.so.6

Thread 41 (Thread 0x7fa96dbe2700 (LWP 22692)):

#0  0x00007fa96f386a00 in sem_wait () from /lib64/libpthread.so.0

#1  0x0000000000e08a38 in v8::base::Semaphore::Wait() ()

#2  0x0000000000dddde9 in v8::platform::TaskQueue::GetNext() ()

#3  0x0000000000dddf3c in v8::platform::WorkerThread::Run() ()

#4  0x0000000000e099c0 in v8::base::ThreadEntry(void*) ()

#5  0x00007fa96f380aa1 in start_thread () from /lib64/libpthread.so.0

#6  0x00007fa96f0cdaad in clone () from /lib64/libc.so.6

使用top命令查看指定进程最耗CPU的线程,

下面找到的线程号为 22970.

>top -H -p 22688

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND

22970 root      20   0 1842m 136m  13m R  100.2 0.9 1423:40 test-program

NOTE:

这里的PID是系统给每个线程分配的唯一的线程号,不是进程号,但名称也是PID。

这两者的具体区别可见:

《linux中pid,tid, 以及 真实pid的关系》

http://blog.csdn.net/u012398613/article/details/52183708

使用线程号PID反查其对应的线程号。

如下就找到了 线程 22970对应的线程10

>pstack 22688 | grep 22970

Thread 10 (Thread 0x7fa92f5fe700 (LWP 22970)):

使用VIM查看进程快照,定位到具体的线程,并查看其调用堆栈;

>pstack 22688 | vim -

Thread 10 (Thread 0x7fa92f5fe700 (LWP 22970)):

#0  0x00007fa96f02a04f in vfprintf () from /lib64/libc.so.6

#1  0x00007fa96f054712 in vsnprintf () from /lib64/libc.so.6

#2  0x00007fa967b3861c in lv_write_log () from /opt/test-program

#3  0x00007fa967b26173 in LvJbuf::pjmedia_jbuf_put_rtp_pkg(pjmedia_rtp_decoded_pkg const*, int*) () from /opt/test-program

#4  0x00007fa96782409f in livesrv::LvAudio::on_rtp_stream(void*, unsigned int, unsigned int) () from /opt/test-program

#5  0x00007fa96781fc87 in livesrv::LvMedia::recv_media(void*, unsigned int, unsigned char, unsigned int) () from /opt/test-program

#6  0x00007fa967818c7f in livesrv::LvChannel::do_recv_media_check_thread2() () from /opt/test-program/node_modules/livesource/Debug/linux/livesource.node

#7  0x00007fa967814699 in recv_media_process2(void*) () from /opt/test-program

#8  0x00007fa96f380aa1 in start_thread () from /lib64/libpthread.so.0

#9  0x00007fa96f0cdaad in clone () from /lib64/libc.so.6

上面的操作基本定位到了具体线程和大概的函数,

如果想查看具体的原因,如现场的函数中变量等的数值等,就要使用的GDB的实时调试功能。

1.3 使用gdb调试实时进程

>gdb attach 22688

:thread 10

:bt

:frame x

:p xxx

二、top用法

2.1 top:动态观察程序的变化

[root@linux ~]# top [-d] | top [-bnp]

参数:

-d :后面可以接秒数,就是整个程序画面更新的秒数。预设是 5 秒;

-b :以批次的方式执行 top ,还有更多的参数可以使用喔!

通常会搭配数据流重导向来将批次的结果输出成为档案。

-n :与 -b 搭配,意义是,需要进行几次 top 的输出结果。

-p :指定某些个 PID 来进行观察监测而已。

在 top 执行过程当中可以使用的按键指令:

? :显示在 top 当中可以输入的按键指令;

P :以 CPU 的使用资源排序显示;

M :以 Memory 的使用资源排序显示;

N :以 PID 来排序喔!

T :由该 Process 使用的 CPU 时间累积 (TIME+) 排序。

k :给予某个 PID 一个讯号 (signal)

r :给予某个 PID 重新制订一个 nice 值。

2.2 top 也是个挺不错的程序观察工具!

不同于 ps 是静态的结果输出, top 这个程序可以持续的监测 (monitor) 整个系统的程序工作状态,

例如上面的范例一所示啊! 在预设的情况下,每次更新程序资源的时间为 5 秒,

不过,可以使用 -d 来进行修改。

top 主要分为两个画面,上面的画面为整个系统的资源使用状态,基本上总共有六行, 显示的内容依序是:

? 第一行:显示系统已启动的时间、目前上线人数、系统整体的负载(load)。

比较需要注意的是系统的负载,三个数据分别代表 1, 5, 10 分钟的平均负载。

一般来说,这个负载值应该不太可能超过 1 才对,除非您的系统很忙碌。

如果持续高于 5 的话,那么.....仔细的看看到底是那个程序在影响整体系统吧!

? 第二行:显示的是目前的观察程序数量,

比较需要注意的是最后的 zombie 那个数值,如果不是 0 ,

嘿嘿!好好看看到底是那个 process 变成疆尸了吧?!

? 第三行:显示的是 CPU 的整体负载,每个项目可使用 ? 查阅。

需要观察的是 id (idle) 的数值,一般来说,他应该要接近 100% 才好,表示系统很少资源被使用啊! ^_^。

? 第四行与第五行:表示目前的物理内存与虚拟内存 (Mem/Swap) 的使用情况。

? 第六行:这个是当在 top 程序当中输入指令时,显示状态的地方。 例如范例四就是一个简单的使用例子。

至于 top 底下的画面,则是每个 process 使用的资源情况。比较需要注意的是:

? PID   :每个 process 的 ID 啦!

? USER  :该 process 所属的使用者;

? PR    :Priority 的简写,程序的优先执行顺序,越小越早被执行;

? NI    :Nice 的简写,与 Priority 有关,也是越小越早被执行;

? %CPU  :CPU 的使用率;

? %MEM  :内存的使用率;

? TIME+ :CPU 使用时间的累加;

一般来说,如果鸟哥想要找出最损耗 CPU 资源的那个程序时,大多使用的就是 top 这支程序啦!

然后强制以 CPU 使用资源来排序 (在 top 当中按下 P 即可), 就可以很快的知道啦! ^_^。

三、pstack用法

此命令可显示每个进程的栈跟踪。

pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack 来确定进程挂起的位置。

此命令允许使用的唯一选项是要检查的进程的 PID。请参见 proc(1) 手册页。

这个命令在排查进程问题时非常有用,比如我们发现一个服务一直处于work状态(如假死状态,好似死循环),

使用这个命令就能轻松定位问题所在;

可以在一段时间内,多执行几次pstack,

若发现代码栈总是停在同一个位置,那个位置就需要重点关注,很可能就是出问题的地方;

示例:查看bash程序进程栈:

/opt/app/tdev1$ps -fe| grep bash

tdev1   7013  7012  0 19:42 pts/1    00:00:00 -bash

tdev1  11402 11401  0 20:31 pts/2    00:00:00 -bash

tdev1  11474 11402  0 20:32 pts/2    00:00:00 grep bash

/opt/app/tdev1$pstack 7013

#0  0x00000039958c5620 in __read_nocancel () from /lib64/libc.so.6

#1  0x000000000047dafe in rl_getc ()

#2  0x000000000047def6 in rl_read_key ()

#3  0x000000000046d0f5 in readline_internal_char ()

#4  0x000000000046d4e5 in readline ()

#5  0x00000000004213cf in ?? ()

#6  0x000000000041d685 in ?? ()

#7  0x000000000041e89e in ?? ()

#8  0x00000000004218dc in yyparse ()

#9  0x000000000041b507 in parse_command ()

#10 0x000000000041b5c6 in read_command ()

#11 0x000000000041b74e in reader_loop ()

#12 0x000000000041b2aa in main ()

四、GDB调试运行中程序的方法

4.1 多线程调试

多线程调试最重要就是下面几个命令:

1. 查看当前进程的线程。

info thread

2. 切换调试的线程为指定ID的线程。

thread 3. 在file.c文件第100行处为所有经过这里的线程设置断点。

break file.c:100 thread all

4. 线程开关

在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,

怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。

set scheduler-locking off|on|step,

. off    不锁定任何线程,也就是所有线程都执行,这是默认值。

. on     只有当前被调试程序会执行。

. step   在单步的时候,除了next过一个函数的情况

(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,

只有当前线程会执行。

4.2 调试宏

在GDB下,我们无法print宏定义,因为宏是预编译的。

但是我们还是有办法来调试宏,这个需要GCC的配合。

在GCC编译程序的时候,加上-ggdb3参数,这样,你就可以调试宏了。

另外,你可以使用下述的GDB的宏调试命令 来查看相关的宏。

info macro – 你可以查看这个宏在哪些文件里被引用了,以及宏定义是什么样的。

macro – 你可以查看宏展开的样子。

1、首先获得程序的PID

ps -ef | grep xxxxx

2、进入调试程序

gdb attach PID

3、gcore命令生成CORE文件

4、进程信息可以用info  proc显示

5、寄存器信息可以用info reg显示

阅读(10975) | 评论(0) | 转发(0) |

centos中bash占用cpu,linux下如何定位CPU占用高的进程的问题点相关推荐

  1. linux下如何获取cpu的利用率

    "proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为访问系统内核数据的操作提供接口.用户和应用程序可以通过proc得到系统的信息,并可以改变内核的某些 ...

  2. Linux下区分物理CPU、逻辑CPU和CPU核数

    Linux下区分物理CPU.逻辑CPU和CPU核数 ㈠ 概念 ① 物理CPU 实际Server中插槽上的CPU个数物理cpu数量,可以数不重复的 physical id 有几个 ② 逻辑CPU Lin ...

  3. Linux下查看物理CPU、逻辑CPU和CPU核数

    Linux下查看物理CPU.逻辑CPU和CPU核数 1.概念 物理CPU:实际Server中插槽上的CPU个数. 物理cpu数量:可以数不重复的 physical id 有几个. 2.逻辑CPU Li ...

  4. Linux下如何查看CPU信息, 包括位数和多核信息

    题记:今天看到一篇关于查看CPU和操作系统信息的文章,转过来和大家分享一下,O(∩_∩)O! 了解cpu架构   http://blog.csdn.net/wyzxg/archive/2009/12/ ...

  5. linux下apache端口被占用,【linux】下Apache无法启动(8080端口被占用)

    Linux下8080端口被占用,apache无法启动. 打开终端输入netstat -lnp|grep 8080 发现竟然是tcp6 占用里,因此ipv6启用占用了端口. 1.打开/etc/sysct ...

  6. Linux下快速查看CPU使用情况的相关命令

    Linux下快速查看CPU使用情况比较常用的命令是free.top.ps.这篇文章来看下如何在Linux下检查服务器的CPU使用情况.我的Linux是Linux-Ubuntu-server-15.04 ...

  7. linux怎么64位,在linux下如何查看CPU是否支持64位

    在linux下如何查看CPU是否支持64位的方法是: # grep "flags" /proc/cpuinfo flags           : fpu tsc msr pae ...

  8. python os模块安装方法_基于python中pygame模块的Linux下安装过程(详解)

    一.使用pip安装Python包 大多数较新的Python版本都自带pip,因此首先可检查系统是否已经安装了pip.在Python3中,pip有时被称为pip3. 1.在Linux和OS X系统中检查 ...

  9. linux 查看核数与线程数,Linux下查看系统CPU个数、核心数、线程数

    Linux下查看系统CPU个数.核心数.线程数 查看系统CPU个数(物理个数)cat /proc/cpuinfo |grep "physical id"|sort -u 结果如下: ...

最新文章

  1. 杭电多校第六场-J-Ridiculous Netizens
  2. 南邮计算机图形学水不水,南邮计算机图形学实验报告(修正版)….doc
  3. 如何通过一个编程获得IP地址归属地的最简单办法
  4. java se 导原码_Java SE 8新功能导览:Java开发世界中的重大变化
  5. 【渝粤教育】21秋期末考试工程项目管理10324k2
  6. Sql2005 PIVOT运算符的操作
  7. trie树和后缀树的应用
  8. 华为在剑桥建芯片厂;小米公布出货量反驳调研机构; 中移动否认限制号 | 极客头条...
  9. 腾讯 监控系统服务器数据采集,日均采集1200亿数据点,腾讯千亿级服务器监控数据存储实践...
  10. ssh关闭终端切断SSH连接
  11. window10激活
  12. python 读取.sgy地震文件到三维ndarray矩阵,(全网仅此一份)
  13. 10015---技术栈
  14. hive presto sql从身份证号提取年龄和性别
  15. Flurry使用初级教程
  16. 对现有计算机应用的建议,对计算机课程的建议
  17. 基于springboot的校园食堂订餐系统
  18. 怎么网络同步计算机的本地时间,VBA实现本地计算机时间与网服务器时间的同步...
  19. 计算机毕业设计JavaWeb美食网站设计(源码+系统+mysql数据库+lw文档)
  20. 【每日一题】涂色PAINT

热门文章

  1. 12月碎碎念-随便聊聊这一年
  2. 批量删除满足指定条件的 SAP CRM One Order 订单
  3. 一个典型的使用 SAP Cloud Application Programming 模型开发的 Fiori 应用
  4. Angular 项目里的 tsconfig.json
  5. 如何使用 controllerExtensions 给 SAP Fiori Elements List Report 的表格注册事件响应函数
  6. SAP Commerce Cloud CMS page 和 page template 的概念
  7. 使用Angular可重用Component思路实现一个自带图标(icon)的input控件
  8. 如何给UI上可以接收focus事件的element动态注册onfocus处理函数
  9. 如何处理使用ngrx时遇到的错误消息: NullInjectorError R3InjectorError(AppModule)[StoreFeatureModule]
  10. 在SAP WebClient UI里显示倒数计时的UI