Android Native Framework gdb Tool

腳本使用方法

  • gdb_native.sh 228 adb1
  • gdb_native.sh 228
    • 其中228代表要調試進程的pid,必須指定;
    • adb1 指定你想使用的adb工具,也可以不指定adb。
#!/bin/bash
  PROJECT_ROOT=$(dirname $_)
  #set -x
  BIN_BIT=64   # BIN_BIT=64 when bin is 64bit version
  GDB=$PROJECT_ROOT/prebuilts/gdb/linux-x86/bin/gdb
  # GDB=$PROJECT_ROOT/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8/bin/arm-eabi-gdb
  # maybe gdbserver64, if process is 64bit version
  GDB_SERVER=gdbserver$BIN_BIT
  OUT=$PROJECT_ROOT/out/target/product/flounder

  usage () {
    echo -e "\033[;35m Usage : $0 228\033[0m"
    echo -e "\033[;35m Usage : $0 228 adb1 \033[0m"
  }
  if [ -n "$2" ] ;then
    aadb=$2
  else
    aadb=/usr/bin/adb
  fi
  if [ -n "$1" ] ;then
    process_pid=$1
  else
    process_pid=0
  fi
  ADB=$aadb
  GDB_PORT=5028

  # 0: setenforce 0
  $ADB root
  $ADB remount
  $ADB shell setenforce 0
  sleep 1

  if [[ $process_pid = 0 ]]; then
      echo -e "\033[;31merror: Process id must designated!!!\033[0m"
      usage
      exit 0
  else
      process_name=$($ADB shell ps $process_pid | grep $process_pid | awk -F '\/' '{print $4}')
  fi
  TARGET_NAME=$process_name  # process name
  TARGET_PID=$process_pid  # process id
  GDB_PARAMETER=/tmp/gdbinit.`whoami`
  echo -e "\033[;33m check target name($TARGET_NAME) pid($TARGET_PID) \033[0m"
  # kill old gdbserver
  oldgdbserver=`$ADB shell ps | grep "gdbserver" | awk '{ print $2 }'`
  if [[ 0$oldgdbserver != 0 ]]; then
      $ADB shell kill -9 $oldgdbserver
  fi

  # 1: bringup gdbserver and attach to host process for wait clent to connet me
  echo "1: $ADB shell $GDB_SERVER :$GDB_PORT --attach $TARGET_PID"
  $ADB shell $GDB_SERVER :$GDB_PORT --attach $TARGET_PID &

  # 2: 設置端口轉發
  # 表示通過adb映射tcp端口1234,命令中前面的是local的端口,后面的是remote的端口。
  echo "2: $ADB forward tcp:$GDB_PORT tcp:$GDB_PORT"
  $ADB forward tcp:$GDB_PORT tcp:$GDB_PORT
  sleep 3

  # 3: 啟動gdb,并傳入參數
  # echo "target remote:$GDB_PORT" > $GDB_PARAMETER
  # echo "file $OUT/system/bin/$TARGET_NAME" >> $GDB_PARAMETER
  # echo "set sysroot $OUT/symbols/" >> $GDB_PARAMETER
  # echo "set dir $PROJECT_ROOT" >> $GDB_PARAMETER

  echo "set solib-absolute-prefix $OUT/symbols/system/lib$BIN_BIT" > $GDB_PARAMETER
  echo "set sysroot $OUT/symbols/" >> $GDB_PARAMETER
  echo "set solib-search-path $OUT/symbols/system/lib$BIN_BIT/" >> $GDB_PARAMETER
  echo "target extended-remote :$GDB_PORT" >> $GDB_PARAMETER
  echo "3: $GDB -x $GDB_PARAMETER $OUT/symbols/system/bin/$TARGET_NAME"
  $GDB -x $GDB_PARAMETER $OUT/symbols/system/bin/$TARGET_NAME

擴展功能

到這里對于剛接觸gdb調試同學也有了入門的知識,對于gdb老手估計是要玩飛的節奏

