dmesg命令的用途

dmesg命令用会把开机信息存到ring bufer中, 形成一个缓冲, 免得你我来不及看。 在root权限下, 可以用dmesg -c来清除这个消息。 单纯的一个dmesg命令则是用来输出这些记录信息的。

功能说明:显示开机信息。

语  法dmesg \[-cn\]\[-s <缓冲区大小>\]

补充说明:kernel会将开机信息存储在ring buffer中。您若是开机时来不及查看信息,可利用dmesg来查看。开机信息亦保存在/var/log目录中,名称为dmesg的文件里。

参  数:

  • -c  显示信息后,清除ring buffer中的内容。
  • -s<缓冲区大小>  预设置为8196,刚好等于ring buffer的大小。
  • -n  设置记录信息的层级

addr2line命令使用

Addr2line 工具(它是标准的 GNU Binutils 中的一部分)是一个可以将指令的地址和可执行映像转换成文件名、函数名和源代码行数的工具。这种功能对于将跟踪地址转换成更有意义的内容来说简直是太棒了。

使用Addr2line 工具,就可以判断出函数名(main)、源文件(test.cpp)以及它在源文件中的行号。

在调用 Addr2line 工具时,要使用 -e 选项来指定可执行映像是 test。通过使用 -f 选项,可以告诉工具输出函数名。

经典dmesg + addr2line命令的使用

下面, 我们来看一下经典的dmesg + addr2line:

可见, 第5行有错。

为什么我的dmesg输出了几百几十行信息呢?当dmesg显示的信息较多时候, 我们通过grep来过滤, 比如 dmesg | grep a.out

在实际开发中, 通常是从日志文件中看到堆栈异常, 同样是为了拿到堆栈出错的地方, 然后用addr2line来定位代码行, 此时, 可以将日志文件看成是dmesg命令的扩展。 在这两种情况下, 我么可以不依赖于core文件, 便可搞定core dump了。

linux addr2line 返回??:?或??:0 如何解决?

按你的教程,为什么我的输出是下面这样子的呢?

为什么我的addr2line -e a.out 000000000040085a后输出了?:??呢?WTFaaaaaaaaa~~~~~

如果遇到addr2line得到??:?或??:0的情况,原因就是编译得到的so文件没有附加上符号表(symbolic)信息。

如果在android源码环境下,android编译环境会自动生成附带有符号表(symbolic)的so文件。标准android5.0中,附带有符号表(symbolic)的so文件在下面路径

out/target/product/[productname]/symbols/system/lib/****.so

如果是非android环境,需要在makefile中指定生成附带有符号表(symbolic)的so文件的选项,具体关于动态链接库以及符号表等,请参阅如下网站:http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

你如果仔细比对了上面两图的指令,会发现编译的参数略有差异:

正常的编译选项是g++ -std=c++11 -g test.cpp,出现?:??的是g++ -std=c++11 test.cpp。也就是说少了-g参数,那这个参数是什么意思呢?复习一下——

  • -o:指定生成可执行文件的名称。使用方法为:g++ -o afile file.cpp file.h … (可执行文件不可与待编译或链接文件同名,否则会生成相应可执行文件且覆盖原编译或链接文件),如果不使用-o选项,则会生成默认可执行文件a.out。
  • -c:只编译不链接,只生成目标文件。
  • -g:添加gdb调试选项。

Over,现在大工告成了!