Linux程序调试和性能分析

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

链接

动态链接

在可执行文件加载或运行时,由操作系统的动态链接器 加载进程所需共享库,完成符号搜索和重定位
链接

动态链接



PIC:地址无关代码 GOT&PLT 延迟绑定
课后思考

进程加载运行时入口函数是main吗?

提示:ELF文件头包含可执行目标文件的入口地址
进程空间

可执行目标文件被加载运行后,进程空间是什 么样的?

符号表(symble table)


其它 (重定位、加载、动态链接、调试等信息)
工具- readelf

功能

查看ELF文件内容 readelf -h 查看ELF文件头 readelf -a 查看ELF所有信息 readelf -s 查看ELF文件中的符号表 readelf -x .data .rodata .bss .text 查看指定节区


用途

通常用法
– – –

举例
系统维度-lsof

功能

它可以列出某个进程打开的所有文件信息。

用途

查看进程打开的普通的文件,目录,nfs文件,块文件,字符文件,共享库, 管道,符号链接,socket流,网络socket,以及其它更多。
不带任何参数运行lsof会列出所有进程打开的所有文件 lsof /tmp/access_log 列出哪些进程使用某些文件 lsof -c httpd;lsof -p PID 查找某个程序打开的所有文件 lsof -i :port 使用某个端口的进程 lsof -d mem 列出所有内存映射文件 lsof -d txt 列出所有加载在内存中并正在执行的进程