但是這里要說一下,如果要調試的是framework相關的進程的native代碼,可能會受到system server的watchdog的影響,1分鐘沒有及時響應操作就會觸發watchdog而kill到system server進程,zygote也會跟著掛掉,這里有個小技巧可以用一下,就是在調試的過程中,如果需要耗時查看一些運行時狀態,可以先執行
adb shell am hang
防止超時重啟,查看完畢想要繼續執行,就Ctrl+c終止掉am hang即可繼續執行,后面就重復這個過程即可。
另外還有一種方式就是用Android Studio在線調試,把斷點加在watchdog里面,配置gdb native調試。

gdb命令說明

  • 顯示gdb命令幫助信息
help            顯示gdb命令種類
help subcommand      顯示subcommand的幫助信息
apropos word       搜索與word相關的命令
  • 顯示調試界面
ctrl + X + A
  • 設置斷點
b(break)     在函數或某一行處設置斷點 
如果只記得部分函的前綴,可以這樣:(gdb) b make_ <按TAB鍵>。 
break filename:linenum       在源文件filename的linenum行處停住 
break filename:function       在源文件filename的function函數的入口處停住 
break *address                       在程序運行的內存地址處停住 
break       break命令沒有參數時,指在下一條指令處停住 
break  …  If …           在條件成立時程序停住 
break thread threadnum       定義在線程threadnum上的斷點,如break BootAnimation.cpp:364 thread 28 if bartab > lim
  • 設置觀察點
watch expr       設置觀察點,當表達式expr的值變化時,程序停住
rwatch expr       設置觀察點,當表達式expr的值被讀時,程序停住
awatch expr       設置觀察點,當表達式expr的值被讀或寫時,程序停住
  • 設置捕捉點
catch       設置被調試程序捕捉點,當event發生時,程序停住 
catch catch [args]       捕捉一個C++捕捉到的異常 
catch throw [args]       捕捉一個C++拋出的異常 
catch syscall [args]       捕捉系統調用
  • 維護被調試程序斷點

condition N COND       修改斷點號為N的停止條件為COND

ignore N COUNT       忽略斷點號為N的停止條件COUNT次

clear [linenum|funname|*]       清除指定的行或函數斷點

d(delete) [breakpoints][range]          清除指定的斷點

disable [breakpoints] [range…]        禁用指定的斷點

enable [breakpoints] [range…]         啟用指定的斷點

  • 為停止點設定運行命令

commands N       調試程序在斷點號為N的斷點處停止后,執行命令 

執行命令 

end

  • 顯示被調試程序的信息
info subcommand       顯示被調試程序的某些信息,可用help info查看子命令。如: 

info breakpoints    [n]       顯示所有斷點(或斷點n)信息 

info watchpoints [n]       顯示所有觀察點(或觀察點n)信息 

info program       查看被調試程序的執行狀態 

info args          打印出當前函數的參數名及其值 

info locals       打印出當前函數中所有局部變量及其值 

info display       查看display設置的自動顯示的信息 

info frame       查看棧幀信息,包括程序語言

  • 運行及查看被調試信息

r(run)       運行被調試程序

c(continue)       從斷點出開始繼續執行直到結束或下一個斷點

s(step)       單步跟蹤,如果有函數調用,他會進入該函數。進入函數的前提是此函數被編譯有debug信息

n(next)       單步跟蹤,如果有函數調用,他不會進入該函數

p(print)       打印表達式的值 

可以查看全局變量(所有文件可見)、靜態全局變量(當前文件可見)、局部變量(當前Scope可見) 

p file::var       查看文件file中的變量var 

p func::var       查看函數file中的變量var 

p start@len       查看一段連續的內存空間的值,“@”的左邊是第一個內存的地址的值,“@”的右邊則你你想查看內存的長度,如: 

int array = (int ) malloc (len * sizeof (int)); 

p *array@len 

p/format expr       按指定的格式顯示表達式expr(format:x, d, f, c, u, o, t, a)

display[/fmt] expr       程序停下來后就會顯示expr的值

undisplay/delete displaynum/disable displaynum/enable displaynum

bt          查看當前函數調用堆棧信息

f(frame)       查看當前棧層信息,包括棧的層編號、當前的函數名、函數參數值、函數所在文件及行號和函數執行到的語句

finish       運行程序,直到當前函數完成返回

