linux跟踪线程的方法: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手册),下面是一个例子程序:
#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号和对应的线程功能,可以为以后的调试提供很大帮助。
参考文章:
1、关于Linux的进程和线程
http://kenby.iteye.com/blog/1014039
2、linux strace命令:
http://www.cnblogs.com/ggjucheng/archive/2012/01/08/2316692.html
本文出自 “篮彩大神” 博客,请务必保留此出处http://lancaidashen.blog.51cto.com/11086793/1734196
linux跟踪线程的方法:LWP和strace命令的更多相关文章
- inux跟踪线程的方法:LWP和strace命令
摘要:在使用多线程程序时,有时会遇到程序功能异常的情况,而这种异常情况并不是每次都发生,很难模拟出来.这时就需要运用在程序运行时跟踪线程的手段,而linux系统的LWP和strace命令正是这种技术手 ...
- 使用 Linux 的 strace 命令跟踪/调试程序的常用选项
原文:http://linoxide.com/linux-command/linux-strace-command-examples/作者: Raghu 在调试的时候,strace能帮助你追踪到一个程 ...
- Linux posix线程库总结
由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...
- Linux编程---线程
首先说一下线程的概念.事实上就是运行在进程的上下文环境中的一个运行流.普通进程仅仅有一条运行流,可是线程提供了多种运行的路径并行的局面. 同一时候,线程还分为核心级线程和用户级线程.主要差别在属于核内 ...
- Linux查看线程
我的程序在其内部创建并执行了多个线程,我怎样才能在该程序创建线程后监控其中单个线程?我想要看到带有它们名称的单个线程详细情况(如,CPU/内存使用率). 线程是现代操作系统上进行并行执行的一个流行的编 ...
- 嵌入式linux应用程序调试方法
嵌入式linux应用程序调试方法 四 内存工具 五 C/C++代码覆盖.性能profiling工具 四 内存工具 您肯定不想陷入类似在几千次调用之后发生分配溢出这样的情形. 许多小组花了许许多多时间来 ...
- Linux中线程使用详解
线程与进程为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些好处?什么的系统应该选用多线程?我们首先必须回答这些问题. 使用多线程的理由之一是和进程相比,它是一种非常"节俭&qu ...
- Linux内核线程之深入浅出【转】
转自:http://blog.csdn.net/yiyeguzhou100/article/details/53126626 [-] 线程和进程的差别 线程的分类 1 内核线程 2 轻 ...
- linux系统——线程
linux系统线程 1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个 ...
随机推荐
- 阅读笔记—JSP
JSP页面概述 JSP(JavaServer Page)是一种动态页面技术,它在java web应用中主要实现表现逻辑.JSP页面是在HTML页面中嵌入JSP元素的动态Web页面,一般来说JSP页面中 ...
- 洛谷 P1358 扑克牌
P1358 扑克牌 题目描述 组合数学是数学的重要组成部分,是一门研究离散对象的科学,它主要研究满足一定条件的组态(也称组合模型)的存在.计数以及构造等方面的问题.组合数学的主要内容有组合计数.组合设 ...
- 安卓使用WebView下载文件,安卓实现软件升级功能
由于调用系统默认浏览器下载更新,造成用户体验非常不好,所以决定在webview中直接下载系统更新.然后直接安装. 由于要下载,所以必须用webview,联网权限这里不说了,直接写在manifafest ...
- 78.pipe多管道云端,客户端通信
压力测试截图: 云端 定义管道缓存区大小,最多连接数量(线程个数),当前线程个数,管道名字 //缓冲区大小 #define SIZE 4096 //最多连接数量 #define MAX_CONNECT ...
- 基于Linux系统的Nagios网络管理模块的实现
基于Linux 系统的Nagios网络管理模块的实现 1.引言 随着计算机网络的普及,网络管理已成为信息时代中最重要的问题之一.在现有的技术条件下,人们希望有一个更加稳定可靠的网络环境.计算机网络管理 ...
- Android 用Socket实现PC和手机的文件传输
PC服务器端代码: /* * PC与<a href="http://lib.csdn.net/base/android" class='replace_word' title ...
- leaf cell
leaf cell是否可以理解为设计中与或非门等这些基本的单元?
- vector转数组
vector转数组 由于vector内部的数据是存放在连续的存储空间,vector转数组事实上只需要获取vector中第一个数据的地址和数据的长度即可.如果仅仅是传参,无需任何操作,直接传地址即可,如 ...
- 百度地图API 添加标签
1.手动创建数据,实际项目则是接受GPS信息 /建立坐标点: // lng:经度 lat:纬度 var points = [ {"lng":112.58,"lat&quo ...
- 【Codeforces Round #452 (Div. 2) D】Shovel Sale
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 让N乘2->a 然后看一下位数是多少. 假设有x位(x>=2) 则(0..(a%10-1) ) + (99..9)[x- ...