如何使用jdb調試android的java程式

來源:互聯網
上載者:User

如何使用jdb調試android的java程式

習慣了gdb,總覺得eclipse太過臃腫,各種不爽。看到李先靜寫了一篇“用jdb/jdbshell調試android程式“(http://www.limodev.cn/blog/archives/1281),用了下,感覺比eclipse舒服多了。jdb的命令有那麼點彆扭,先靜寫了個jdbshell,加入了命令曆史和命令別名(幾個常用的gdb命令)。

下面是一個簡單的how to,以調試browser應用為例

1)下載jdbshell並編譯

www.limodev.cn/blog/?dl_name=jdbshell.tar.gz

因為我基本上每次一開始都要執行threads變數,所以我在開始wile迴圈前加了一句話

else
{
close(parent_to_child[0]);
                write(parent_to_child[1], "threads\n",strlen("threads\n")); 
while(1)
{
int i = 0;
line = readline ("");

                       ...

                  }

        }

                        

編譯後將jdbshell放到~/bin,或者將目錄加到PATH裡

出現無法開啟readline.h的話,安裝libreadline6和libreadline6-dev

2)仿照gdbclient,在build/envsetup.sh中加入jdbclient函數

function jdbclient()
{
    local MY_SRC_PATH="$1"
    if [ "$MY_SRC_PATH" ] ; then
        MY_SRC_PATH=$1
        echo $MY_SRC_PATH
    else
        echo "ROOT" $OUR_ROOT
        MY_SRC_PATH="app_process"
    fi

    local PORT="$2"
    if [ "$PORT" ] ; then
        PORT=$2
    else
        PORT=":9000"
    fi

    local PID
    local PROG="$3"
    if [ "$PROG" ] ; then
        PID=`pid $3`
        echo tcp$PORT jdwp$PID
        adb forward "tcp$PORT" "jdwp:$PID"
        echo jdbshell -sourcepath $MY_SRC_PATH -attach localhost$PORT 
        jdbshell -sourcepath $MY_SRC_PATH -attach localhost$PORT 
        sleep 2
    else
        echo ""
        echo "please specify app you want to debug:"
        echo ""
    fi
}

3)啟動android模擬器,運行瀏覽器

4)jdbclient packets/app/Browser/src/ :9000 browser
第一個參數是你要load進來的代碼的地址,如果你要load多個代碼(調試的時候可以看),可以
export DEBUG_SRC_PATH=
然後
jdbclient $DEBUG_SRC_PATH :9000 browser

第二個參數是attach連接埠,如果9000有在用,可以用其他連接埠
第三個參數是要調試的應用,指令碼裡面根據
pid browser來取得進程id,所以你要保證
adb shell ps |grep browser
能夠看到對應的進程

比如我在~/.bashrc裡面,設定了DEBUG_SRC_PATH

