国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

gdb調(diào)試多線程

2019-11-08 19:39:56
字體:
供稿:網(wǎng)友
gdb使用gdb與多線程

gdb使用

gdb是非常強大的調(diào)試工具,在文本模式下使用。使用方法可以參考陳皓的兩篇文章 用GDB調(diào)試程序(一) 用GDB調(diào)試程序(二)

gdb常用命令在下表列出:

命令描述
backtrace(或bt)查看各級函數(shù)調(diào)用及參數(shù)
finish連續(xù)運行到當前函數(shù)返回為止,然后停下來等待命令
frame(或f)幀編號 選擇棧幀
info(或i)locals 查看當前棧幀局部變量的值
list(或l)列出源代碼,接著上次的位置往下列,每次列10行
list 行號列出從第幾行開始的源代碼
list 函數(shù)名列出某個函數(shù)的源代碼
next(或n)執(zhí)行下一行語句
PRint(或p)打印表達式的值,通過表達式可以修改變量的值或者調(diào)用函數(shù)
quit(或q)退出gdb調(diào)試環(huán)境
set var修改變量的值
start開始執(zhí)行程序,停在main函數(shù)第一行語句前面等待命令
step(或s)執(zhí)行下一行語句,如果有函數(shù)調(diào)用則進入到函數(shù)中

gdb與多線程

在多線程編程時,當我們需要調(diào)試時,有時需要控制某些線程停在斷點,有些線程繼續(xù)執(zhí)行。有時需要控制線程的運行順序。有時需要中斷某個線程,切換到其他線程。這些都可以通過gdb實現(xiàn)。

先來看一下gdb調(diào)試多線程常用命令:

info threads:顯示可以調(diào)試的所有線程。gdb會為每個線程分配一個ID(和tid不同),編號一般從1開始。后面的ID是指這個ID。

thread ID:切換當前調(diào)試的線程為指定ID的線程。

break FileName.cpp:LinuNum thread all:所有線程都在文件FileName.cpp的第LineNum行有斷點。

thread apply ID1 ID2 IDN command:多個線程執(zhí)行g(shù)db命令command。

thread apply all command:所有線程都執(zhí)行command命令。

set scheduler-locking off|on|step:在調(diào)式某一個線程時,其他線程是否執(zhí)行。off,不鎖定任何線程,默認值。on,鎖定其他線程,只有當前線程執(zhí)行。step,在step(單步)時,只有被調(diào)試線程運行。

set non-stop on/off:當調(diào)式一個線程時,其他線程是否運行。

set pagination on/off:在使用backtrace時,在分頁時是否停止。

set target-async on/ff:同步和異步。同步,gdb在輸出提示符之前等待程序報告一些線程已經(jīng)終止的信息。而異步的則是直接返回。

來看一個例子: gdbTest.cpp。程序很簡單,只是讓兩個線程執(zhí)行函數(shù)ThreadFun,在函數(shù)中打印傳入的參數(shù)。

#include <iostream>#include <pthread.h>void* ThreadFun(void* arg){    int *value=static_cast<int*> (arg);    std::cout<<"This is thread"<<*value<<std::endl;    pthread_exit(0);}int main(){    int  ret=0;    pthread_t thread_id1,thread_id2;    int* v1=new int(1);    int* v2=new int(2);    ret = pthread_create(&thread_id1, NULL, ThreadFun, static_cast<void*>(v1));     if (ret)    {        std::cout<<"Create pthread error!"<<std::endl;        return 1;    }    ret = pthread_create(&thread_id2, NULL, ThreadFun, static_cast<void*>(v2));    if (ret)    {        std::cout<<"Create pthread error!"<<std::endl;        return 1;    }    pthread_join(thread_id1, NULL);    pthread_join(thread_id2, NULL);    return 0;}123456789101112131415161718192021222324252627282930313233343536123456789101112131415161718192021222324252627282930313233343536
$ gdb gdbThreadTest//調(diào)試gdbThreadTest11

