導航:首頁 > 編程系統 > linuxgdb進程

linuxgdb進程

發布時間:2023-03-10 01:33:46

linux的調試工具gdb怎麼重新開始運行程序

gdb好像沒有重新運行程序的命令吧,如果需要重新運行程序,先quit退出gdb,再重新調試不就行了。

② 嵌入式Linux的GDB遠程調試如何實現呢

遠程調試環境由宿主機GDB和目標機調試
stub共同構成,兩者通過串口或TCP連接。使用GDB標准遠程串列協議協同工作,實現對目標機上的系統內核和上層應用的監控和調試功能。調試stub
是嵌入式系統中的一段代碼,作為宿主機GDB和目標機調試程序間的一個媒介而存在。就目前而言,嵌入式Linux系統中,主要有三種遠程調試方法,分別適用於不同場合的調試工作:
用ROM Monitor調試目標機程序
用KGDB調試系統內核
用gdbserver調試用戶空間程序。
這三種調試方法的區別主要在於:目標機遠程調試stub的存在形式的不同,而其設計思路和實現方法則是大致相同的,而我們最常用的是調試應用程序,就是採用gdb+gdbserver的方式進行調試。在很多情況下,用戶需要對一個應用程序進行反復調試,特別是復雜的程序,採用GDB方法調試,由於嵌入式系統資源有限性,一般不能直接在目標系統上進行調試,通常采gdb+gdbserver的方式進行調試。Gdbserver在目標系統中運行,gdb則在宿主機上運行。
下載需要用的的軟體包。
一.編譯安裝arm-linux-gdb
<1>#tar jxvf gdb-7.3.tar.bz2
<2>#cd gdb-7.3
<3>#./configure--target=arm-linux --enable-sim --prefix=/usr/local/bin
<4>#make
<5>#make install
二.編譯安裝gdbserver
<1>#cd gdb-7.3/gdb/gdbserver
<2>#./configure --target=arm-linux--host=arm-linux
<3>#make
這樣在gdb-7.3/gdb/gdbserver目錄下就生成了一個gdbserver可執行文件,拷貝到目標開發板上.
三.測試arm-linux-gdb + gdbserver
<1>在超級終端輸入:
#./gdbserver 192.168.100.1:2345 hello
[192.168.100.1為pc機ip地址,2345為監聽埠,hello為待調試程序
這樣在開發板上可以看到如下提示信息:
Process wpa_cli created; pid = 730
Listening on port 2345
表示gdbserver 成功運行等待客戶端的連接信息
<2>在pc機上輸入:
#arm-linux-gdb hello
然後在GDB界面輸入:
#target remote 192.168.100.2:2345
[192.168.100.2為開發板ip地址,2345為開發版監聽埠]
這樣在開發板上可以看到如下提示信息:
Remote debugging from host 192.168.100.1
表示gdbserver成功運行並且建立連接關系,等待客戶端的調試信息。

③ 請教linux下用戶態進程調度問題

在進行Linux系統操作的時候,有時候會遇到一次用戶態進程死循環,即系統反應遲鈍、進程掛死等問題,那麼遇到這些問題又該如何解決呢?下面小編就給大家介紹下一次用戶態進程死循環的問題該如何處理。
Linux下如何處理一次用戶態進程死循環問題
1、問題現象
業務進程(用戶態多線程程序)掛死,操作系統反應遲鈍,系統日誌沒有任何異常。從進程的內核態堆棧看,看似所有線程都卡在了內核態的如下堆棧流程中:
[root@vmc116 ~]# cat /proc/27007/task/11825/stack
[《ffffffff8100baf6》] retint_careful+0x14/0x32
[《ffffffffffffffff》] 0xffffffffffffffff
2、問題分析
1)內核堆棧分析
從內核堆棧看,所有進程都阻塞在 retint_careful上,這個是中斷返回過程中的流程,代碼(匯編)如下:
entry_64.S
代碼如下:
ret_from_intr:
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
decl PER_CPU_VAR(irq_count)
/* Restore saved previous stack */
popq %rsi
CFI_DEF_CFA rsi,SS+8-RBP /* reg/off reset after def_cfa_expr */
leaq ARGOFFSET-RBP(%rsi), %rsp
CFI_DEF_CFA_REGISTER rsp
CFI_ADJUST_CFA_OFFSET RBP-ARGOFFSET
。。。
retint_careful:
CFI_RESTORE_STATE
bt $TIF_NEED_RESCHED,%edx
jnc retint_signal
TRACE_IRQS_ON
ENABLE_INTERRUPTS(CLBR_NONE)
pushq_cfi %rdi
SCHEDULE_USER
popq_cfi %rdi
GET_THREAD_INFO(%rcx)
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
jmp retint_check
這其實是用戶態進程在用戶態被中斷打斷後,從中斷返回的流程,結合retint_careful+0x14/0x32,進行反匯編,可以確認阻塞的點其實就在
SCHEDULE_USER
這其實就是調用schele()進行調度,也就是說當進程走到中斷返回的流程中時,發現需要調度(設置了TIF_NEED_RESCHED),於是在這里發生了調度。
有一個疑問:為什麼在堆棧中看不到schele()這一級的棧幀呢?
因為這里是匯編直接調用的,沒有進行相關棧幀壓棧和上下文保存操作。
2)進行狀態信息分析
從top命令結果看,相關線程實際一直處於R狀態,CPU幾乎完全耗盡,而且絕大部分都消耗在用戶態:
[root@vmc116 ~]# top
top - 09:42:23 up 16 days, 2:21, 23 users, load average: 84.08, 84.30, 83.62
Tasks: 1037 total, 85 running, 952 sleeping, 0 stopped, 0 zombie
Cpu(s): 97.6%us, 2.2%sy, 0.2%ni, 0.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 32878852k total, 32315464k used, 563388k free, 374152k buffers
Swap: 35110904k total, 38644k used, 35072260k free, 28852536k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
27074 root 20 0 5316m 163m 14m R 10.2 0.5 321:06.17 z_itask_templat
27084 root 20 0 5316m 163m 14m R 10.2 0.5 296:23.37 z_itask_templat
27085 root 20 0 5316m 163m 14m R 10.2 0.5 337:57.26 z_itask_templat
27095 root 20 0 5316m 163m 14m R 10.2 0.5 327:31.93 z_itask_templat
27102 root 20 0 5316m 163m 14m R 10.2 0.5 306:49.44 z_itask_templat
27113 root 20 0 5316m 163m 14m R 10.2 0.5 310:47.41 z_itask_templat
25730 root 20 0 5316m 163m 14m R 10.2 0.5 283:03.37 z_itask_templat
30069 root 20 0 5316m 163m 14m R 10.2 0.5 283:49.67 z_itask_templat
13938 root 20 0 5316m 163m 14m R 10.2 0.5 261:24.46 z_itask_templat
16326 root 20 0 5316m 163m 14m R 10.2 0.5 150:24.53 z_itask_templat
6795 root 20 0 5316m 163m 14m R 10.2 0.5 100:26.77 z_itask_templat
27063 root 20 0 5316m 163m 14m R 9.9 0.5 337:18.77 z_itask_templat
27065 root 20 0 5316m 163m 14m R 9.9 0.5 314:24.17 z_itask_templat
27068 root 20 0 5316m 163m 14m R 9.9 0.5 336:32.78 z_itask_templat
27069 root 20 0 5316m 163m 14m R 9.9 0.5 338:55.08 z_itask_templat
27072 root 20 0 5316m 163m 14m R 9.9 0.5 306:46.08 z_itask_templat
27075 root 20 0 5316m 163m 14m R 9.9 0.5 316:49.51 z_itask_templat
。。。
3)進程調度信息
從相關線程的調度信息看:
[root@vmc116 ~]# cat /proc/27007/task/11825/schedstat
15681811525768 129628804592612 3557465
[root@vmc116 ~]# cat /proc/27007/task/11825/schedstat
15682016493013 129630684625241 3557509
[root@vmc116 ~]# cat /proc/27007/task/11825/schedstat
15682843570331 129638127548315 3557686
[root@vmc116 ~]# cat /proc/27007/task/11825/schedstat
15683323640217 129642447477861 3557793
[root@vmc116 ~]# cat /proc/27007/task/11825/schedstat
15683698477621 129645817640726 3557875
發現相關線程的調度統計一直在增加,說明相關線程一直是在被調度運行的,結合其狀態也一直是R,推測很可能在用戶態發生了死循環(或者非睡眠死鎖)。
這里又有問題:為什麼從top看每個線程的CPU佔用率只有10%左右,而不是通常看到的死循環進程導致的100%的佔用率?
因為線程數很多,而且優先順序都一樣,根據CFS調度演算法,會平均分配時間片,不會讓其中一個線程獨佔CPU。結果為多個線程間輪流調度,消耗掉了所有的cpu。。
另一個問題:為什麼這種情況下,內核沒有檢測到softlockup?
因為業務進程的優先順序不高,不會影響watchdog內核線程(最高優先順序的實時線程)的調度,所以不會產生softlockup的情況。
再一個問題:為什麼每次查看線程堆棧時,總是阻塞在retint_careful,而不是其它地方?
因為這里(中斷返回的時候)正是調度的時機點,在其它時間點不能發生調度(不考慮其它情況~),而我們查看線程堆棧的行為,也必須依賴於進程調度,所以我們每次查看堆棧時,正是查看堆棧的進程(cat命令)得到調度的時候,這時正是中斷返回的時候,所以正好看到的阻塞點為retint_careful。
4)用戶態分析
從上面的分析看,推測應該是用戶態發生了死鎖。
用戶態確認方法:
部署debug信息,然後gdb attach相關進程,確認堆棧,並結合代碼邏輯分析。
最終確認該問題確為用戶態進程中產生了死循環。