export ANDROID_SRC=/home/tom/work/gingerbread
export DEBUG_SRC_PATH=$ANDROID_SRC/frameworks/base/opengl/java:$ANDROID_SRC/frameworks/base/awt/java:$ANDROID_SRC/frameworks/base/core/java:$ANDROID_SRC/frameworks/base/location/java:$ANDROID_SRC/frameworks/base/sax/java:$ANDROID_SRC/frameworks/base/graphics/java:$ANDROID_SRC/frameworks/base/telephony/java:$ANDROID_SRC/frameworks/base/services/java:$ANDROID_SRC/frameworks/base/media/java:$ANDROID_SRC/frameworks/base/wifi/java:$ANDROID_SRC/frameworks/base/im/java:$ANDROID_SRC/dalvik/libcore/suncompat/src/main/java:$ANDROID_SRC/dalvik/libcore/nio_char/src/main/java:$ANDROID_SRC/dalvik/libcore/nio_char/src/main/java/java:$ANDROID_SRC/dalvik/libcore/security-kernel/src/main/java:$ANDROID_SRC/dalvik/libcore/security-kernel/src/main/java/java:$ANDROID_SRC/dalvik/libcore/security/src/main/java:$ANDROID_SRC/dalvik/libcore/security/src/main/java/java:$ANDROID_SRC/dalvik/libcore/archive/src/main/java:$ANDROID_SRC/dalvik/libcore/archive/src/main/java/java:$ANDROID_SRC/dalvik/libcore/awt-kernel/src/main/java:$ANDROID_SRC/dalvik/libcore/awt-kernel/src/main/java/java:$ANDROID_SRC/dalvik/libcore/luni/src/main/java:$ANDROID_SRC/dalvik/libcore/luni/src/main/java/java:$ANDROID_SRC/dalvik/libcore/math/src/main/java:$ANDROID_SRC/dalvik/libcore/math/src/main/java/java:$ANDROID_SRC/dalvik/libcore/x-net/src/main/java:$ANDROID_SRC/dalvik/libcore/openssl/src/main/java:$ANDROID_SRC/dalvik/libcore/dalvik/src/main/java:$ANDROID_SRC/dalvik/libcore/auth/src/main/java:$ANDROID_SRC/dalvik/libcore/concurrent/src/main/java:$ANDROID_SRC/dalvik/libcore/concurrent/src/main/java/java:$ANDROID_SRC/dalvik/libcore/sql/src/main/java:$ANDROID_SRC/dalvik/libcore/sql/src/main/java/java:$ANDROID_SRC/dalvik/libcore/prefs/src/main/java:$ANDROID_SRC/dalvik/libcore/prefs/src/main/java/java:$ANDROID_SRC/dalvik/libcore/xml/src/main/java:$ANDROID_SRC/dalvik/libcore/text/src/main/java:$ANDROID_SRC/dalvik/libcore/text/src/main/java/java:$ANDROID_SRC/dalvik/libcore/luni-kernel/src/main/java:$ANDROID_SRC/dalvik/libcore/luni-kernel/src/main/java/java:$ANDROID_SRC/dalvik/libcore/regex/src/main/java:$ANDROID_SRC/dalvik/libcore/regex/src/main/java/java:$ANDROID_SRC/dalvik/libcore/nio/src/main/java:$ANDROID_SRC/dalvik/libcore/nio/src/main/java/java:$ANDROID_SRC/dalvik/libcore/json/src/main/java:$ANDROID_SRC/dalvik/libcore/crypto/src/main/java:$ANDROID_SRC/dalvik/libcore/icu/src/main/java:$ANDROID_SRC/dalvik/libcore/annotation/src/main/java:$ANDROID_SRC/dalvik/libcore/annotation/src/main/java/java:$ANDROID_SRC/dalvik/libcore/junit/src/main/java:$ANDROID_SRC/dalvik/libcore/logging/src/main/java:$ANDROID_SRC/dalvik/libcore/logging/src/main/java/java:$ANDROID_SRC/dalvik/libcore-disabled/instrument/src/main/java:$ANDROID_SRC/dalvik/libcore-disabled/instrument/src/main/java/java:$ANDROID_SRC/dalvik/libcore-disabled/sound/src/main/java:packages/apps/Browser/src/

5)顯示如下資訊,說明調試器啟動
Set uncaught java.lang.Throwable
Set deferred uncaught java.lang.Throwable
Initializing jdb ...
Group system:
  (java.lang.Thread)0xc14050d0c0                  <6> Compiler             cond. waiting
  (java.lang.Thread)0xc14050cf50                  <4> Signal Catcher       cond. waiting
  (java.lang.Thread)0xc14050cea8                  <3> GC                   cond. waiting
  (java.lang.Thread)0xc14050cdf0                  <2> HeapWorker           cond. waiting
