1. 程式人生 > >多執行緒中快速定位段錯誤位置

多執行緒中快速定位段錯誤位置

參考連結:https://blog.csdn.net/u011426247/article/details/79736111

在做嵌入式Linux開發的時候,程式很容易出現段錯誤。段錯誤一般是記憶體操作指標出錯或是記憶體溢位等問題,有的時候系統會有一點錯誤提示,但有的時候就直接提示個Segmentation fault (core dumped) 。如果程式是單執行緒,那很好處理,編譯的時候新增引數-g  ,直接使用gdb 單步除錯就可以直接定位到問題點在哪了。但是對於多執行緒,情況就不一樣了。多執行緒進行單步除錯不好處理,並且時候程式需要執行很久才出來段錯誤。這樣直接使用gdb單步除錯就不合適了。這裡提供一種快速定位段錯誤的方式。

1.ulimit 命令設定core檔案的最大值
1.1執行ulimit -a, 檢視core檔案的最大值,一般預設值是0

[email protected]:~/test/FWH/9th_DiskTest$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 3712
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 3712
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited


1.2執行命令:ulimit -c unlimited

[email protected]:~/test/FWH/9th_DiskTest$ ulimit -c unlimited
[email protected]:~/test/FWH/9th_DiskTest$ ulimit -a 
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 3712
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 3712
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
[email protected]
:~/test/FWH/9th_DiskTest$ 


可以看到core file size  已經被修改為不受限制,執行程式的時候會在當前目錄生成一個core檔案
[email protected]:~/test/FWH/9th_DiskTest$ ls
core  Diskmanage  EncodeReadWrite  IndexManage  main.cpp  main.o  Makefile  sharestruct.h  test


2.使用gdb除錯:
[email protected]:~/test/FWH/9th_DiskTest$ sudo gdb test core 
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from test...done.
[New LWP 7445]
[New LWP 7440]
[New LWP 7441]
[New LWP 7443]
[New LWP 7444]
[New LWP 7442]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00000000004046c0 in StorageService::VideoWriteThread (this=0x71e470, arg=0x7fffac5cbccc)
    at EncodeReadWrite/StorageService.cpp:627
627                             l_s32Ret = l_pAudioQue[i]->ReadQueue(i,(void*)l_pAudioDataOut[i]);
[Current thread is 1 (Thread 0x7f32e0fa5700 (LWP 7445))]
(gdb) printf i
Bad format string, missing '"'.
(gdb) print i 
$1 = 6
(gdb) q
[email protected]:~/test/FWH/9th_DiskTest$ 

上面的test 為我的可執行程式。
這樣可以精確的定位到出現段錯誤的函式行,並可以檢視各引數的值,這樣定位起來就很快了。


注意:在一個shell 執行緒中,core file size 值只能被修改一次,如果取消之後再修改會出現錯誤:
-bash: ulimit: core file size: cannot modify limit: Operation not permitted
解決這一問題的方法是exit退出該shell,重啟一個shell 就可以了。