inux跟踪线程的方法:LWP和strace命令
摘要:在使用多线程程序时,有时会遇到程序功能异常的情况,而这种异常情况并不是每次都发生,很难模拟出来。这时就需要运用在程序运行时跟踪线程的手段,而linux系统的LWP和strace命令正是这种技术手段。本文对LWP和strace命令做了简明扼要的介绍,并通过一个实例来说明如何运用。总而言之,LWP和strace的使用可以提高多线程程序的可维护性。
问题描述:
我们来看一个问题:程序tcp_client同时创建多个线程向同一个服务器发送数据,每个线程发送不同类型的数据,服务器接收数据后,可以通过界面查看到多个数据在刷新。程序运行一段时间后,突然出现只有某个类型的数据不刷新,其他数据刷新正常,但是服务端和客户端程序都没有报错。这时我们该怎么办?
很明显,这时程序调试者需要知道不刷新线程的线程ID,然后通过某种手段查看该线程为何出现了异常。通过linux的ps -eLF|grep pid命令可以查看进程的线程ID(LWP号),但是问题在于如果我们没有在创建线程时记录其线程ID,我们仍然无法得知哪个LWP号是我们想要追踪的。
我们来看一下LWP号是什么,以及如何在创建线程时记录每个线程的LWP号。
pthread_create是基于clone实现的, 创建出来的其实是进程, 但这些进程与父进程共享很多东西,
共享的东西都不用复制给子进程, 从而节省很多开销, 因此,这些子进程也叫轻量级进程(light-weight process)简称LWP. 每个LWP都会与一个内核线程绑定, 这样它就可以作为独立的调度实体参与cpu竞争.
LWP被pthread封装后, 以线程面目示人, 它有自己的id, 这里要区分 phtread_create
给LWP分配的id, 和操作系统给LWP分配的进程id. 这两者是不同的, 前者用于标志线程,可以暴露给
用户, 后者其实就是进程的id, 它没有暴露出来, 必须通过系统调用来得到.
获取LWP的方法是通过syscall系统调用(具体说明参加man手册),下面是一个例子程序:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#include <stdio.h>#include <unistd.h>#include <sys/syscall.h>#include <pthread.h>//线程处理函数,输出LWP号void *func(void *argv){ //获取LWP的方法1 int lwp; lwp = syscall(__NR_gettid); printf("lwp[%d]\n", lwp); //获取LWP的方法2 int lwp2; lwp2 = syscall(SYS_gettid); printf("lwp2[%d]\n", lwp2); sleep(50);}int main(void){ pthread_t thd; pthread_create(&thd, NULL, func, NULL); //创建线程 sleep(60); return 0;} |
在获取LWP号以后,接下来就是通过strace命令对线程进行追踪了。
strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通 过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。
在理想世界里,每当一个程序不能正常执行一个功能时,它就会给出一个有用的错误提示,告诉你在足够的改正错误的线索。但遗憾的是,我们不是生活在理想世界 里,起码不总是生活在理想世界里。有时候一个程序出现了问题,你无法找到原因。这就是调试程序出现的原因。strace是一个必不可少的 调试工具,strace用来监视系统调用。你不仅可以调试一个新开始的程序,也可以调试一个已经在运行的程序(把strace绑定到一个已有的PID上 面)。
strace的参数有很多,常见的参数介绍如下:
-o filename 将strace的输出写入文件filename
-p pid 跟踪指定的进程pid.
-t 在输出中的每一行前加上时间信息.
-tt 在输出中的每一行前加上时间信息,微秒级.
-T 显示每一调用所耗的时间.
-f 跟踪由fork调用所产生的子进程.
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程 号.
举个例子:我们对tcp_client程序做一个小小的改动,在通过pthread_create创建线程后,每个线程里都通过syscall函数记录其LWP号,同时记录该LWP号对应的数据类型。如果程序再次出现文章开头时提到的异常状况,这时我们可以通过“strace -o tcp_client.txt -tt -p 欲追踪的LWP号”,这样就很快就能知道发生异常的线程在做哪些系统调用了。
总结:在设计程序的时候,一定要考虑将来的维护问题。对于多线程程序,其调试会更加困难,通过在创建线程中记录LWP号和对应的线程功能,可以为以后的调试提供很大帮助。
inux跟踪线程的方法:LWP和strace命令的更多相关文章
- linux跟踪线程的方法:LWP和strace命令
摘要:在使用多线程程序时,有时会遇到程序功能异常的情况,而这种异常情况并不是每次都发生,很难模拟出来.这时就需要运用在程序运行时跟踪线程的手段,而linux系统的LWP和strace命令正是这种技术手 ...
- strace命令跟踪进程
在实际系统维护过程中,常常需要知道一个进程在做哪些动作,比如想判断一个进程是否hang,我们可以使用strace命令,此命令式用来跟踪一个进程在调用哪些系统函数和信号 通过跟踪xinetd进程演示st ...
- java17 线程的方法
线程的方法: .isAlive():判断线程是否还活着,即线程是否还未中止. .getPriority():获得线程的优先级数值. .setPriority():设置线程的优先级. .setName( ...
- Qt新建线程的方法(四种办法,很详细,有截图)
看了不少Qt线程的东西,下面总结一下Qt新建一个线程的方法. 一.继承QThread 继承QThread,这应该是最常用的方法了.我们可以通过重写虚函数void QThread::run ()实现我们 ...
- Qt新建线程的方法(有QRunnable,QThreadPool,moveToThread和QtConcurrent的例子)
看了不少Qt线程的东西,下面总结一下Qt新建一个线程的方法. 一.继承QThread 继承QThread,这应该是最常用的方法了.我们可以通过重写虚函数void QThread::run ()实现我们 ...
- 远程线程注入方法CreateRemoteThread
最近在整理学习Windows注入方面的知识,这个远程注入前面早写过,现在看看人家博客的理解整理,整理, 需要源码的可以到我的github上下载. 链接是 https://github.com/Ars ...
- 使用 Linux 的 strace 命令跟踪/调试程序的常用选项
原文:http://linoxide.com/linux-command/linux-strace-command-examples/作者: Raghu 在调试的时候,strace能帮助你追踪到一个程 ...
- 使用strace命令跟踪系统调用
一.是什么strace? strace常用来跟踪进程执行时的系统调用和所接收的信号. 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由 ...
- Thread线程join方法自我理解
Thread线程join方法自我理解 thread.join():等待thread线程运行终止,指的是main-thread(main线程)必须等待thread线程运行结束,才能继续thread.jo ...
随机推荐
- ubuntu中pycharm配置opencv2环境
在ubuntu中安装pycharm.opencv2后.在pycharm环境中无法使用opencv,后来查资料显示OpenCV is not pip-installable. You’ll need t ...
- svn解决不能clean的方法
http://blog.csdn.net/victory08/article/details/42100325 svn执行clean up后出现提示:svn cleanup failed–previo ...
- 实验一 ASP.NET应用环境配置 总结
通过本次实验我学会了在Windows XP系统中安装IIS服务器,虽然我的电脑是Windows7系统,但是通过虚拟机软件,配置了一台Windows XP系统的虚拟机,在虚拟机内进行各项配置操作.这次实 ...
- Axiom3D:Ogre中Mesh网格分解成点线面。
这个需求可能比较古怪,一般Mesh我们组装好顶点,索引数据后,直接放入索引缓冲渲染就好了.但是如果有些特殊需要,如需要标注出Mesh的顶点,线,面这些信息,以及特殊显示这些信息. 最开始我想的是自己分 ...
- C++ 结构体和枚举
共同体 共同体(union) 是一种数据格式, 它能够存储不同的数据类型, 但只能同时存储其中的一种类型.也就是说, 结构可以同时存储int.long 和 double, 共同体只能存储int.lon ...
- 【HTML】div居中显示
方法1: .parent { width:800px; height:500px; border:2px solid #000; position:relative; } .child { width ...
- 记一次win10 installer安装MySQL 5.7的过程
最新发现:其实就是windows显示的DPI改为了200%导致的,改成100%就没问题了.囧 不想折腾参数配置什么的,直接使用installer安装的. 诡异的是,安装完成之后需要配置,但界面上看不到 ...
- MongoDB mongod.exe或mongo.exe双击一闪就关闭
场景: 在 D:\data\ 创建 db目录之后,运行 mongod -repair 原因: 磁盘满了,没有空间了. 解决方法: 把 MongoDB\data 下的 lock 文件删掉,清理下磁盘空间 ...
- MOD 10,11算法(GB/T 17710-1999 数据处理 校验码系统 ),使用javascript实现
原文链接:http://chunniu.info/p/74.html GB/T 17710-1999 数据处理 校验码系统 ,便于使用,使用javascript做了一个页面 [php] var NUM ...
- muscle 软件进行多序列比对
今天在使用muscle 软件进行多序列比对时,发现输出的结果全部为gap, 而且还没有明显的报错信息 找了很久之后,终于发现了问题 muscle 为了追求速度,对输入序列的个数和长度进行了限制 下面是 ...