linux常用命令--开发调试篇

前言

Linux常用命令中有一些命令可以在开发或调试过程中起到很好的帮助作用,有些可以帮助了解或优化我们的程序,有些可以帮我们定位疑难问题。本文将简单介绍一下这些命令。
转自:https://www.yanbinghu.com/2018/09/26/61877.html

示例程序

我们用一个小程序,来帮助后面我们对这些命令的描述,程序清单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=%d\n",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错误异常终止。

常用开发调试命令

1 查看文件基本信息—file

file cmdTest

输出:

cmdTest: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=a1bd4a7dd456246a029c0f5dfc763042b8d2c68e, with debug_info, not stripped

通过file命令可以看到cmdTest的类型为elf,是64位、运行于x86-64的程序,not striped表明elf文件中还保留着符号信息以及调试信息等不影响程序运行的内容。

2 查看程序依赖库—ldd

ldd cmdTest

输出:

        linux-vdso.so.1 (0x00007fffa5be0000)libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3185bf0000)/lib64/ld-linux-x86-64.so.2 (0x00007f31861e3000)

我们可以看到cmdTest依赖了libc.so等库。

3 查看函数或者全局变量是否存在于elf文件中—nm

nm命令用于查看elf文件的符号信息。文件编译出来之后,我们可能不知道新增加的函数或者全局变量是否已经成功编译进去。这时候,我们可以使用nm命令来查看。
例如,查看前面所提到的elf文件有没有test函数,可以用命令:

nm cmdTest | grep test

输出:

000000000040052d T test  

按照地址顺序列出符号信息:

nm -n cmdTest

输出:

                 w __cxa_finalize@@GLIBC_2.2.5w __gmon_start__w _ITM_deregisterTMCloneTablew _ITM_registerTMCloneTableU __libc_start_main@@GLIBC_2.2.5U printf@@GLIBC_2.2.5
00000000000004f0 T _init
0000000000000540 T _start
0000000000000570 t deregister_tm_clones
00000000000005b0 t register_tm_clones
0000000000000600 t __do_global_dtors_aux
0000000000000640 t frame_dummy
000000000000064a T test
000000000000065d T main
00000000000006b0 T __libc_csu_init
0000000000000720 T __libc_csu_fini
0000000000000724 T _fini
0000000000000730 R _IO_stdin_used
0000000000000740 r __GNU_EH_FRAME_HDR
00000000000008ac r __FRAME_END__
0000000000200db8 t __frame_dummy_init_array_entry
0000000000200db8 t __init_array_start
0000000000200dc0 t __do_global_dtors_aux_fini_array_entry
0000000000200dc0 t __init_array_end
0000000000200dc8 d _DYNAMIC
0000000000200fb8 d _GLOBAL_OFFSET_TABLE_
0000000000201000 D __data_start
0000000000201000 W data_start
0000000000201008 D __dso_handle
0000000000201010 B __bss_start
0000000000201010 b completed.7698
0000000000201010 D _edata
0000000000201010 D __TMC_END__
0000000000201018 B _end

可以看到test函数的开始地址为000000000000064a,结束地址为000000000000065d。

4 打印elf文件中的可打印字符串—strings

例如你在代码中存储了一个版本号信息,那么即使编译成elf文件后,仍然可以通过strings搜索其中的字符串甚至可以搜索某个.c文件是否编译在其中:

strings elfFile| grep "someString"

5 查看文件段大小—size

可以通过size命令查看各段大小:

size cmdTest

输出:

   text    data     bss     dec     hex filename1619     600       8    2227     8b3 cmdTest

text段:正文段字节数大小
data段:包含静态变量和已经初始化的全局变量的数据段字节数大小
bss段:存放程序中未初始化的全局变量的字节数大小
当我们知道各个段的大小之后,如果有减小程序大小的需求,就可以有针对性的对elf文件进行优化处理。

6 为elf文件”瘦身“—strip

strip用于去掉elf文件中所有的符号信息:

ls -al cmdTest
-rwxr-xr-x 1 hyb root 9792 Sep 25 20:30 cmdTest #总大小为9792字节strip cmdTestls -al cmdTest
-rwxr-xr-x 1 hyb root 6248 Sep 25 20:35 cmdTest#strip之后大小为6248字节

可以看到,“瘦身”之后,大小减少将近三分之一。但是要特别注意的是,“瘦身”之后的elf文件由于没有了符号信息,许多调试命令将无法正常使用,出现core dump时,问题也较难定位,因此只建议在正式发布时对其进行“瘦身”。

7 查看elf文件信息—readelf

readelf用于查看elf文件信息,它可以查看各段信息,符号信息等,下面的例子是查看elf文件头信息:

readelf -h cmdTest

