基本的功能有了,可以開始了,首先在發送和接收線程增加斷點:
(gdb) b 36
Breakpoint 14 at 0x417e3e: file /root/projects/gdbTest/inet/Server.cpp, line 36.
(gdb) c
Continuing.
Breakpoint 14, inet::Server::__lambda0::operator() (__closure=0xc913c0) at /root/projects/gdbTest/inet/Server.cpp:36
36 int len = strlen(barr[num % 10]);
(gdb)
(gdb) b 55
Breakpoint 15 at 0x417fd6: file /root/projects/gdbTest/inet/Server.cpp, line 55.
(gdb) c
Continuing.
[Switching to Thread 0x7f18878d7700 (LWP 4146)]
Breakpoint 15, inet::Server::__lambda1::operator() (__closure=0xc91660) at /root/projects/gdbTest/inet/Server.cpp:55
55 int len = pData_->GetMemCount(0);
(gdb)
通過c命令來啟動進程的運行。
(gdb) l
50 {
51 this->idwork = std::thread([&]() {
52 //ת53 while (!quit_)
54 {
55 int len = pData_->GetMemCount(0);
56 if (len > 0)
57 {
58 for (int num = 0; num < len; num++)
59 {
(gdb)
60 std::shared_ptr<global::MemData> tmp = pData_->GetMemData(num, 0);
61 std::cout << "dataparse tmp comData:" << tmp->len << std::endl;
62 }
63
64 }
65
66 len = pData_->GetMemCount(1);
67 if (len > 0)
68 {
69 for (int num = 0; num < len; num++)
(gdb) p tmp
No symbol "tmp" in current context.
(gdb) n
[Switching to Thread 0x7f18880d8700 (LWP 4145)]
Breakpoint 14, inet::Server::__lambda0::operator() (__closure=0xc913c0) at /root/projects/gdbTest/inet/Server.cpp:36
36 int len = strlen(barr[num % 10]);
(gdb) n
37 memmove(dbuf_, barr[num%10], len);
(gdb) p num
$1 = (int &) @0x7ffc47677f9c: 33010
(gdb) p barr
$2 = {0x41cde3 "abce459v,$#@!`pit", 0x41cdf5 "NBG^*(_rrtthth", 0x41ce04 "YT%$#dghhfgdh88980", 0x41ce17 "##$gryryejhetrjrj", 0x41ce29 "whethtwrh8967777", 0x41ce3a "346346546*&****jjkkIO",
0x41ce50 "JL)(567568jgjhjgk", 0x41ce62 "ghjgktytuk", 0x41ce6d "45747476466&&***HJJKKTryret", 0x41ce89 "truytritrkmb<>NNHGG$##@"}
(gdb) p /x barr
$3 = {0x41cde3, 0x41cdf5, 0x41ce04, 0x41ce17, 0x41ce29, 0x41ce3a, 0x41ce50, 0x41ce62, 0x41ce6d, 0x41ce89}
(gdb) p /s barr
$4 = {0x41cde3 "abce459v,$#@!`pit", 0x41cdf5 "NBG^*(_rrtthth", 0x41ce04 "YT%$#dghhfgdh88980", 0x41ce17 "##$gryryejhetrjrj", 0x41ce29 "whethtwrh8967777", 0x41ce3a "346346546*&****jjkkIO",
0x41ce50 "JL)(567568jgjhjgk", 0x41ce62 "ghjgktytuk", 0x41ce6d "45747476466&&***HJJKKTryret", 0x41ce89 "truytritrkmb<>NNHGG$##@"}
(gdb) p /c barr
$5 = {227 '\343', 245 '\365', 4 '\004', 23 '\027', 41 ')', 58 ':', 80 'P', 98 'b', 109 'm', 137 '\211'}
(gdb) p *barr@3
$7 = {0x41cde3 "abce459v,$#@!`pit", 0x41cdf5 "NBG^*(_rrtthth", 0x41ce04 "YT%$#dghhfgdh88980"}
(gdb)
上面通過查看數據的命令來查看關心的數據。
二、線程切換控制在前面看到了線程的切換,下面使用命令鎖定一個線程來監控:
(gdb) show scheduler-locking
Mode for locking scheduler during execution is "step".
(gdb) set schedule
schedule-multiple scheduler-locking
(gdb) set scheduler-locking on
(gdb) n
37 memmove(dbuf_, barr[num%10], len);
(gdb) n
38 pData_->ParseComData(dbuf_, len);
(gdb) n
39 pData_->ParseNetData(dbuf_, len);
(gdb) n
41 num++;
(gdb) n
42 sleep(1);
(gdb) n
34 while (!quit_)
(gdb) n
Breakpoint 1, inet::Server::__lambda0::operator() (__closure=0x6a93c0) at /root/projects/gdbTest/inet/Server.cpp:36
36 int len = strlen(barr[num % 10]);
(gdb) n
37 memmove(dbuf_, barr[num%10], len);
(gdb) n
38 pData_->ParseComData(dbuf_, len);
(gdb) n
39 pData_->ParseNetData(dbuf_, len);
(gdb) n
41 num++;
(gdb)
可以發現,即使在線程Sleep退出時間片佔用後,仍然再次回到本線程,而沒有跳到另外一個線程中去。這樣就很好的解決了多線程,只想對某個線程進行控制的方法。
如果線程很多,可以用命令:
(gdb) info thread
Id Target Id Frame
* 3 Thread 0x7f5c9d2e3700 (LWP 97767) "gdbTest" inet::Server::__lambda0::operator() (__closure=0x6a93c0) at /root/projects/gdbTest/inet/Server.cpp:41
2 Thread 0x7f5c9cae2700 (LWP 97768) "gdbTest" 0x00007f5c9d3d3a1d in write () from /lib64/libc.so.6
1 Thread 0x7f5c9e305740 (LWP 97766) "gdbTest" 0x00007f5c9d6bb017 in pthread_join () from /lib64/libpthread.so.0
(gdb) thread 2
這種方法先進入指定線程,再進行鎖定即可。需要說明的是,調試完成後,要記得將線程調度重新設置為off。
如果想達到在IDE軟體中對某個變量的不間斷的監視,可以使用命令:
(gdb) display num
2: num = (int &) @0x7ffc447985bc: 32883
(gdb) c
Continuing.
Breakpoint 1, inet::Server::__lambda0::operator() (__closure=0x6a93c0) at /root/projects/gdbTest/inet/Server.cpp:36
36 int len = strlen(barr[num % 10]);
2: num = (int &) @0x7ffc447985bc: 32884
(gdb) c
Continuing.
[Switching to Thread 0x7f5c9cae2700 (LWP 97768)]
Breakpoint 2, inet::Server::__lambda1::operator() (__closure=0x6a9660) at /root/projects/gdbTest/inet/Server.cpp:55
55 int len = pData_->GetMemCount(0);
1: len = 21
(gdb) c
Continuing.
[Switching to Thread 0x7f5c9d2e3700 (LWP 97767)]
Breakpoint 1, inet::Server::__lambda0::operator() (__closure=0x6a93c0) at /root/projects/gdbTest/inet/Server.cpp:36
36 int len = strlen(barr[num % 10]);
2: num = (int &) @0x7ffc447985bc: 32885
(gdb) c
Continuing.
Breakpoint 1, inet::Server::__lambda0::operator() (__closure=0x6a93c0) at /root/projects/gdbTest/inet/Server.cpp:36
36 int len = strlen(barr[num % 10]);
2: num = (int &) @0x7ffc447985bc: 32886
(gdb) c
Continuing.
[Switching to Thread 0x7f5c9cae2700 (LWP 97768)]
Breakpoint 2, inet::Server::__lambda1::operator() (__closure=0x6a9660) at /root/projects/gdbTest/inet/Server.cpp:55
55 int len = pData_->GetMemCount(0);
1: len = 21
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
2: y num (cannot be evaluated in the current context)
1: y len
(gdb)
假如對線程中的數據操作達到某個條件感興趣,可以使用:
(gdb) b 61 if num == 3
Breakpoint 3 at 0x41802a: file /root/projects/gdbTest/inet/Server.cpp, line 61.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000417e3e in inet::Server::__lambda0::operator()() const at /root/projects/gdbTest/inet/Server.cpp:36
breakpoint already hit 5 times
2 breakpoint keep y 0x0000000000417fd6 in inet::Server::__lambda1::operator()() const at /root/projects/gdbTest/inet/Server.cpp:55
breakpoint already hit 3 times
3 breakpoint keep y 0x000000000041802a in inet::Server::__lambda1::operator()() const at /root/projects/gdbTest/inet/Server.cpp:61
stop only if num == 3
(gdb) c
Continuing.
[Switching to Thread 0x7f5c9d2e3700 (LWP 97767)]
Breakpoint 1, inet::Server::__lambda0::operator() (__closure=0x6a93c0) at /root/projects/gdbTest/inet/Server.cpp:36
36 int len = strlen(barr[num % 10]);
2: num = (int &) @0x7ffc447985bc: 32887
(gdb) c
Continuing.
[Switching to Thread 0x7f5c9cae2700 (LWP 97768)]
Breakpoint 3, inet::Server::__lambda1::operator() (__closure=0x6a9660) at /root/projects/gdbTest/inet/Server.cpp:61
61 std::cout << "dataparse tmp comData:" << tmp->len << std::endl;
1: len = 36
(gdb) display num
3: num = 3
(gdb)
如果只關心一次的情況可以使用臨時斷點:
先刪除原有斷點:
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000417e3e in inet::Server::__lambda0::operator()() const at /root/projects/gdbTest/inet/Server.cpp:36
breakpoint already hit 9 times
2 breakpoint keep y 0x0000000000417fd6 in inet::Server::__lambda1::operator()() const at /root/projects/gdbTest/inet/Server.cpp:55
breakpoint already hit 4 times
3 breakpoint keep y 0x000000000041802a in inet::Server::__lambda1::operator()() const at /root/projects/gdbTest/inet/Server.cpp:61
stop only if num == 3
breakpoint already hit 2 times
(gdb) delete 3
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000417e3e in inet::Server::__lambda0::operator()() const at /root/projects/gdbTest/inet/Server.cpp:36
breakpoint already hit 9 times
2 breakpoint keep y 0x0000000000417fd6 in inet::Server::__lambda1::operator()() const at /root/projects/gdbTest/inet/Server.cpp:55
breakpoint already hit 4 times
再重新使用臨時斷點:
(gdb) tb 61 if num == 3
Temporary breakpoint 4 at 0x41802a: file /root/projects/gdbTest/inet/Server.cpp, line 61.
(gdb) c
Continuing.
[Switching to Thread 0x7f5c9d2e3700 (LWP 97767)]
Breakpoint 1, inet::Server::__lambda0::operator() (__closure=0x6a93c0) at /root/projects/gdbTest/inet/Server.cpp:36
36 int len = strlen(barr[num % 10]);
2: num = (int &) @0x7ffc447985bc: 32891
(gdb) c
Continuing.
Breakpoint 1, inet::Server::__lambda0::operator() (__closure=0x6a93c0) at /root/projects/gdbTest/inet/Server.cpp:36
36 int len = strlen(barr[num % 10]);
2: num = (int &) @0x7ffc447985bc: 32892
(gdb) c
2: num = (int &) @0x7ffc447985bc: 32893
(gdb) c
Continuing.
[Switching to Thread 0x7f5c9cae2700 (LWP 97768)]
Temporary breakpoint 4, inet::Server::__lambda1::operator() (__closure=0x6a9660) at /root/projects/gdbTest/inet/Server.cpp:61
61 std::cout << "dataparse tmp comData:" << tmp->len << std::endl;
3: num = 3
1: len = 38
(gdb)
可以查看一下智能指針的數據內容:
(gdb) n
56 if (len > 0)
1: len = 42
(gdb) n
58 for (int num = 0; num < len; num++)
3: num = 41
1: len = 42
(gdb) n
60 std::shared_ptr<global::MemData> tmp = pData_->GetMemData(num, 0);
3: num = 0
1: len = 42
(gdb) p tmp
$3 = std::shared_ptr (count 1, weak 0) 0x7f5c98003518
(gdb) p tmp->len
$4 = 60
(gdb) p tmp->buf
$5 = "awhet45747476466&&***HJJKKTryrettruytritrkmb<>NNHGG$##@abce4", '\000' <repeats 39 times>
一個初步的GDB實戰項目就啟動了,靈活的應用各種命令和監控方式,來驗證和程序設計本身的目標是否吻合,下一步,就針對具體的數據流程,走一個完整的過程。