加斷點

(gdb) break 7Breakpoint 1 at 0x400a19: file kangThread.cpp, line 7.(gdb) break 35Breakpoint 2 at 0x400b35: file kangThread.cpp, line 35.(gdb) info breakNum     Type           Disp Enb Address            What1       breakpoint     keep y   0x0000000000400a19 in ThreadFun(void*) at kangThread.cpp:72       breakpoint     keep y   0x0000000000400b35 in main() at kangThread.cpp:351234567812345678

開始運行

(gdb) rStarting program: /home/kang/src/mulThread/kangThread [Thread debugging using libthread_db enabled]Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".Traceback (most recent call last):  File "/usr/share/gdb/auto-load/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19-gdb.py", line 63, in <module>    from libstdcxx.v6.printers import register_libstdcxx_printersImportError: No module named 'libstdcxx'[New Thread 0x7ffff6fd5700 (LWP 2773)][Switching to Thread 0x7ffff6fd5700 (LWP 2773)]Breakpoint 1, ThreadFun (arg=0x602010) at kangThread.cpp:7warning: Source file is more recent than executable.7       int *value=static_cast<int*> (arg);12345678910111213141234567891011121314

查看線程信息

(gdb) info thread[New Thread 0x7ffff67d4700 (LWP 2774)]  Id   Target Id         Frame   3    Thread 0x7ffff67d4700 (LWP 2774) "kangThread" clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:81* 2    Thread 0x7ffff6fd5700 (LWP 2773) "kangThread" ThreadFun (arg=0x602010) at kangThread.cpp:7  1    Thread 0x7ffff7fda780 (LWP 2769) "kangThread" clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:81123456123456

可以看到ID為2的線程執(zhí)行到了斷點Breakpoint 1。可以看一下value的值

(gdb) n8       std::cout<<"This is thread"<<*value<<std::endl;(gdb) p *value$2 = 112341234

切換到線程3,看一下線程3執(zhí)行到了哪里

(gdb) cContinuing.1[Switching to Thread 0x7ffff67d4700 (LWP 2774)]Breakpoint 1, ThreadFun (arg=0x602030) at kangThread.cpp:77       int *value=static_cast<int*> (arg);(gdb) info thread  Id   Target Id         Frame * 3    Thread 0x7ffff67d4700 (LWP 2774) "kangThread" ThreadFun (arg=0x602030) at kangThread.cpp:7  2    Thread 0x7ffff6fd5700 (LWP 2773) "kangThread" __GI__dl_debug_state () at dl-debug.c:74  1    Thread 0x7ffff7fda780 (LWP 2769) "kangThread" 0x00007ffff7bc566b in pthread_join (threadid=140737337186048,     thread_return=0x0) at pthread_join.c:92(gdb) thread 3[Switching to thread 3 (Thread 0x7ffff67d4700 (LWP 2774))]#0  ThreadFun (arg=0x602030) at kangThread.cpp:77       int *value=static_cast<int*> (arg);(gdb) n8       std::cout<<"This is thread"<<*value<<std::endl;(gdb) p *value$3 = 2123456789101112131415161718192021123456789101112131415161718192021

可以看出線程3的value為2。

還有其他許多命令和方法,要在實踐中慢慢熟悉。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 平度市| 德格县| 岢岚县| 三穗县| 米林县| 固始县| 贡山| 威信县| 淮安市| 盐津县| 固安县| 大连市| 东至县| 逊克县| 和林格尔县| 尉氏县| 温宿县| 泌阳县| 和田县| 阳新县| 固阳县| 集安市| 郁南县| 山西省| 嵊州市| 彭州市| 牡丹江市| 高唐县| 夏河县| 刚察县| 水富县| 海原县| 邯郸县| 淳化县| 霍山县| 巴彦淖尔市| 湘阴县| 察哈| 玉山县| 大理市| 南开区|