/proc/*/stat



sar –x 12345 1 100 程序自己调用times()
进程维度-strace

功能

显示程序调用的系统调用


用途

分清系统调用和c库函数
重要参数


Debug、性能分析、学习现有程序

举例
-c计算各个系统调用累计占用的时间 -T –tt显示单个系统调用的开始时间、执行时间
– – – –
显示各个函数的执行时间

性能分析
gcc -pg -g 不能strip 必须通过正常途径退出(exit()、main返回),不能kill -9 有时不太准 只管了用户态时间消耗,没有管内核态消耗 可对c库函数进行性能分析,libc_p.a (gcc –lc_p)

– –

( 举例 )gprof -b a.out gmon.out

用途
– –

重要显示列


举例
– –
系统维度-top

功能

显示系统各个进程整体负载情况 性能分析


用途

举例
系统维度-free

功能

显示系统内存使用情况 性能分析 free -m free -g


用途

举例
– –
系统维度-sar
Fra Baidu bibliotek
功能

性能监控 性能分析 sar –d 1 100 sar n DEV 1 100 sar -u 1 100
进程空间

思考
– –
如下两种写法中,数组s是如何分配的? 代码有什么问题? for (i=0; i<N; i++) { static char s[1024] = {0}; …… if (x) return s; }
for (i=0; i<N; i++) { char s[1024] = {0}; …… if (x) return s; }


用途

举例
– –
链接

静态链接

由链接器将一个或多个库或目标文件链接并 拷贝到一块生成可执行目标文件。
链接

静态链接
– –


符号解析:将符号的定义和引用联系起来 重定位:修改引用符号的地址,使其指向符 号定义的位置 优点: – 可直接在对应的操作系统运行 – 运行速度快 缺点: – 更新及维护困难 – 空间浪费

理解c代码对应的内存分配(示例: maps_demo)
进程空间

Linux系统中,进程逻辑地址空间介绍
– – – –

– – –
代码段(TEXT)(代码) 已初始化数据段(DATA)(已初始化的全局变量、函数静 态变量) 未初始化数据段(BSS)(未初始化的全局变量、函数静态 变量) 堆(malloc()、brk()等) 共享库 共享内存(shmat()等) 栈 内核保留空间
举例

– – – –
进程维度-time

功能

显示程序执行时间、其中用户态时间、其中内核态 时间 性能分析 time只跟踪父进程,所以不能fork

用途

注意

举例
fork情况下如何分析time

功能

Fork情况下,time命令不起作用,使用下面的方 法可获取utime & stime cat /proc/12345/stat | awk ‘{print $14,$15}’ man 5 proc 查看/proc/[number]/stat

举例
– – – – – –
总结回顾

如何诊断一个没有响应的进程在做什么? 如何查看一个进程用了多少内存?怎么用的? 如何判断一个遇到性能瓶颈的机器是出在cpu, disk,网卡?
学习方法

man


man 5 proc man strace 等 info gcc info gprof

info
– –



KM 《深入理解计算机系统》 《深入理解Linux内核》 测试程序

源代码 -> 目标文件
– – – –

gcc –E gcc –S as -o ld .o
.c ->.i 预编译 .i ->.s 编译 .s -> .o 汇编 .o* -> exe 链接
gcc –v 显示详细编译链接过程
基础知识

目标文件包含什么信息?
ELF文件

可执行链接格式
Linux最普遍的目标文件格式 作为一种可移植的目标文件格式,可以在Intel体系 结构上的很多操作系统中使用,从而减少重新编码 和重新编译程序的需要
跟踪链接错误(尤其是C++、C混编的程序) -C,把C++函数签名转为可读形式 (认识c++ name mangling) 不同版本的g++,对于同样C++函数的函数签名可能是不同的,所 以C++库难以跨gcc版本编译使用 如果发现类似问题,先用nm –C看看有无该函数,如果有,再用 nm看看函数签名是否一样


ELF文件
ELF文件

目标文件包含什么信息?
– –
代码(.text) 数据

.data 初始化了的全局静态变量和局部静态变量 .bss 未初始化的全局变量和局部静态变量 .rodata 只读数据(字符串常量) 包括:函数名、全局变量名、函数静态变量名 不包括:数据类型名、局部自动变量名
进程维度-gdb

功能

debug程序运行 debug gcc –g bt attach/detach

用途
– –


进程维度-ldd

功能

显示程序需要使用的动态库和实际使用的动态库
用途

– –
解决运行库不匹配的问题
$ ldd /bin/ls librt.so.1 => /lib/librt.so.1 (0x4001a000) libc.so.6 => /lib/libc.so.6 (0x4002c000) libpthread.so.0 => /lib/libpthread.so.0 (0x4014f000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) 第一栏:需要用什么库;第二栏:实际用哪个库文件;第三栏:库 文件装载地址 如果缺少动态库,就会没有第二栏。

特别注意
工具- strip

功能

去除二进制文件里面包含的符号 反编译、反跟踪(基本手段,作用不大) 减小目标文件大小 去除调试信息 不要随意的对库文件strip,否则… strip_demo

用途
– –



举例

工具- strings

功能

获取二进制文件里面的字符串常量 很多,比较重要的是检查KEY泄露 strings –f * | grep ‘^.\{16\}$’ strings_demo

用途
– –


工具- objdump

功能

显示来自目标 文件 的信息 objdump –d 反汇编目标文件 objdump –s 查看ELF文件节区内容

用途
– –
工具-nm

功能

获取二进制文件里面包含的符号


用途 (示例) 重要参数
– – – –
二进制文件:可执行文件、目标文件、库文件 符号:函数、变量
进程维度-ltrace

功能

显示程序调用的动态库函数

分清系统调用和c库函数

用途

Debug、性能分析、学习现有程序 -c计算各个函数累计占用的时间 -T –tt显示单个函数的开始时间、执行时间
重要参数
– –

注意:Slackware8上面没有装(Suse有)
进程维度-pmap

功能
– – –


用途

通常用法

举例
系统维度-iostat

功能

对系统的磁盘操作活动进行监视 性能分析 Iostat –x


用途

通常用法

举例
系统维度-netstat

功能
– –

显示udp/tcp socket状态 接收、发送队列的大小 udp接收丢包 高危端口 性能分析 Recv-Q:Socket接收缓存,满了(比如CPU太忙)就会丢包 netstat -lpn watch netstat -su
(Executable Linkable Format)
– –
ELF文件


ELF文件类型
可重定位文件(Relocatable File) 包含适合于与其他目标文件链接来创建可执行文件或者共享目标文 件的代码和数据。 可执行文件(Executable File) 包含适合于执行的一个程序,此文件规定了 exec() 如何创建一个 程序的进程映像。 共享目标文件(Shared Object File) 包含可在两种上下文中链接的代码和数据。首先链接编辑器可以将 它和其它可重定位文件和共享目标文件一起处理,生成另外一个目 标文件。其次,动态链接器(Dynamic Linker)可能将它与某个 可执行文件以及其它共享目标一起组合,创建进程映像。
常用调试工具

进程维度
– – – – – – –
gdb ldd time strace ltrace pmamp gprof vmstat、iostat、 netstat top、free sar、lsof

系统维度
– – –
使用工具的好处

不用改程序,方便,节省时间 可以直接检查正在跑的进程,无需重启 基本不影响正常业务 有时是无法替代的


拥有独立的虚拟地址空间 与可执行目标文件存在映射关系
进程空间

通过maps查看进程内存逻缉空间布局

进程逻缉地址空间 (虚拟地址空间) (示例)


区间:库在进程里地址范围 权限:r=读,w=写,x=执行,s=共享,p=私有; 偏移量:库在进程里地址范围 设备:映像文件的主设备号和次设备号 节点:映像文件的节点号 路径: 映像文件的路径


用途
举例

显示进程内存使用情况 性能分析 pmap -d 5167
SIZE:该进程占用的地址空间。 RSS:实际被分配的内存的大小。 shared :表示这些被分配的内存是被系统中其他进程共享 的。 private :表示只能被该进程使用的空间大小。
进程维度-gprof

功能 用途 注意
进程性能优化的一般步骤

确定运行时间主要花在用户态还是内核态 如果是用户态,则使用gprof进行性能分析 如果是内核态,则使用strace进行性能分析 另外可以使用其他工具(比如ltrace等)辅助
系统维度-vmstat

功能

显示系统整体负载情况 性能分析 vmstat 1 每秒刷新一次结果
Linux程序调试和性能分析
即通平台——Tommyli
课程知识范围

主要内容
– –
从编译到进程等基础知识 常用调试与性能分析工具
基础知识

程序 vs 进程
– –
程序是指令和数据的集合文件 进程是由操作系统将程序加载到内存并运行的实例

目标文件是程序的二进制表示,可以直接在某
种处理器上执行
基础知识
相关文档
最新文档