1 | @c |
---|
2 | @c RTEMS Remote Debugger Server Specifications |
---|
3 | @c |
---|
4 | @c Written by: Eric Valette <valette@crf.canon.fr> |
---|
5 | @c Emmanuel Raguet <raguet@crf.canon.fr> |
---|
6 | @c |
---|
7 | @c |
---|
8 | @c $Id$ |
---|
9 | @c |
---|
10 | |
---|
11 | @chapter A Rapid Tour of GDB Internals |
---|
12 | |
---|
13 | To help the reader to understand what needs to be implemented, we |
---|
14 | will present briefly how GDB works regardless if the target is local or remote. |
---|
15 | A debugger is a tool which enables control of the execution of software on a |
---|
16 | target system. In most of cases, the debugger connects to a target system, attaches |
---|
17 | a process, inserts breakpoints and resumes execution. Then the normal execution |
---|
18 | is completely events driven (process execution stopped due to a breakpoint, |
---|
19 | process fault, single-step,...) coming from the debuggee. It can also directly |
---|
20 | access some parts of the target processor context (registers, data memory, code |
---|
21 | memory,...) and change their content. Native GDB debugger can just be seen as |
---|
22 | special cases where the host and the target are on the same machine and GDB |
---|
23 | can directly access the target system debug API. |
---|
24 | |
---|
25 | |
---|
26 | In our case, the host and the target are not on the same machine and |
---|
27 | an Ethernet link is used to communicate between the different machines. Because |
---|
28 | GDB needs to be able to support various targets (including Unix core file, ...), |
---|
29 | each action that needs to be performed on the debuggee is materialized by a |
---|
30 | field of the following @emph{targets_op}s structure : |
---|
31 | |
---|
32 | @example |
---|
33 | struct target_ops |
---|
34 | @{ |
---|
35 | char *to_shortname; /* Name this target type */ |
---|
36 | char *to_longname; /* Name for printing */ |
---|
37 | char *to_doc; /* Documentation. Does not include trailing |
---|
38 | newline, and starts with a one-line descrip- |
---|
39 | tion (probably similar to to_longname). */ |
---|
40 | void (*to_open) PARAMS ((char *, int)); |
---|
41 | void (*to_close) PARAMS ((int)); |
---|
42 | void (*to_attach) PARAMS ((char *, int)); |
---|
43 | void (*to_detach) PARAMS ((char *, int)); |
---|
44 | void (*to_resume) PARAMS ((int, int, enum target_signal)); |
---|
45 | int (*to_wait) PARAMS ((int, struct target_waitstatus *)); |
---|
46 | void (*to_fetch_registers) PARAMS ((int)); |
---|
47 | void (*to_store_registers) PARAMS ((int)); |
---|
48 | void (*to_prepare_to_store) PARAMS ((void)); |
---|
49 | |
---|
50 | /* Transfer LEN bytes of memory between GDB address MYADDR and |
---|
51 | target address MEMADDR. If WRITE, transfer them to the target, else |
---|
52 | transfer them from the target. TARGET is the target from which we |
---|
53 | get this function. |
---|
54 | |
---|
55 | Return value, N, is one of the following: |
---|
56 | |
---|
57 | 0 means that we can't handle this. If errno has been set, it is the |
---|
58 | error which prevented us from doing it (FIXME: What about bfd_error?). |
---|
59 | |
---|
60 | positive (call it N) means that we have transferred N bytes |
---|
61 | starting at MEMADDR. We might be able to handle more bytes |
---|
62 | beyond this length, but no promises. |
---|
63 | |
---|
64 | negative (call its absolute value N) means that we cannot |
---|
65 | transfer right at MEMADDR, but we could transfer at least |
---|
66 | something at MEMADDR + N. */ |
---|
67 | |
---|
68 | int (*to_xfer_memory) PARAMS ((CORE_ADDR memaddr, char *myaddr, |
---|
69 | int len, int write, |
---|
70 | struct target_ops * target)); |
---|
71 | |
---|
72 | void (*to_files_info) PARAMS ((struct target_ops *)); |
---|
73 | int (*to_insert_breakpoint) PARAMS ((CORE_ADDR, char *)); |
---|
74 | int (*to_remove_breakpoint) PARAMS ((CORE_ADDR, char *)); |
---|
75 | void (*to_terminal_init) PARAMS ((void)); |
---|
76 | void (*to_terminal_inferior) PARAMS ((void)); |
---|
77 | void (*to_terminal_ours_for_output) PARAMS ((void)); |
---|
78 | void (*to_terminal_ours) PARAMS ((void)); |
---|
79 | void (*to_terminal_info) PARAMS ((char *, int)); |
---|
80 | void (*to_kill) PARAMS ((void)); |
---|
81 | void (*to_load) PARAMS ((char *, int)); |
---|
82 | int (*to_lookup_symbol) PARAMS ((char *, CORE_ADDR *)); |
---|
83 | void (*to_create_inferior) PARAMS ((char *, char *, char **)); |
---|
84 | void (*to_mourn_inferior) PARAMS ((void)); |
---|
85 | int (*to_can_run) PARAMS ((void)); |
---|
86 | void (*to_notice_signals) PARAMS ((int pid)); |
---|
87 | int (*to_thread_alive) PARAMS ((int pid)); |
---|
88 | void (*to_stop) PARAMS ((void)); |
---|
89 | enum strata to_stratum; |
---|
90 | struct target_ops |
---|
91 | *DONT_USE; /* formerly to_next */ |
---|
92 | int to_has_all_memory; |
---|
93 | int to_has_memory; |
---|
94 | int to_has_stack; |
---|
95 | int to_has_registers; |
---|
96 | int to_has_execution; |
---|
97 | struct section_table |
---|
98 | *to_sections; |
---|
99 | struct section_table |
---|
100 | *to_sections_end; |
---|
101 | int to_magic; |
---|
102 | /* Need sub-structure for target machine related rather than comm related? */ |
---|
103 | @}; |
---|
104 | @end example |
---|
105 | |
---|
106 | This structure contains pointers to functions (in C++, this would |
---|
107 | be called a virtual class). Each different target supported by GDB has its own |
---|
108 | structure with the relevant implementation of the functions (some functions |
---|
109 | may be not implemented). When a user connects GDB to a target via the ``target'' |
---|
110 | command, GDB points to the structure corresponding to this target. Then the |
---|
111 | user can attache GDB to a specific task via the ``attach'' command. We have |
---|
112 | therefore identified two steps to begin a remote debug session : |
---|
113 | |
---|
114 | @enumerate |
---|
115 | @item the choice of the target type (in our case RTEMS), |
---|
116 | @item the choice of what to debug (entire system, specific task,...), |
---|
117 | @end enumerate |
---|
118 | Note that in the case of natives debugger, the choice of the target is implicitly |
---|
119 | performed by commands like @b{run}, @b{attach}, @b{detach}. Several |
---|
120 | figures will now be described showing the main steps of a debug session. |
---|
121 | |
---|
122 | @c XXX figure reference |
---|
123 | Figure @b{Debug session initialization} explains how the debugger connects to the target |
---|
124 | : |
---|
125 | |
---|
126 | @enumerate |
---|
127 | @item The debugger opens a connection to the target. The word ``connection'' |
---|
128 | doesn't only mean Ethernet or serial link connection but all the ways by which |
---|
129 | a process can communicate with another one (direct function call, messages mailbox, |
---|
130 | ...), |
---|
131 | @item The targets checks if it can accept or reject this connection, |
---|
132 | @item If the connection is accepted, the host ``attaches'' the process, |
---|
133 | @item the target stops the process, notifies a child's stop to the host |
---|
134 | and waits for command, |
---|
135 | @item the host can ask information about the debugged process (name, registers,...) |
---|
136 | or perform some action like setting breakpoints, ... |
---|
137 | @end enumerate |
---|
138 | |
---|
139 | @c XXX figure reference |
---|
140 | Figure @b{Breakpoint and process execution} explains how the debugger manages the |
---|
141 | breakpoints and controls the execution of a process : |
---|
142 | |
---|
143 | @enumerate |
---|
144 | @item The host asks the debuggee what is the opcode at the concerned address |
---|
145 | in order for GDB to memorize this instruction, |
---|
146 | @item the host sends a CONTINUE command : it asks the target to write the |
---|
147 | ``DEBUG'' opcode (for example, the INTEL ``DEBUG'' opcode is INT3 which |
---|
148 | generate a breakpoint trap) instead of the debugged opcode. |
---|
149 | @item then the host waits for events, |
---|
150 | @item after the change of instruction, the target resumes the execution |
---|
151 | of the debuggee, |
---|
152 | @item when the ``DEBUG'' opcode is executed, the breakpoint exception |
---|
153 | handler is executed and it notifies the host that the process is stopped. Then |
---|
154 | it waits for commands (if no command is sent after a certain amount of time, |
---|
155 | the connection will be closed by the target). |
---|
156 | @item the host asks the target to re-write the right opcode instead of the |
---|
157 | ''DEBUG'' opcode and then can ask information |
---|
158 | @end enumerate |
---|
159 | |
---|
160 | @c XXX figure reference |
---|
161 | Figure @b{Breakpoint and process execution} also shows the case of other ``CONTINUE'' |
---|
162 | commands (remember that the ``DEBUG'' opcode has been replaced by the right |
---|
163 | instruction): |
---|
164 | |
---|
165 | @enumerate |
---|
166 | @item Host sends first a ``single step'' command to execute the debugged |
---|
167 | instruction, |
---|
168 | @item It then waits for ``single step`` exception event, |
---|
169 | @item the target, once the single step executed, calls the debug exception |
---|
170 | handler. It notifies the host that execution is suspended and wait for commands. |
---|
171 | @item the host asks the target to re-write the ``DEBUG'' opcode (breakpoint |
---|
172 | trap) instead of the debugged one. |
---|
173 | @item then the host sends a ``CONTINUE'' command in order the target to |
---|
174 | resume the process execution to the next breakpoint. |
---|
175 | @end enumerate |
---|
176 | |
---|
177 | @c XXX figure reference |
---|
178 | Figure @b{Detach a process and close a connection} explains how the debugger disconnects from |
---|
179 | a target : |
---|
180 | |
---|
181 | @enumerate |
---|
182 | @item the host sends a detach command to the target. |
---|
183 | @item the target detaches the concerned process, notifies the detachment |
---|
184 | and resumes the process execution. |
---|
185 | @item once notified, the host sends a close connection command. |
---|
186 | @item the target closes the connection. |
---|
187 | @end enumerate |
---|
188 | These 3 examples show that the mains actions that are performed by |
---|
189 | the host debugger on the target are only simple actions which look like : |
---|
190 | |
---|
191 | @itemize @bullet |
---|
192 | @item read/write code, |
---|
193 | @item read/write data, |
---|
194 | @item read/write registers, |
---|
195 | @item manage exceptions, |
---|
196 | @item send/receive messages to/from the host. |
---|
197 | @end itemize |
---|
198 | |
---|
199 | |
---|
200 | @c |
---|
201 | @c Debug session initialization Figure |
---|
202 | @c |
---|
203 | |
---|
204 | @ifset use-ascii |
---|
205 | @example |
---|
206 | @group |
---|
207 | XXXXX reference it in the previous paragraph |
---|
208 | XXXXX insert seg_init.eps |
---|
209 | XXXXX Caption Debug session initialization |
---|
210 | @end group |
---|
211 | @end example |
---|
212 | @end ifset |
---|
213 | |
---|
214 | @ifset use-tex |
---|
215 | @example |
---|
216 | @group |
---|
217 | XXXXX reference it in the previous paragraph |
---|
218 | XXXXX insert seg_init.eps |
---|
219 | XXXXX Caption Debug session initialization |
---|
220 | @end group |
---|
221 | @end example |
---|
222 | @end ifset |
---|
223 | |
---|
224 | @c @image{seg_init} |
---|
225 | |
---|
226 | @ifset use-html |
---|
227 | @c <IMG SRC="seg_init.jpg" WIDTH=500 HEIGHT=600 ALT="Debug session initialization"> |
---|
228 | @html |
---|
229 | <IMG SRC="seg_init.jpg" ALT="Debug session initialization"> |
---|
230 | @end html |
---|
231 | @end ifset |
---|
232 | |
---|
233 | |
---|
234 | @c |
---|
235 | @c Breakpoint and process execution Figure |
---|
236 | @c |
---|
237 | |
---|
238 | @ifset use-ascii |
---|
239 | @example |
---|
240 | @group |
---|
241 | XXXXX reference it in the previous paragraph |
---|
242 | XXXXX insert seq_break.eps |
---|
243 | XXXXX Caption Breakpoint and process execution |
---|
244 | @end group |
---|
245 | @end example |
---|
246 | @end ifset |
---|
247 | |
---|
248 | @ifset use-tex |
---|
249 | @example |
---|
250 | @group |
---|
251 | XXXXX reference it in the previous paragraph |
---|
252 | XXXXX insert seq_break.eps |
---|
253 | XXXXX Caption Breakpoint and process execution |
---|
254 | @end group |
---|
255 | @end example |
---|
256 | @end ifset |
---|
257 | |
---|
258 | @c @image{seq_break} |
---|
259 | |
---|
260 | @ifset use-html |
---|
261 | @c <IMG SRC="seq_break.jpg" WIDTH=500 HEIGHT=600 ALT="Breakpoint and process execution"> |
---|
262 | @html |
---|
263 | <IMG SRC="seq_break.jpg" ALT="Breakpoint and process execution"> |
---|
264 | @end html |
---|
265 | @end ifset |
---|
266 | |
---|
267 | |
---|
268 | |
---|
269 | @c |
---|
270 | @c Detach a process and close a connection Figure |
---|
271 | @c |
---|
272 | |
---|
273 | @ifset use-ascii |
---|
274 | @example |
---|
275 | @group |
---|
276 | XXXXX reference it in the previous paragraph |
---|
277 | XXXXX insert seq_detach.eps |
---|
278 | XXXXX Caption Detach a process and close a connection |
---|
279 | @end group |
---|
280 | @end example |
---|
281 | @end ifset |
---|
282 | |
---|
283 | @ifset use-tex |
---|
284 | @example |
---|
285 | @group |
---|
286 | XXXXX reference it in the previous paragraph |
---|
287 | XXXXX insert seq_detach.eps |
---|
288 | XXXXX Caption Detach a process and close a connection |
---|
289 | @end group |
---|
290 | @end example |
---|
291 | @end ifset |
---|
292 | |
---|
293 | @c @image{seq_detach} |
---|
294 | |
---|
295 | @ifset use-html |
---|
296 | @c <IMG SRC="seq_detach.jpg" WIDTH=500 HEIGHT=600 ALT="Detach a process and close a connection"> |
---|
297 | @html |
---|
298 | <IMG SRC="seq_detach.jpg" ALT="Detach a process and close a connection"> |
---|
299 | @end html |
---|
300 | @end ifset |
---|
301 | |
---|
302 | |
---|
303 | |
---|
304 | |
---|