一,前言
qemu中有些glib库的api,我想学习试用下。
二,编译及调试
1. 使用glib库后编译报错,缺少头文件
root@ubuntu:/work/study# gcc t1.c -o t1
t1.c:2:18: fatal error: glib.h: No such
file or directory
#include <glib.h>
^
compilation terminated.
2. 搜索glib.h的头文件路径
root@ubuntu:/work/study# locate glib.h
/mnt/hgfs/sharevm/nuttx/apache-nuttx-10.0.1-incubating.tar/apache-nuttx-10.0.1-incubating/nuttx/graphics/nxglib/nxglib.h
/mnt/hgfs/sharevm/nuttx/apache-nuttx-10.0.1-incubating.tar/apache-nuttx-10.0.1-incubating/nuttx/include/nuttx/nx/nxglib.h
/usr/include/glib-2.0/glib.h
/usr/src/linux-headers-4.4.0-142-generic/include/config/blk/dev/bsglib.h
找到路径是/usr/include/glib-2.0
3. 然后想到还有其他路径或库路径,最简单的是用pkg-config来搜索自定路径,先看看路径吧
root@ubuntu:/work/study# pkg-config
--cflags --libs glib-2.0
-I/usr/include/glib-2.0
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include
-lglib-2.0
4. 编译命令修改为
gcc `pkg-config --cflags --libs glib-2.0` t1.c -o t1,结果报错,有一堆undefined,难道库路径不正确,奇怪
t1.c:(.text+0x42): undefined reference to `g_free'
4. 查库路径下是否有函数定义
root@ubuntu:/work/study# nm -D
/usr/lib/x86_64-linux-gnu/libglib-2.0.so|grep g_hash_table_new_full
0000000000038150 T g_hash_table_new_full
看上去有函数定义的。难道makefile链接的是同名的其它路径
5. 搜索libglib-2.0.so的路径
root@ubuntu:/work/study# locate
libglib-2.0.so
/lib/x86_64-linux-gnu/libglib-2.0.so.0
/lib/x86_64-linux-gnu/libglib-2.0.so.0.4002.0
/usr/lib/vmware-tools/lib32/libglib-2.0.so.0
/usr/lib/vmware-tools/lib32/libglib-2.0.so.0/libglib-2.0.so.0
/usr/lib/vmware-tools/lib64/libglib-2.0.so.0
/usr/lib/vmware-tools/lib64/libglib-2.0.so.0/libglib-2.0.so.0
/usr/lib/x86_64-linux-gnu/libglib-2.0.so
作为默认路径/usr/lib下就这么一个库,怎么回事,后来搜索其它人用pkg-config的用法,原来位置要放.c后面
6. 修改命令为gcc t1.c `pkg-config --cflags --libs glib-2.0` -o t1后编译通过。
7. 运行后就core dumped了
root@ubuntu:/work/study# ./t1
hash num:5
key:1, value:test1
*** Error in `./t1': munmap_chunk():
invalid pointer: 0x0000000000400c4f ***
Aborted (core dumped)
8. 先要支持生成coredump
ulimit -c unlimit
9. Coredump的路径查看
root@ubuntu:/work/study# cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %d %P
10. coredump的路径修改(此为临时修改法,复位后就没了)
echo "/tmp/cores/core.%e.%p.%h.%t" > /proc/sys/kernel/core_pattern
然后在tmp文件夹下创建cores文件夹即可。
就会看到生成了core文件。
cp core.t1.2779.ubuntu.1694238626 /work/study/
11. 在temp/cores下有dump的文件,在本地路径也有。用gdb调试core文件
输入命令gdb ./t1 core.t1.2779.ubuntu.1694238626
然后bt
Using host libthread_db library
"/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./t1'.
Program terminated with signal SIGABRT,
Aborted.
#0
0x00007f0577140c37 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c:
No such file or directory.
(gdb) bt
#0
0x00007f0577140c37 in __GI_raise (sig=sig@entry=6)
at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1
0x00007f0577144028 in __GI_abort () at abort.c:89
#2
0x00007f057717d2a4 in __libc_message (do_abort=do_abort@entry=1,
fmt=fmt@entry=0x7f057728f350 "*** Error in `%s': %s: 0x%s
***\n")
at ../sysdeps/posix/libc_fatal.c:175
#3
0x00007f0577188007 in malloc_printerr (action=<optimized out>,
str=0x7f057728f6d0 "munmap_chunk(): invalid pointer",
ptr=<optimized out>)
at malloc.c:4998
#4
0x00007f057750a840 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#5
0x00007f057750adfa in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#6
0x0000000000400b65 in main ()
(gdb)
基本上看出munmap_chunk函数后就出问题了。
12. 然后去看源码,根据print的log信息基本上认为是删除动作出问题,然后看了qemu的用法,创建的时候最后2个是NULL,改成NULL就通过了。
所以我猜测这个glib版本有缺陷。
13. 内存检查看下
valgrind --leak-check=full ./t1
所以若无qemu中的用法对比,然后结合print的信息,也可以猜到和free相关的错误,就是g_hash_table_new_full中的参数。
三,输出物
四,小结
没想到就用几个api,过程还比较坎坷,不过正好让我复习下基于linux的debug技术。但是这也体现了一个问题,就是用库的过程中库若错误,真是又多了一个工作量,问题严重的话,可能还要去排查库的源码呢~