Group main:
  (java.lang.Thread)0xc14001f1a8                  <1> main                 running
  (java.lang.Thread)0xc140562ad8                  <21> AsyncTask #5        cond. waiting
  (android.os.HandlerThread)0xc1405528f8          <20> WebViewWorkerThread running
  (android.net.http.ConnectionThread)0xc14053a780 <19> http3               cond. waiting
  (android.net.http.ConnectionThread)0xc14053a5a8 <18> http2               cond. waiting
  (android.net.http.ConnectionThread)0xc140530f90 <17> http1               cond. waiting
  (android.net.http.ConnectionThread)0xc140530da0 <16> http0               cond. waiting
  (java.lang.Thread)0xc14058c008                  <15> Thread-18           running
  (java.lang.Thread)0xc140593370                  <14> AsyncTask #4        cond. waiting
  (java.lang.Thread)0xc140595dd0                  <13> AsyncTask #3        cond. waiting
  (java.lang.Thread)0xc14058f9f0                  <12> AsyncTask #2        cond. waiting
  (java.lang.Thread)0xc14055a820                  <11> WebViewCoreThread   running
  (java.lang.Thread)0xc140591bc8                  <10> AsyncTask #1        cond. waiting
  (java.lang.Thread)0xc140589710                  <9> CookieSyncManager    running
  (java.lang.Thread)0xc14050f288                  <8> Binder Thread #2     running
  (java.lang.Thread)0xc14050e900                  <7> Binder Thread #1     running

6)選擇感興趣的線程
大部分應用跑在main線程裡面,browser也不例外
命令 thread 線程ID

> thread 0xc14001f1a8
<1> main[1] 

7)掛起線程
命令 suspend 線程ID
<1> main[1] suspend 0xc14001f1a8

8)設定斷點
命令:
stop at <類>:<行號> 或
stop in <類>.<方法名>[(參數類型,...)]

<1> main[1] stop at com.android.browser.BrowserActivity:2689
Set breakpoint com.android.browser.BrowserActivity:2689

這個地方要寫類名稍微麻煩一點,哪位大蝦可以轉化成像gdb那樣,直接檔案名稱?

9)繼續執行
命令 c(ont)

<1> main[1] c

10)點擊網頁中的某一個連結
就會看到程式在BrowserActivty:2689(shouldOverideUrlLoading)處斷住了
此時可以看堆棧
命令:bt/wherei
<1> main[1]bt
  [1] com.android.browser.BrowserActivity.shouldOverrideUrlLoading (BrowserActivity.java:2,689), pc = 8
  [2] com.android.browser.Tab$2.shouldOverrideUrlLoading (Tab.java:552), pc = 44
  [3] android.webkit.CallbackProxy.uiOverrideUrlLoading (CallbackProxy.java:216), pc = 19
  [4] android.webkit.CallbackProxy.handleMessage (CallbackProxy.java:323), pc = 347
  [5] android.os.Handler.dispatchMessage (Handler.java:99), pc = 20
  [6] android.os.Looper.loop (Looper.java:123), pc = 75
  [7] android.app.ActivityThread.main (ActivityThread.java:3,683), pc = 31
  [8] java.lang.reflect.Method.invokeNative (native method)
  [9] java.lang.reflect.Method.invoke (Method.java:507), pc = 18
  [10] com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:839), pc = 11
  [11] com.android.internal.os.ZygoteInit.main (ZygoteInit.java:597), pc = 84
  [12] dalvik.system.NativeStart.main (native method)

