aboutsummaryrefslogtreecommitdiff
path: root/en/devices/tech/debug/gdb.html
blob: 49d62aa3f0b6f65689d58a126ace82669695dbdb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
<html devsite>
  <head>
    <title>Using GDB</title>
    <meta name="project_path" value="/_project.yaml" />
    <meta name="book_path" value="/_book.yaml" />
  </head>
  <body>
  <!--
      Copyright 2017 The Android Open Source Project

      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      See the License for the specific language governing permissions and
      limitations under the License.
  -->


<p>The GNU Project debugger (GDB) is a commonly used Unix debugger. This page
details using <code>gdb</code> to debug Android apps and processes for platform
developers. For third-party app development, see
<a class="external"
href="https://developer.android.com/studio/debug/index.html">Debug Your
App</a>.</p>

<h2 id="prerequisites">Prerequisites</h2>

<p>To use GDB for debugging apps and processes:</p>

  <ul>
    <li>Set up environment with <code>envsetup.sh</code>
    <li>Run the <code>lunch</code> command</li>
  </ul>

<p>For more help with setting up your environment, see
  <a href="/setup/build/building#initialize">Preparing to Build</a>.</p>

<h2 id=running>Debugging running apps or processes</h2>

<p>To connect to an already-running app or native daemon, use
<code>gdbclient.py</code> with a PID. For example, to debug the process with PID
1234, run:</p>

<pre class="devsite-terminal devsite-click-to-copy">
gdbclient.py -p 1234
</pre>

<p>The script sets up port forwarding, starts the appropriate
<code>gdbserver</code> on the device, starts the appropriate <code>gdb</code> on
the host, configures <code>gdb</code> to find symbols, and connects
<code>gdb</code> to the remote <code>gdbserver</code>.</p>

<aside class="note"><strong>Note:</strong> In Android 6 and lower the script was
a shell script called <code>gdbclient</code> instead of a Python script called
<code>gdbclient.py</code>.</aside>

<h2 id=starts>Debugging native process startup</h2>

<p>To debug a process as it starts, use <code>gdbserver</code> or
<code>gdbserver64</code>. For a 64-bit executable:</p>

<pre class="devsite-terminal devsite-click-to-copy">
adb shell gdbserver64 :5039 /system/bin/<var>MY_TEST_64_BIT_APP</var>
</pre>

<p>For a 32-bit executable:</p>

<pre class="devsite-terminal devsite-click-to-copy">
adb shell gdbserver :5039 /system/bin/<var>MY_TEST_32_BIT_APP</var>
</pre>

<p>Example output:</p>
<pre class="devsite-click-to-copy">
Process <var>MY_TEST_64_BIT_APP</var> created; pid = 3460
Listening on port 5039
</pre>

<p>Next, identify the application PID from the <code>gdbserver</code> output and
use it in another terminal window:</p>

<pre class="devsite-terminal devsite-click-to-copy">
gdbclient.py -p <var>APP_PID</var>
</pre>

<p>Finally, enter <strong>continue</strong> at the <code>gdb</code> prompt.</p>

<p class="note"><strong>Note:</strong> If you specify the wrong
<code>gdbserver</code>, you'll get an unhelpful error message (such as
"<code>Reply contains invalid hex digit 59</code>").</p>

<h2 id="app-startup">Debugging app startup</h2>

<p>Sometimes you want to debug an app as it starts, such as when there's a crash
and you want to step through code to see what happens <em>before</em> the crash.
<a href="#running">Attaching</a> works in some cases, but in other cases is
impossible because the app crashes before you can attach. The
<code>logwrapper</code> approach (used for <code>strace</code> and
<code>valgrind</code>) does not always work because the app might not have
permissions to open a port, and <code>gdbserver</code> inherits that
restriction.</p>

<p>To debug app startup, use the developer options in Settings to instruct
the app to wait for a Java debugger to attach:</p>

<ol>
<li>Go to <em>Settings > Developer options > Select debug app</em> and choose
your app from the list, then press <strong>Wait for debugger</strong>.</li>

<li>Start the app, either from the launcher or by using the command line to run:
<pre class="devsite-terminal devsite-click-to-copy">
adb shell am start -a android.intent.action.MAIN -n <var>APP_NAME</var>/.<var>APP_ACTIVITY</var>
</pre></li>

<li>Wait for the app to load and a dialog to appear telling you the app is
waiting for a debugger.</li>

<li>Attach <code>gdbserver</code>/<code>gdbclient</code> normally, set
breakpoints, then continue the process.</li></ol>

<p>To let the app actually run, attach a Java Debug Wire Protocol (JDWP)
debugger such as Java Debugger (jdb):</p>
<pre class="devsite-click-to-copy">
<code class="devsite-terminal">adb forward tcp:12345 jdwp:<var>XXX</var>  # (Where XXX is the pid of the debugged process.)</code>
<code class="devsite-terminal">jdb -attach localhost:12345</code>
</pre>

<h2 id=crash>Debugging apps or processes that crash</h2>

<p>If you want <code>debuggerd</code> to suspend crashed processes so you can
attach <code>gdb</code>, set the appropriate property:</p>

<pre class="devsite-click-to-copy">
# Android 7.0 Nougat and later.
<code class="devsite-terminal">adb shell setprop debug.debuggerd.wait_for_gdb true</code>
</pre>

<pre class="devsite-click-to-copy">
# Android 6.0 Marshmallow and earlier.
<code class="devsite-terminal">adb shell setprop debug.db.uid 999999</code>
</pre>

<p>At the end of the usual crash output, <code>debuggerd</code> provides
instructions on how to connect <code>gdb</code> using the command:
<pre class="devsite-terminal devsite-click-to-copy">
gdbclient.py -p <var>PID</var>
</pre>

<h2 id=symbols>Debugging without symbols</h2>

<p>For 32-bit ARM, if you don’t have symbols, <code>gdb</code> can get confused
about the instruction set it is disassembling (ARM or Thumb). To specify the
instruction set chosen as the default when symbol information is missing, set
the following property:</p>

<pre class="devsite-terminal devsite-click-to-copy">
set arm fallback-mode arm  # or thumb
</pre>

  </body>
</html>