输出:

ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              DYN (Shared object file)Machine:                           Advanced Micro Devices X86-64Version:                           0x1Entry point address:               0x540Start of program headers:          64 (bytes into file)Start of section headers:          8808 (bytes into file)Flags:                             0x0Size of this header:               64 (bytes)Size of program headers:           56 (bytes)Number of program headers:         9Size of section headers:           64 (bytes)Number of section headers:         34Section header string table index: 33

从elf头信息中,我们可以知道该elf是64位可执行文件,运行在x86-64中,且字节序为小端序。另外,我们还注意到它的入口地址是0x400440(_start),而不是400540(main)。也就是说,我们的程序运行并非从main开始

8 反汇编指定函数—objdump

objdump用于展示elf文件信息,功能较多,在此不逐一介绍。有时候我们需要反汇编来定位一些问题,可以使用命令:

objdump -d cmdTest #反汇编整个cmdTest程序

但是如果程序较大,那么反汇编时间将会变长,而且反汇编文件也会很大。如果我们已经知道了问题在某个函数,只想反汇编某一个函数,怎么处理呢?
我们可以利用前面介绍的nm命令获取到函数test的地址,然后使用下面的方式反汇编:

objdump -d cmdTest --start-address=0x40052d --stop-address=0x400540 	# 反汇编指定地址区间

9 端口占用情况查看—netstat

我们可能常常会遇到进程第一次启动后,再次启动会出现端口绑定失败的问题,我们可以通过netstat命令查看端口占用情况:

netstat -anp|grep 端口号

10 进程状态查看—ps&top

ps命令用于显示当前进程的状态,类似于 windows 的任务管理器。
top命令实时显示当前进程状态,最活跃的进程显示在最顶部。

11 core dump文件生成配置—ulimit -c

有时候我们的程序core dump了却没有生成core文件,很可能是我们设置的问题:

ulimit -c #查看core文件配置,如果结果为0,程序core dump时将不会生成core文件
ulimit -c unlimited #不限制core文件生成大小
ulimit -c 10 #设置最大生成大小为10kb

12 调试神器—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行。

13 定位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命令名的方式去了解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532779.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简单有趣的c语言小程序,一个有趣的小程序

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼源码:#include #include #include #include #include HINSTANCE g_hInstance 0;LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR lpCmdLine,int nSh…

linux下ora 01110,ORA-01003ORA-01110

Oracle 9i数据库登录时&#xff0c;提示ORA-01003&ORA-01110&#xff0c;大概意思是数据文件存储介质损坏。startup nomount,正常&#xff1b;alter database mount,也正常&#xff1b;alter database open,提示如下&#xff1a;alter database open*ERROR 位于第 1 行:ORA…

x11转发:通过ssh远程使用GUI程序

x11转发&#xff1a;通过ssh远程使用GUI程序 我们常常使用ssh服务远程操控服务器&#xff0c;大多数操作我们都可以通过命令行命令来实现。 ssh远程无法查看GUI程序 现在&#xff0c;笔者在x11-test目录下放入一张图片test.jpg&#xff0c;并通过opnencv-python写一个简单的…

操作系统引导详细过程

操作系统引导详细过程 转自&#xff1a;https://blog.csdn.net/lijie45655/article/details/89366372 就直观而言&#xff0c;我们所见到计算机启动的过程是&#xff1a;按下电脑开机键&#xff0c;系统在黑色的屏幕下打印出一些英文语句、然后进入进度条状态&#xff0c;最后…

android 自定义透明 等待 dialog,Android自定义Dialog内部透明、外部遮罩效果

Android自定义Dialog内部透明、外部遮罩效果发布时间&#xff1a;2020-09-09 03:01:41来源&#xff1a;脚本之家阅读&#xff1a;117作者&#xff1a;zst1303939801本文实例为大家分享了Android自定义Dialog遮罩效果的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下图…

对比损失的PyTorch实现详解

对比损失的PyTorch实现详解 本文以SiT代码中对比损失的实现为例作介绍。 论文&#xff1a;https://arxiv.org/abs/2104.03602 代码&#xff1a;https://github.com/Sara-Ahmed/SiT 对比损失简介 作为一种经典的自监督损失&#xff0c;对比损失就是对一张原图像做不同的图像…

android 融云浏览大图,融云 Android sdk kit 头像昵称更新机制

先申明笔者的实现方式不是唯一 也不一定是最优化的方案 如果您看到此篇博文 有不同看法 或者 更好的优化 更高的效率 欢迎在评论发表意见 融云官网点我融云头像机制相关视频详解首先跟大家说一下 kit 跟 lib 的头像机制 kit 是已经包含融云已经给开发者定制好的界面 诸如 会话界…

RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one.

RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. 报错信息 报错信息&#xff1a; RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one. This error indicates tha…

android访问重定向地址,如何从android中重定向url加载图像(示例代码)

