Linux-gdb调试
来源:互联网 发布:苏联大清洗知乎 编辑:程序博客网 时间:2024/06/02 05:59
今天训练yolo-v2一直出错,就想单步调试以下,因为用printf比较麻烦,选用了gdb调试。
首先修改下Makefile文件,将19行
CC=gcc
改为
CC=gcc -g
然后重新编译,编译完成后运行以下命令进入gdb调试
$gdb darknet
你会看到以下提示
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-51.el7Copyright (C) 2013 Free Software Foundation, Inc.License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>This is free software: you are free to change and redistribute it.There is NO WARRANTY, to the extent permitted by law. Type "show copying"and "show warranty" for details.This GDB was configured as "x86_64-redhat-linux-gnu".For bug reporting instructions, please see:<http://www.gnu.org/software/gdb/bugs/>...Reading symbols from /home/guoyana/my_files/local_install/darknet-v2/darknet...done.(gdb)
然后设置命令行参数,方法如下
(gdb) set args yolo train ./cfg/yolo-voc.cfg
回车后命令行参数就设置完了,我们用show来看一下
(gdb) show argsArgument list to give program being debugged when it is started is "yolo train ./cfg/yolo-voc.cfg ".
然后我们想在yolo.c文件中设置个断点,等程序运行到指定位置的时候停止,然后单步运行,看错误出在哪一步,设置断点方式如下:
(gdb) b yolo.c:40Breakpoint 1 at 0x451d44: file ./src/yolo.c, line 40.
然后用r指令来运行程序:
(gdb) rStarting program: /home/guoyana/my_files/local_install/darknet-v2/darknet yolo train ./cfg/yolo-voc.cfg [Thread debugging using libthread_db enabled]Using host libthread_db library "/lib64/libthread_db.so.1".yolo-voclayer filters size input output 0 [New Thread 0x7fffc52e1700 (LWP 13524)]conv 32 3 x 3 / 1 416 x 416 x 3 -> 416 x 416 x 32 1 max 2 x 2 / 2 416 x 416 x 32 -> 208 x 208 x 32 2 conv 64 3 x 3 / 1 208 x 208 x 32 -> 208 x 208 x 64 3 max 2 x 2 / 2 208 x 208 x 64 -> 104 x 104 x 64 4 conv 128 3 x 3 / 1 104 x 104 x 64 -> 104 x 104 x 128 5 conv 64 1 x 1 / 1 104 x 104 x 128 -> 104 x 104 x 64 6 conv 128 3 x 3 / 1 104 x 104 x 64 -> 104 x 104 x 128 7 max 2 x 2 / 2 104 x 104 x 128 -> 52 x 52 x 128 8 conv 256 3 x 3 / 1 52 x 52 x 128 -> 52 x 52 x 256 9 conv 128 1 x 1 / 1 52 x 52 x 256 -> 52 x 52 x 128 10 conv 256 3 x 3 / 1 52 x 52 x 128 -> 52 x 52 x 256 11 max 2 x 2 / 2 52 x 52 x 256 -> 26 x 26 x 256 12 conv 512 3 x 3 / 1 26 x 26 x 256 -> 26 x 26 x 512 13 conv 256 1 x 1 / 1 26 x 26 x 512 -> 26 x 26 x 256 14 conv 512 3 x 3 / 1 26 x 26 x 256 -> 26 x 26 x 512 15 conv 256 1 x 1 / 1 26 x 26 x 512 -> 26 x 26 x 256 16 conv 512 3 x 3 / 1 26 x 26 x 256 -> 26 x 26 x 512 17 max 2 x 2 / 2 26 x 26 x 512 -> 13 x 13 x 512 18 conv 1024 3 x 3 / 1 13 x 13 x 512 -> 13 x 13 x1024 19 conv 512 1 x 1 / 1 13 x 13 x1024 -> 13 x 13 x 512 20 conv 1024 3 x 3 / 1 13 x 13 x 512 -> 13 x 13 x1024 21 conv 512 1 x 1 / 1 13 x 13 x1024 -> 13 x 13 x 512 22 conv 1024 3 x 3 / 1 13 x 13 x 512 -> 13 x 13 x1024 23 conv 1024 3 x 3 / 1 13 x 13 x1024 -> 13 x 13 x1024 24 conv 1024 3 x 3 / 1 13 x 13 x1024 -> 13 x 13 x1024 25 route 16 26 reorg / 2 26 x 26 x 512 -> 13 x 13 x2048 27 route 26 24 28 conv 1024 3 x 3 / 1 13 x 13 x3072 -> 13 x 13 x1024 29 conv 125 1 x 1 / 1 13 x 13 x1024 -> 13 x 13 x 125 30 detectionLearning Rate: 0.0001, Momentum: 0.9, Decay: 0.0005Breakpoint 1, train_yolo (cfgfile=0x7fffffffe5bb "./cfg/yolo-voc.cfg", weightfile=<optimized out>) at ./src/yolo.c:4141 char **paths = (char **)list_to_array(plist);Missing separate debuginfos, use: debuginfo-install glibc-2.17-55.el7_0.3.x86_64 libgcc-4.8.2-16.2.el7_0.x86_64 libstdc++-4.8.2-16.2.el7_0.x86_64(gdb)
我们看到程序停留在了41行,为什么呢?不是40行么……
之后我们敲个n,然后就不停的回车,会看到以下运行过程
...48 args.m = plist->size;(gdb) 52 args.d = &buffer;(gdb) 58 args.hue = net.hue;(gdb) 52 args.d = &buffer;(gdb) 58 args.hue = net.hue;(gdb) 60 pthread_t load_thread = load_data_in_thread(args);(gdb) [New Thread 0x7fff384fd700 (LWP 16478)]22 float avg_loss = -1;(gdb) 60 pthread_t load_thread = load_data_in_thread(args);(gdb) 22 float avg_loss = -1;(gdb) 63 while(get_current_batch(net) < net.max_batches){(gdb) 65 time=clock();(gdb) 66 pthread_join(load_thread, 0);(gdb) 65 time=clock();(gdb) 66 pthread_join(load_thread, 0);(gdb) Program received signal SIGSEGV, Segmentation fault.[Switching to Thread 0x7fff384fd700 (LWP 16478)]0x00007fffeffd7595 in _int_malloc () from /lib64/libc.so.6(gdb)
可以看到程序不是一步一步往下执行,跳来跳去,这是多线程的问题,最后程序报错了。SIGSEGV是什么意思呢?看一下百度百科的解释~
在POSIX兼容的平台上,SIGSEGV是当一个进程执行了一个无效的内存引用,或发生段错误时发送给它的信号。SIGSEGV的符号常量在头文件signal.h中定义。因为在不同平台上,信号数字可能变化,因此符号信号名被使用。通常,它是信号#11。
原来是内存错误,可能是内存不够用,我就看下内存占用
$free -h total used free shared buffers cachedMem: 125G 124G 1.1G 1.4G 50M 82G-/+ buffers/cache: 41G 84GSwap: 0B 0B 0B
原来小伙伴都在搞事情啊……
最后补充一个gdb的常用命令,供大家参考
(END)
1 0
- linux gdb调试
- LINUX下GDB调试
- linux gdb 调试实例
- LINUX下GDB调试
- LINUX下GDB调试
- linux GDB 调试多线程
- linux-arm gdb调试
- linux GDB调试程序
- LINUX下GDB调试
- Linux Gdb调试初步
- gdb调试Linux内核
- gdb 调试 linux程序
- GDB--Linux调试工具
- LINUX下GDB调试
- linux下gdb调试
- linux GDB调试学习
- Linux下GDB调试
- LINUX下GDB调试
- oj期中测验--B: 刑警的射击成绩(2449)
- 【leetcode】Remove Duplecates from Sorted Array 和 Remove Duplicates from Sorted List
- 左手有话说(2)
- 【Linux多线程同步】读写锁
- JQUERY EASYUI DATAGRID设置可编辑行的某个列不可编辑
- Linux-gdb调试
- 观察者模式
- CSS清除浮动的方法优缺点分析
- ORACLE PROFILE(配置文件)查询
- PhoneGAP实现带进度条的文件上传(支持任意类型文件)
- 网络层 学习笔记
- 微信直播平台制作
- RabbitMQ初探
- mfc Png转IStream