④ 深度linux V20如何安裝gdb,如何用gdb調試程序、用gdb設置斷點刪除斷點、gdb自動顯示變數值、看內存值

因本人通過幾個小時的時間才解決這個問題,希望我的答案能節省大部分初學者在gdb上的時間。我也是今天才接觸gdb,以下是有關深度linux V20的gdb調試問題的初步總結:
安裝gdb方式,sudo apt-get install gdb ,有ok點擊ok安裝,直到安裝結束。
gcc -g aa.c之後才能調試a.out文件。(aa.c表示你的源文件)
用法gdb a.out或者gdb進入後file a.out
l N是查看N行附近的代碼,直接l是顯示接下去的代碼。r運行過程中遇到斷點,按l則顯示斷點附近代碼。
l 函數名是查看函數名里邊的代碼
q退出調試。
p 變數,查看變數即時值。
r運行。
n單步執行。
s單步執行-進入函數。
c連續多步運行,直到下個斷點(循環的下一次斷點)暫停。
b N第N行設置斷點。
b 函數名,在函數名的入口處設置斷點。
b 文件名:行號,在指定文件名行號設置斷點。其中文件名是源文件的文件名。
(條件斷點)b 行號 if 變數==N,表示該行號的斷點必須滿足變數==N的條件下才停下來。
ignore 斷點編號 N,表示該斷點編號在接下來的運行過程中忽略N次,即第N+1次該斷點才會停下來。
info break顯示全部斷點。簡寫i b
delete 1-3刪除編號為1到3的斷點。簡寫 d 1-3。d 4隻刪除編號為4的斷點。
delete break刪除所有斷點。無法簡寫
clear 20刪除20行斷點。
運行中disable break n 禁用斷點號為n的斷點。enable break n 使能斷點為n的斷點號重新啟用。其中break可以簡寫為b
display {var1,var2,var3}自動顯示var1~3變數的值。要刪除display則用delete display N,N表示display的編號,如果不加N則表示刪除全部的display。如果要自動顯示數組內容,用display 數組名。注意:display需要r之後才能設置。
watch {var1,var2,var3}自動跟蹤改變的值,只要有改變才顯示watch。要刪除watch,用d N,N代表watch編號,用i b可以查看該編號。注意:watch需要r之後才能設置。
gdb死循環程序按鍵盤ctrl+c可結束程序
****************
要查看內存地址的內容用x /nfu 內存地址。以下是n、f、u的解釋