嗨&#xff0c;我正面临这个问题我从RESTCall获取了一个URL网址是http://hck.re/kWWxUI但是当我在浏览器中检查时&#xff0c;它会重定向到https://s3-ap-southeast-1.amazonaws.com/he-public-data/afreen2ac5a33.jpg如何将此图像加载到我的imageView中我已经知道如何将毕加索…

Linux中的awk、sed、grep及正则表达式详解

Linux中的awk、sed、grep及正则表达式详解 简介 awk、sed和grep是Linux中文本操作的三大利器。 其中awk适用于取列&#xff0c;sed适用于取行&#xff0c;grep适用于过滤。 正则表达式 首先我们来介绍一下正则表达式&#xff0c;正则表达式(regular expression)描述了一种…

android聚焦时如何给控件加边框,edittext设置获得焦点时的边框颜色

第一步&#xff1a;为了更好的比较&#xff0c;准备两个一模一样的EditText(当Activity启动时&#xff0c;焦点会在第一个EditText上&#xff0c;如果你不希望这样只需要写一个高度和宽带为0的EditText即可避免&#xff0c;这里就不这么做了)&#xff0c;代码如下&#xff1a;a…

gcc参数 -i, -L, -l, -include

gcc参数 -i, -L, -l, -include -i&#xff0c;-L&#xff0c;-l&#xff0c;-include -l和-L -l参数就是用来指定程序要链接的库&#xff0c;-l参数紧接着就是库名&#xff0c;那么库名跟真正的库文件名有什么关系呢&#xff1f;就拿数学库来说&#xff0c;他的库名是m&…

xargs 命令教程

xargs 命令教程 转自&#xff1a;http://www.ruanyifeng.com/blog/2019/08/xargs-tutorial.html 作者&#xff1a; 阮一峰 日期&#xff1a; 2019年8月 8日 xargs是 Unix 系统的一个很有用的命令&#xff0c;但是常常被忽视&#xff0c;很多人不了解它的用法。 本文介绍如…

android strictmode有什么作用,Android 性能优化 之 StrictMode

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;StrictMode概述StrictMode 是用来检测程序中违例情况的开发者工具。使用StrictMode&#xff0c;系统检测出主线程违例的情况会做出相应的反应&#xff0c;如日志打…

curl 的用法指南

curl 的用法指南 转自&#xff1a;http://www.ruanyifeng.com/blog/2019/09/curl-reference.html 作者&#xff1a; 阮一峰 日期&#xff1a; 2019年9月 5日 简介 curl 是常用的命令行工具&#xff0c;用来请求 Web 服务器。它的名字就是客户端&#xff08;client&#xf…

怎么在html显示已登录状态,jQuery Ajax 实现在html页面实时显示用户登录状态

当网站是全静态的html页面时&#xff0c;而又希望网站会员在登录之后并在所有页面头部显示登录状态&#xff0c;如用户名等&#xff0c;如果未登录就是未登录状态&#xff0c;下面给大家来分享实现的方法。一、在html静态页面中加入div&#xff0c;并指定ID如&#xff1a;二、新…

互斥锁、条件变量、信号量浅析

互斥锁、条件变量、信号量浅析 互斥锁与条件变量 条件变量是为了保证同步 条件变量用在多线程多任务同步的&#xff0c;一个线程完成了某一个动作就通过条件变量告诉别的线程&#xff0c;别的线程再进行某些动作&#xff08;大家都在semtake的时候&#xff0c;就阻塞在哪里&a…

xpwifi热点设置android,教你在XP电脑中开启设置WiFi热点使用的步骤

对于系统中网络的连接问题是最重要的&#xff0c;那在处理不同的错误的情况中&#xff0c;对于无线网络的设置也就是我们说的WiFi的使用也是会遇到问题的&#xff0c;那在操作的时候对于电脑中是怎么实现设置WiFi热点的的&#xff0c;对于这个问题今天小编就来跟大家分享一下教…

C/C++ 指针详解

指针详解 参考视频&#xff1a;https://www.bilibili.com/video/BV1bo4y1Z7xf/&#xff0c;感谢Bilibilifengmuzi2003的搬运翻译及后续勘误&#xff0c;也感谢已故原作者Harsha Suryanarayana的讲解&#xff0c;RIP。 学习完之后&#xff0c;回看找特定的知识点&#xff0c;善…

android双联动列表,Android Fragment实现列表和内容联动

在平板上经常能看到这种的情况&#xff1a;左边是一个列表&#xff0c;右边是列表项对应的内容&#xff0c;当点击某一个列表时&#xff0c;右边内容区也会随之改变。下面使用fragment简单的demo&#xff1a;思路&#xff1a;在mainactivity定义一个回调接口&#xff0c;并在列…