u(until)       運行程序直到退出循環體

  • 顯示源代碼

l(list)       列出具體的函數或代碼行 

list       顯示當前行后面的源程序 

list -         顯示當前行前面的源程序 

list +       顯示當前行后面的源程序 

list linenum       顯示程序第linenum行的周圍的源程序 

list file:filenum       顯示文件file中的filenum行 

list file:func       顯示文件file中的函數func 

list funcname       顯示函數名為function的函數的源程序,如list android::BootAnimation::movie

  • 搜索源代碼

forward-search reg       利用正則表達式前向搜索源碼

search reg       利用正則表達式前向搜索源碼

reverse-search reg       利用正則表達式在全部源碼中進行搜索

  • 設置被調試程序參數/gdb配置

set subcommand       設置gdb環境變量,可以使用help set查看set子命令。如: 

set args       設置被調試程序運行參數 

set directories       設置源文件搜索路徑,多個使用“:”分割 

set solib-search-path       設置符號表搜索路徑 

set environment varname [=value]       設置環境變量。如:set env USER=llj 

set listsize num       設置一次顯示源代碼的行數 

set step-mode on       打開step-mode模式,于是,在進行單步跟蹤時,程序不會因為沒有debug信息而不停住。這個參數有很利于查看機器碼 

set print address on       打開地址輸出, 當程序顯示函數信息時,GDB會顯出函數的參數地址 

set print array on       打開數組顯示,打開后當數組顯示時,每個元素占一行,如果不打開的話,每個元素則以逗號分隔 

set print elements num       設置顯示數組元素的最大個數 

set print null-stop on/off       如果打開了這個選項,那么當顯示字符串時,遇到結束符則停止顯示 

set print pretty on/off       打開后gdb顯示結構體時會比較漂亮 

set print sevenbit-strings       設置字符顯示,是否按“/nnn”的格式顯示 

set print union on/off       設置顯示結構體時,是否顯式其內的聯合體數據

show subcommand       顯示調試器的信息,使用help show查看子命令。如: 

show environment [varname]       查看環境變量 

show listsize       顯示當前listsize的設置 

show directories       顯示定義了的源文件搜索路徑 

show language       查看gdb當前的語言環境

  • 其他

q(quit)       退出gdb

handle          處理信號

  • shell命令

此外gdb中可以執行shell命令,使用SHELL環境變量定義的可執行程序來執行shell命令,常用的命令如下:

show environment SHELL       查看shell執行程序

make       重新編譯程序,相當于shell make

cd       必變工作目錄,相當于shell cd

pwd       查看當前工具目錄,相當于shell pwd

  • 調整程序線路

     一旦使用GDB掛上被調試程序,當程序運行起來后,你可以根據自己的調試思路來動態地在GDB中更改當前被調試程序的運行線路或是其變量的值,這個強大的功能能夠讓你更好的調試你的程序,比如,你可以在程序的一次運行中走遍程序的所有分支。
    
  • 修改變量的值


print x = 4       C/C++語法,把變量x的值修改為4 

set var width=10       用gdb命令將參數width值修改為10

  • 跳轉執行

jump +num       當前運行點向下偏移num行開始執行 

jump linenum       從當前調試文件的linenum行開始執行 

jump file:linenum       從file的linenum行開始執行

-產生信號量


singal SIGNAL       發送信號SINGAL給被調試程序

-強制函數返回


return       強制函數返回,忽略未執行的語句 

return result       強制函數返回結果result,忽略未執行的語句

-強制調用函數


call func       調用當前程序中的函數 

print func       調用當前程序中的函數

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,757評論 25 708
  • 時光流轉,愿你安好。
    莊德坤閱讀 170評論 0 0
  • 模塊與包 控制模塊被全部導入的內容 在模塊中以下劃線命名的變量或函數是不會被導入的 在模塊中使用all來控制導入的...
    buildbody_coder閱讀 385評論 0 0
  • 每日必讀:輕熟原則 早起儀式=反思回顧+想做事情列表 晚間儀式=陪家人閑話+反思+坐享 日省——每日復盤,a Ti...
    wenzi2507閱讀 168評論 0 0