其中n表示要顯示多少個內存單元。

f表示顯示方式, 可取如下值
x 按十六進制格式顯示變數。
d 按十進制格式顯示變數。
u 按十進制格式顯示無符號整型。
o 按八進制格式顯示變數。
t 按二進制格式顯示變數。
a 按十六進制格式顯示變數。
i 指令地址格式
c 按字元格式顯示變數。
f 按浮點數格式顯示變數。

u表示一個地址單元的長度
b表示單位元組,
h表示雙位元組,
w表示四位元組,
g表示八位元組
*****************

⑤ linux中怎麼使用gdb調試進程有dettach

在2.5.60版Linux內核及以後,GDB對使用fork/vfork創建子進程的程序提供了follow-fork-mode選項來支持多進程調試。 follow-fork-mode的用法為: set follow-fork-mode [parentchild] parent: fork之後繼續調試父進程,子進程不受影響。 child: fork之後調試子進程,父進程不受影響。 因此如果需要調試子進程,在啟動gdb後: (gdb) set follow-fork-mode child並在子進程代碼設置斷點。 此外還有detach-on-fork參數,指示GDB在fork之後是否斷開(detach)某個進程的調試,或者都交由GDB控制: set detach-on-fork [onoff] on: 斷開調試follow-fork-mode指定的進程。 off: gdb將控制父進程和子進程。follow-fork-mode指定的進程將被調試,另一個進程置於暫停(suspended)狀態。 注意,最好使用GDB 6.6或以上版本,如果你使用的是GDB6.4,就只有follow-fork-mode模式。 follow-fork-mode/detach-on-fork的使用還是比較簡單的,但由於其系統內核/gdb版本限制,我們只能在符合要求的系統上才能使用。而且,由於follow-fork-mode的調試必然是從父進程開始的,對於fork多次,以至於出現孫進程或曾孫進程的系統,例如上圖3進程系統,調試起來並不方便。 Attach子進程 眾所周知,GDB有附著(attach)到正在運行的進程的功能,即attach <pid>命令。因此我們可以利用該命令attach到子進程然後進行調試。 例如我們要調試某個進程RIM_Oracle_Agent.9i,首先得到該進程的pid [root@tivf09 tianq]# ps -efgrep RIM_Oracle_Agent.9i nobody 6722 6721 0 05:57 ? 00:00:00 RIM_Oracle_Agent.9i root 7541 27816 0 06:10 pts/3 00:00:00 grep -i rim_oracle_agent.9i通過pstree可以看到,這是一個三進程系統,oserv是RIM_Oracle_prog的父進程,RIM_Oracle_prog又是RIM_Oracle_Agent.9i的父進程。 [root@tivf09 root]# pstree -H 6722通過 pstree 察看進程 啟動GDB,attach到該進程 用 GDB 連接進程 現在就可以調試了。一個新的問題是,子進程一直在運行,attach上去後都不知道運行到哪裡了。有沒有辦法解決呢? 一個辦法是,在要調試的子進程初始代碼中,比如main函數開始處,加入一段特殊代碼,使子進程在某個條件成立時便循環睡眠等待,attach到進程後在該代碼段後設上斷點,再把成立的條件取消,使代碼可以繼續執行下去。 至於這段代碼所採用的條件,看你的偏好了。比如我們可以檢查一個指定的環境變數的值,或者檢查一個特定的文件存不存在。以文件為例,其形式可以如下: void debug_wait(char *tag_file) { while(1) { if (tag_file存在) 睡眠一段時間; else break; } }當attach到進程後,在該段代碼之後設上斷點,再把該文件刪除就OK了。當然你也可以採用其他的條件或形式,只要這個條件可以設置/檢測即可。 Attach進程方法還是很方便的,它能夠應付各種各樣復雜的進程系統,比如孫子/曾孫進程,比如守護進程(daemon process),唯一需要的就是加入一小段代碼。 GDB wrapper 很多時候,父進程 fork 出子進程,子進程會緊接著調用 exec族函數來執行新的代碼。對於這種情況,我們也可以使用gdb wrapper 方法。它的優點是不用添加額外代碼。 其基本原理是以gdb調用待執行代碼作為一個新的整體來被exec函數執行,使得待執行代碼始終處於gdb的控制中,這樣我們自然能夠調試該子進程代碼。 還是上面那個例子,RIM_Oracle_prog fork出子進程後將緊接著執行RIM_Oracle_Agent.9i的二進制代碼文件。我們將該文件重命名為RIM_Oracle_Agent.9i.binary,並新建一個名為RIM_Oracle_Agent.9i的shell腳本文件,其內容如下: [root@tivf09 bin]# mv RIM_Oracle_Agent.9i RIM_Oracle_Agent.9i.binary [root@tivf09 bin]# cat RIM_Oracle_Agent.9i #!/bin/sh gdb RIM_Oracle_Agent.binary當fork的子進程執行名為RIM_Oracle_Agent.9i的文件時,gdb會被首先啟動,使得要調試的代碼處於gdb控制之下。