看代碼 
命令:l(ist)
<1> main[1] l
2,685            }
2,686        }
2,687    
2,688        boolean shouldOverrideUrlLoading(WebView view, String url) {
2,689 =>         if (url.startsWith(SCHEME_WTAI)) {
2,690                // wtai://wp/mc;number
2,691                // number=string(phone-number)
2,692                if (url.startsWith(SCHEME_WTAI_MC)) {
2,693                    Intent intent = new Intent(Intent.ACTION_VIEW,
2,694                            Uri.parse(WebView.SCHEME_TEL +

看變數
命令:print
<1> main[1] print url
 url = "http://m.baidu.com/img?tn=bdidxiphone&ssid=0&from=844b&bd_page_type=1&uid=wiaui_1320452293_7438&pu=sz%401320_480&itj=41"

繼續執行
s(tep) – 執行當前行
step up – 執行到當前方法返回到其調用程式
s(tep)i – 執行當前指令
n(ext) – 跳過一行(跨過調用)
c(ont) – 從斷點處繼續執行

不說了,help是一種美德
<1> main[1] help
** command list **
connectors                -- list available connectors and transports in this VM

run [class [args]]        -- start execution of application's main class

threads [threadgroup]     -- list threads
thread <thread id>        -- set default thread
suspend [thread id(s)]    -- suspend threads (default: all)
resume [thread id(s)]     -- resume threads (default: all)
where [<thread id> | all] -- dump a thread's stack
wherei [<thread id> | all]-- dump a thread's stack, with pc info
up [n frames]             -- move up a thread's stack
down [n frames]           -- move down a thread's stack
kill <thread id> <expr>   -- kill a thread with the given exception object
interrupt <thread id>     -- interrupt a thread

print <expr>              -- print value of expression
dump <expr>               -- print all object information
eval <expr>               -- evaluate expression (same as print)
set <lvalue> = <expr>     -- assign new value to field/variable/array element
locals                    -- print all local variables in current stack frame

classes                   -- list currently known classes
class <class id>          -- show details of named class
methods <class id>        -- list a class's methods
fields <class id>         -- list a class's fields

threadgroups              -- list threadgroups
threadgroup <name>        -- set current threadgroup

stop in <class id>.<method>[(argument_type,...)]
                          -- set a breakpoint in a method
stop at <class id>:<line> -- set a breakpoint at a line
clear <class id>.<method>[(argument_type,...)]
                          -- clear a breakpoint in a method
clear <class id>:<line>   -- clear a breakpoint at a line
clear                     -- list breakpoints
catch [uncaught|caught|all] <class id>|<class pattern>
                          -- break when specified exception occurs
ignore [uncaught|caught|all] <class id>|<class pattern>
                          -- cancel 'catch' for the specified exception
watch [access|all] <class id>.<field name>
                          -- watch access/modifications to a field
unwatch [access|all] <class id>.<field name>
                          -- discontinue watching access/modifications to a field
trace [go] methods [thread]
                          -- trace method entries and exits.
                          -- All threads are suspended unless 'go' is specified
trace [go] method exit | exits [thread]
                          -- trace the current method's exit, or all methods' exits
                          -- All threads are suspended unless 'go' is specified
untrace [methods]         -- stop tracing method entrys and/or exits
step                      -- execute current line
step up                   -- execute until the current method returns to its caller
stepi                     -- execute current instruction
next                      -- step one line (step OVER calls)
cont                      -- continue execution from breakpoint

list [line number|method] -- print source code
use (or sourcepath) [source file path]
                          -- display or change the source path
exclude [<class pattern>, ... | "none"]
                          -- do not report step or method events for specified classes
classpath                 -- print classpath info from target VM

monitor <command>         -- execute command each time the program stops
monitor                   -- list monitors
unmonitor <monitor#>      -- delete a monitor
read <filename>           -- read and execute a command file

lock <expr>               -- print lock info for an object
threadlocks [thread id]   -- print lock info for a thread

pop                       -- pop the stack through and including the current frame
reenter                   -- same as pop, but current frame is reentered
redefine <class id> <class file name>
                          -- redefine the code for a class

disablegc <expr>          -- prevent garbage collection of an object
enablegc <expr>           -- permit garbage collection of an object

!!                        -- repeat last command
<n> <command>             -- repeat command n times
# <command>               -- discard (no-op)
help (or ?)               -- list commands
version                   -- print version information
exit (or quit)            -- exit debugger

<class id>: a full class name with package qualifiers
<class pattern>: a class name with a leading or trailing wildcard ('*')
<thread id>: thread number as reported in the 'threads' command
<expr>: a Java(tm) Programming Language expression.
Most common syntax is supported.

Startup commands can be placed in either "jdb.ini" or ".jdbrc"
in user.home or user.dir

如果要看別名映射,在終端執行

tom@tom-laptop:~/work/gingerbread$ jdbshell
usage: jdbshell [jdb args]
example: ./jdbshell -sourcepath $ANDROID_SRC_PATH -attach 6107
command alias:
c -- cont
l -- list
n -- next
r -- run
s -- step
si -- stepi
f -- step up
bt -- wherei

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.