共计 5044 个字符,预计需要花费 13 分钟才能阅读完成。
今天小编要跟大家分享的文章是关于 Linux 运维 常用的命令介绍 - 开发调试命令介绍。Linux 常用命令中有一些命令可以在开发或调试过程中起到很好的帮助作用,有些可以帮助了解或优化我们的程序,有些可以帮我们定位疑难问题。本文将简单介绍一下这些命令。Linux 入门 新手和正在 Linux 学习 的小伙伴快来看一看吧,希望能够对大家有所帮助!
一、示例程序
我们用一个小程序,来帮助后面我们对这些命令的描述,程序清单 cmdTest.c 如下:
#include<stdio.h>
int test(int a,int b)
{
return a/b;
}
int main(int argc,char *argv[])
{
int a = 10;
int b = 0;
printf(“a=%d,b=%dn”,a,b);
test(a,b);
return 0;
}
编译获得 elf 文件 cmdTest 并运行:
gcc -g -o cmdTest cmdTest.c
./cmdTest
a=10,b=0
Floating point exception (core dumped)
程序内容是在 main 函数中调用 test,计算 a / b 的值,其中 b 的值为 0,因此程序由于除 0 错误异常终止。
二、查看文件基本信息 –file
file cmdTest
cmdTest: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=448e1c34b4c548120e2c04f6a2bfce4e6d2281a3, not stripped
通过 file 命令可以看到 cmdTest 的类型为 elf,是 64 位、运行于 x86-64 的程序,not striped 表明 elf 文件中还保留着符号信息以及调试信息等不影响程序运行的内容。
三、查看程序依赖库 –ldd
ldd cmdTest
Linux-vdso.so.1 => (0x00007ffc8e548000)
libc.so.6 => /lib/x86_64-Linux-gnu/libc.so.6 (0x00007f0621931000)
/lib64/ld-Linux-x86-64.so.2 (0x00007f0621cf6000)
我们可以看到 cmdTest 依赖了 libc.so 等库。
四、查看函数或者全局变量是否存在于 elf 文件中 –nm
nm 命令用于查看 elf 文件的符号信息。文件编译出来之后,我们可能不知道新增加的函数或者全局变量是否已经成功编译进去。这时候,我们可以使用 nm 命令来查看。
例如,查看前面所提到的 elf 文件有没有 test 函数,可以用命令:
nm cmdTest|grep test
000000000040052d T test #打印结果
按照地址顺序列出符号信息:
nm -n cmdTest
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
w _Jv_RegisterClasses
w __gmon_start__
U __libc_start_main@@GLIBC_2.2.5
U printf@@GLIBC_2.2.5
00000000004003e0 T _init
0000000000400440 T _start
0000000000400470 t deregister_tm_clones
00000000004004a0 t register_tm_clones
00000000004004e0 t __do_global_dtors_aux
0000000000400500 t frame_dummy
000000000040052d T test
0000000000400540 T main
0000000000400590 T __libc_csu_init
0000000000400600 T __libc_csu_fini
(列出部分内容)
可以看到 test 函数的开始地址为 0x000000000040052d,结束地址为 0x0000000000400540。
五、打印 elf 文件中的可打印字符串 –strings
例如你在代码中存储了一个版本号信息,那么即使编译成 elf 文件后,仍然可以通过 strings 搜索其中的字符串甚至可以搜索某个.c 文件是否编译在其中:
strings elfFile| grep “someString”
六、查看文件段大小 –size
可以通过 size 命令查看各段大小:
size cmdTest
text data bss dec hex filename
1319 560 8 1887 75f cmdTest
text 段:正文段字节数大小
data 段: 包含静态变量和已经初始化的全局变量的数据段字节数大小
bss 段:存放程序中未初始化的全局变量的字节数大小
当我们知道各个段的大小之后,如果有减小程序大小的需求,就可以有针对性的对 elf 文件进行优化处理。
七、为 elf 文件”瘦身“–strip
strip 用于去掉 elf 文件中所有的符号信息:
ls -al cmdTest
-rwxr-xr-x 1 hyb root 9792 Sep 25 20:30 cmdTest #总大小为 9792 字节
strip cmdTest
ls -al cmdTest
-rwxr-xr-x 1 hyb root 6248 Sep 25 20:35 cmdTest#strip 之后大小为 6248 字节
可以看到,“瘦身”之后,大小减少将近三分之一。但是要特别注意的是,“瘦身”之后的 elf 文件由于没有了符号信息,许多调试命令将无法正常使用,出现 core dump 时,问题也较难定位,因此只建议在正式发布时对其进行“瘦身”。
八、查看 elf 文件信息 –readelf
readelf 用于查看 elf 文件信息,它可以查看各段信息,符号信息等,下面的例子是查看 elf 文件头信息:
readelf -h cmdTest
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 #elf 文件魔数字
Class: ELF64 #64 位 elf 文件
Data: 2’s complement, little endian# 字节序为小端序
Version: 1 (current)
OS/ABI: UNIX – System V #
ABI Version: 0
Type: EXEC (Executable file)# 目标文件类型
Machine: Advanced Micro Devices X86-64 #目标处理器体系
Version: 0x1
Entry point address: 0x400440 #入口地址
Start of program headers: 64 (bytes into file)
Start of section headers: 4456 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 28
Section header string table index: 27
从 elf 头信息中,我们可以知道该 elf 是 64 位可执行文件,运行在 x86-64 中,且字节序为小端序。另外,我们还注意到它的入口地址是 0x400440(_start),而不是 400540(main)。也就是说,我们的程序运行并非从 main 开始。
九、反汇编指定函数 –objdump
objdump 用于展示 elf 文件信息,功能较多,在此不逐一介绍。有时候我们需要反汇编来定位一些问题,可以使用命令:
objdump -d cmdTest #反汇编整个 cmdTest 程序
但是如果程序较大,那么反汇编时间将会变长,而且反汇编文件也会很大。如果我们已经知道了问题在某个函数,只想反汇编某一个函数,怎么处理呢?
我们可以利用前面介绍的 nm 命令获取到函数 test 的地址,然后使用下面的方式反汇编:
objdump -d cmdTest –start-address=0x40052d –stop-address=0x400540 ## 反汇编指定地址区间
十、端口占用情况查看 –netstat
我们可能常常会遇到进程第一次启动后,再次启动会出现端口绑定失败的问题,我们可以通过 netstat 命令查看端口占用情况:
netstat -anp|grep 端口号
十一、core dump 文件生成配置 –ulimit -c
有时候我们的程序 core dump 了却没有生成 core 文件,很可能是我们设置的问题:
ulimit -c #查看 core 文件配置,如果结果为 0,程序 core dump 时将不会生成 core 文件
ulimit -c unlimited #不限制 core 文件生成大小
ulimit -c 10 #设置最大生成大小为 10kb
十二、调试神器 –gdb
gdb 是一个强大的调试工具,但这里仅介绍两个简单使用示例。
有时候程序可能已经正在运行,但是又不能终止它,这时候仍然可以使用 gdb 调试正在运行的进程:
gdb processFile PID #processFile 为进程文件,pid 为进程 id,可通过 ps 命令查找到
有时候程序可能 core dump 了,但是系统还留给了我们一个礼物 –core 文件。
在 core 文件生成配置完成之后,运行 cmdTest 程序,产生 core 文件。我们可以用下面的方法通过 core 文件定位出错位置:
gdb cmdTest core #processFile 为进程文件,core 为生成的 core 文件
Core was generated by `./cmdTest’.
Program terminated with signal SIGFPE, Arithmetic exception.
#0 0x00000000004004fb in test (a=10, b=0) at cmdTest.c:4
4 return a/b;
(gdb)bt
#0 0x00000000004004fb in test (a=10, b=0) at cmdTest.c:4
#1 0x000000000040052c in main (argc=1, argv=0x7ffca9536d38) at cmdTest.c:10
(gdb)
输入 bt 后,就可以看到调用栈了, 出错位置在 test 函数,cmdTest.c 的第 4 行。
十三、定位 crash 问题 –addr2line
有时候程序崩溃了但不幸没有生成 core 文件,是不是就完全没有办法了呢? 还是 cmdTest 的例子。运行完 cmdTest 之后,我们通过 dmesg 命令可以获取到以下内容
[27153070.538380] traps: cmdTest[2836] trap divide error ip:40053b sp:7ffc230d9280 error:0 in cmdTest[400000+1000]
该信息记录了 cmdTest 运行出错的基本原因 (divide error) 和出错位置(40053b), 我们使用 addr2line 命令获取出错具体行号:
addr2line -e cmdTest 40053b
/home/hyb/practice/cmdTest.c:4
可以看到 addr2line 命令将地址 (40053b) 翻译成了文件名 (cmdTest.c) 和行号(4),确定了出错位置。
总结
本文对以上命令仅介绍其经典使用,这些命令都还有其他一些有帮助的用法,但由于篇幅有限,不在此介绍,更多使用方法可以通过 man 命令名的方式去了解。
以上就是马哥教育今天为大家分享的关于 Linux 运维常用的命令介绍 - 开发调试命令介绍的文章,希望本篇文章能够对正在从事 Linux 相关工作的小伙伴们有所帮助,想要了解更多 Linux 相关知识记得关注马哥教育官网。最后祝愿小伙伴们工作顺利!
声明:文章来源于网络,侵删!