⑥ linux中如何更改程序的父進程

getppid()
獲取父進程
id,
getpid()
獲取當前進程
id.
比如
int
main()
{
int
pid
=
fork();
if
(pid
==
0)
{
//
child
printf
("parentid
is
%d\n",
getppid());
}
esle
{
printf("i'm
parent,
id
%d\n",
getpid());
wait(null);
}
return
0;
}
再就是程序編譯沒錯,但是運行時出現「實時專信號
2」
沒有源碼,誰也幫不上屬你。
你可以用
gdb去調試。

閱讀全文

與linuxgdb進程相關的資料

熱點內容
專題學習網站源碼 瀏覽:163
jsphead什麼 瀏覽:88
gps串口數據怎麼發送 瀏覽:968
win10文件主頁共享查看 瀏覽:411
中國聯通有哪些app是免流的 瀏覽:176
邊做邊保存的文件找不到了 瀏覽:858
win10照片應用文件夾名稱 瀏覽:966
編程如何解決資金的原子性 瀏覽:638
如何製作廣角鏡頭矯正文件 瀏覽:513
在網頁開發中應該選用哪個資料庫 瀏覽:742
iphone5移動卡貼 瀏覽:990
電腦文件的格式 瀏覽:127
extjs的xtype 瀏覽:959
suse11iso文件要u盤安裝 瀏覽:153
如何將報表統計數據轉化為圖形 瀏覽:444
如何寄快遞材料文件 瀏覽:265
java構造方法private 瀏覽:475
手機文件找回恢復 瀏覽:516
word怎麼把u盤里的文件拔掉 瀏覽:976
港版蘋果用的插排 瀏覽:1000

友情鏈接