source: rtems/doc/rgdb_specs/daemon.t @ c6af99c3

4.104.114.84.9
Last change on this file since c6af99c3 was c6af99c3, checked in by Ralf Corsepius <ralf.corsepius@…>, on May 22, 2003 at 8:00:44 AM

2003-05-22 Ralf Corsepius <corsepiu@…>

  • daemon.t: Reflect c/src/exec having moved to cpukit.
  • Property mode set to 100644
File size: 19.3 KB
Line 
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 RTEMS Debugger Server Daemon
12
13We will describe in this section how this debugger server will be
14implemented on RTEMS environment. Our initial target is based on Intel Pentium
15and we will use an Ethernet link to communicate between the host and the target.
16
17The RTEMS remote debugger will be composed by several tasks and exception
18handlers :
19
20@itemize @bullet
21@item an initialization task which opens the sockets and runs the SUN RPC
22server. This task will also connect the interrupt handlers and launch the communication
23task
24@item a communication task which receives the SUN RPC commands, executes
25them and sends the result to the GDB client,
26@item A debuggee event management task which waits for events. We need a different
27task than the command management task in order to be able to still accept commands
28while no event has yet occurred for the debuggee. An example could be a continue
29command from GDB and then hitting to DEL key to see what is currently going
30on on the target side because an expected breakpoint is not caught...
31@item a debug exception handler which manages the hardware breakpoint and
32single step exceptions (INT 1 on Intel x86),
33@item a breakpoint exception handler which manages the software breakpoints
34exceptions (INT 3 on Intel x86),
35@item a default exception handler used to catch every possible errors make on the
36target system,
37@end itemize
38
39@c XXX figure reference
40@c XXX references to other sections
41Figure @b{remote debugger tasks and handlers} represents these
42different tasks and handlers. The synchronization between the different task
43and exception handlers will be described below in the section
44@b{Synchronization Among Tasks and Exception Handlers}.
45Some open issues we have faced for a prototype implementation are described
46in the section @b{Open Issues}. The temporary workaround we chose are described
47in chapter @b{Workarounds for Open Issues in Prototype}.
48
49
50@section The INITIALIZATION task
51
52This is the task that must be executed at the boot phase of RTEMS.
53It initializes the debug context. It must :
54
55@itemize @bullet
56@item open the UDP sockets,
57@item run the SUN RPC server main loop,
58@item create the COMMAND MANAGEMENT task,
59@item connect the DEBUG EXCEPTION handler,
60@item connect the SOFTWARE BREAKPOINT handler,
61@item delete itself.
62@end itemize
63If an error occurs at any step of the execution, the connections established
64before the error will be closed, before the initialization task deletes itself.
65
66
67@section The COMMAND_MNGT task
68
69This task is in charge of receiving the SUN RPC messages and executing
70the associated commands. This task must have an important priority because it
71must be executed each time a command message comes from the debugger. It must
72be executed even if one or both exception handlers are executed. But the COMMAND
73MANAGEMENT task must not block the TCP/IP module without which no message can
74be received.
75
76When not executing a command, this task is waiting for a SUN RPC message
77on the primary port. This idle state blocks the task, so the other active tasks
78can run. Once a message comes from Ethernet via the primary port, the COMMAND
79MANAGEMENT task wakes up and receives the message which is a request from GDB.
80This request is sent to the SUN RPC server code which extracts the command and
81its arguments, executes it and, if needed, sends a result to GDB. After having
82performed these actions, the task sleeps, waiting for another message.
83
84A particular case is the reception of the ATTACH command : in this
85case the COMMAND_MNGT task creates the EVENT_MNGT task described below before
86going to wait on UDP socket again.
87
88
89@section The EVENT_MNGT task
90
91This task is in charge of managing events happening on the debuggee such as
92breakpoint, exceptions. This task does a basic simple loop waiting for event
93on a synchronization variable. It is waken up by exception handlers code. It
94then signals GDB that an event occurred and then go sleeping again as further
95requests will be processed by the COMMAND_MNGT task.
96
97
98@section The DEBUG EXCEPTION handler
99
100This handler is connected to the DEBUG exception (INT 1 on Intel ix86).
101This exception is entered when :
102
103@itemize @bullet
104@item executing a single-step instruction,
105@item hardware breakpoint condition is true,
106@end itemize
107These events will be treated by the debugger because they are the
108primary event used when debugging a software for instruction stepping. In both
109cases, the DEBUG EXCEPTION handler code is executed. Please note that the execution
110context of the exception handler is the supervisor stack of the task that generated
111the exception. This implies:
112
113@itemize @bullet
114@item We may sleep in this context,
115@item We have as many possible execution context for the DEBUG EXCEPTION handler as
116we need to,
117@item When we enter the high level exception handler code, a normalized exception
118context has been pushed on the system stack and a pointer to this context is
119available as the first argument (cf cpukit/score/cpu/i386/cpu.c for more
120details),
121@end itemize
122First the exception handler wakeup the EVENT_MNGT task. Then it will
123cause the faulting thread to sleep on a synchronization object. As soon as GDB
124receives the event notifying that the debuggee status has changed, it will start
125sending requests to get the debuggee status (registers set, faulty task id,
126...). These requests are handled by the COMMAND MANAGEMENT task. When this task
127receive a PTRACE_CONT command it will resume the execution of the task that
128caused the exception by doing a V on the synchronization object.
129
130
131@section The BREAKPOINT EXCEPTION handler
132
133This handler is connected to the BREAKPOINT exception (INT3 on Intel
134Ix86). Each time the debugger wants to place a software breakpoint in the debuggee,
135a debuggee opcode is temporarily replaced by an instruction causing BREAKPOINT
136exception (the ``INT 3'' instruction on Intel ix86). When ``INT 3'' is executed,
137the BREAKPOINT handler is executed. Otherwise, the exception processing is the
138same than the one described in previous section.
139
140
141@section Synchronization Among Tasks and Exception Handlers
142
143The previous chapters have presented a simplified and static view of the various
144tasks and exceptions handlers. This chapter is more focussed on synchronization
145requirements about the various pieces of code executed when RGDBSD is operating.
146
147
148@subsection Implicit Synchronization Using Task Priorities
149
150This chapter is relevant on Uniprocessor System (UP) only. However, it will
151also list the requirements for explicit synchronization on Multi-processor Systems
152(MP). Below are the task priorities sorted by high priority. They are not supposed
153to be equal :
154
155@enumerate
156@item Network Input Task. This is the highest priority task. This can be regarded
157as a software interrupt task for FreeBSD code,
158@item RGDBSD command task. As this task waits on UDP sockets, it shall not prevent
159the previous task from running. As the main debug entry point, it should preempt
160any other task in the system,
161@item RGDBSD event task. This task should preempt any task but the two mentionned
162before to signal a debug event to GDB. The command task shall be able to preempt
163this task for emergency command such as DEL, or REBOOT,
164@item Applications tasks (task we are able to debug),
165@end enumerate
166
167Using theses priorities eliminates the need for adding more synchronization
168objects in the next section. My belief is that symmetric MP support will require
169more important change in the RTEMS than RGDBSD itself like multiple scheduler
170queues, task to processor binding for non symmetric IO, use a different implementation
171for @emph{task_disable_preemption}, ...
172
173
174@subsection Explicit Synchronization
175
176This chapter will describe the synchronization variables that need to be implemented
177in order to sequence debug events in a way that is compatible with what GDB
178code expects. The root of the problem is that GDB code mainly expects that once
179a debug event has occurred on the debuggee, the entire debuggee is frozen and
180no other event will occur before the CONTINUE command is issued. This behavior
181is hard to achieve in our case as once we hit a breakpoint, only the task that
182hits the breakpoint will be asleep on a synchronization object. Other tasks
183may hit other breakpoints while we are waiting commands from GDB generating
184potential unexpected events. There is a solutions if RGDBSD itself use RTEMS
185threads to fix this problem by creating a task that loops forever at a priority
186superior to any debugged task but below RGDBSD task priorities. Unfortunately
187this will not work for the case we use the nano-kernel implementation and we
188think it is better to study synchronization problems now. We also expects that
189multi-thread debug support hardening in GDB will remove some event serializations
190requirements. Here is the list of synchronization variables we plan to use and
191their usage. They are all regular semaphores. They are not binary semaphores
192because the task that does V is not the task that has done the P.
193
194@itemize @bullet
195@item @emph{WakeUpEventTask} : used by exception handler code to wake up the EVENT_MNGT
196task by doing a V operation on this object. When target code is running normally
197the EVENT_MNGT task sleeps due to a P operation on this semaphore,
198@item @emph{SerializeDebugEvent} : used to serialize events in a way compatible to
199what GDB expects. Before doing a V operation on @emph{WakeUpEventTask}, the
200exception handler does a P on this semaphore to be sure processing of another
201exception is not in progress. Upon reception of a CONTINUE command, the COMMAND_MNGT
202task will issue a V operation so that the exception code can wake up EVENT_MNGT
203task using the mechanism described above,
204@item @emph{RestartFromException} : (in fact one semaphore per task) used by exception
205handling code to put a faulty task to sleep once it has generated an exception
206by doing a P operation on this semaphore. In the case the exception was generated
207due to a breakpoint, GDB command will modify back the BREAKPOINT opcode to the
208original value before doing the CONTINUE command. This command will perform
209a V on this semaphore. In the case it is a real non restartable exception (faulty
210memory reference via invalid pointer for example), GDB will not allow to restart
211the program avoiding any loop. So not special analysis of cause of exception
212is foreseen as far as RGDBSD code is concerned,
213@end itemize
214
215@section Open Issues
216
217Here are some problems we have faced while implementing our prototype :
218
219@table @b
220@item [Protected ReadMem/WriteMem (I1)]:
221A GDB user can request to see the content
222of a corrupted pointer. The request PEEK_DATA will be performed by the COMMAND_MNGT
223task. It shall not enter the default exception handler set by RGDBSD or it will
224cause a dead lock in the RGDBSD code. Replacing the default exception vector
225before calling @b{readMem/writeMem} can be temporarily sufficient but :
226
227@itemize @bullet
228@item It will never work on MP system as it will rely on task priorities to insure
229that other task will not cause exceptions while we have removed the default
230exception handler,
231
232@item This feature should not be usable in RGDBSD only but also by an embedded debugger
233that may run without any task. It is also unavoidable in case of protected memory
234and in this case no priority mechanism can be used,
235
236@item In the case of using RGDBSD code on a dedicated nano kernel, this code will
237be called from interrupt level and we need a way to be sure we can debug other
238interrupts that may also cause exceptions,
239@end itemize
240
241@item [ATTACH Command Implementation (I2)]:
242After the @emph{target rtems symbolic_ip_target_name}
243command, the normal operation is to issue an @emph{attach lid} command where
244@emph{lid} represents a valid execution context. For Unix this is a process
245id, for other multi-tasking system this is the id of a thread. After the attach
246command, GDB expects to be waken up in the same manner as it is for normal events.
247Once waken up it expects to have a complete register context available and also
248that the target task is in a stopped state and that it can restart it using
249the regular CONTINUE command. In RTEMS there is a way to get force a thread
250to become inactive via @emph{rtems_task_suspend} but no way to get the full
251registers set for the thread. A partial context can be retrieved from the task
252@emph{Registers} data structure. On the other hand, relying on @emph{rtems_task_suspend}
253will be a problem for the nano-kernel implementation.
254
255@item [Stopping Target System (I3)]:
256Allthough it might not be obvious, most of the
257actions made by a GDB user assume the target is not running. If you modify a
258variable via the @emph{set variable = value} command you expect that the value
259is the one you have put when restarting. If a still running task modifies the
260same value in the mean time, this may be false. On the other hand, stopping
261all the tasks on the target system impose to have a very deep knowledge of the
262system. Using an interrupt driven RGDBSD, may facilitate the implementation
263on the nano-kernel.
264
265@item [Getting Tasks Contexts (I4)]:
266As previously mentionned there is no way to get
267tasks execution contexts via the RTEMS API. This is needed when debugging for
268example via this classical sequence :
269
270@enumerate
271
272@item @emph{(gdb) target rtems symbolic_ip_target_name}
273
274@item @emph{(gdb) info threads <=} get a thread list on screen
275
276@item @emph{(gdb)} @emph{attach thread_id} <= thread_id is one of the thread in
277the list
278
279@item @emph{(gdb) b a_function_of_interest }
280
281@item @emph{(gdb) continue}
282
283@item @emph{(gdb)} @emph{backtrace} <= print the call stack on the screen once we
284have hit the breakpoint
285
286@item @emph{(gdb) thread target another_thread_li <=} change implicit current thread
287value for gdb commands
288
289@item @emph{(gdb)} @emph{backtrace <=} should print the backtrace for the chosen thread
290@end enumerate
291In our execution model, we have a valid context only for the threads that hits
292the breakpoint as it has been pushed by the exception handler code. The other
293thread is still running and during the various RPC requesting memory access,
294it even changes as the COMMAND_MNGT thread is going to sleep. So the backtrace
295command will fail. We must find a way to make this work as it is very usefull
296when debugging multi-threaded programs,
297
298
299@item [Backtrace Stop convention (I5)]:
300The backtrace command on RTEMS task does not
301gracefully terminate as GDB does not find some backtrace termination condition
302it expects.
303@end table
304
305@section Workarounds for Open Issues in Prototype
306
307@table @b
308
309@item [(I1)]:
310Not implemented.We would rather like to work on the formalization of
311per thread flags and global flags that are much more general than any kludge
312we could implement,
313
314@item [(I2)]:
315We have tried two solutions in our prototype. The first one was to use
316the @emph{idle} thread context contained in the @emph{Registers} task control
317block field. The drawback of this solution was that we had to implement specific
318code for the continue operation immediately following the attach command. We
319then decided to create a dedicated task that will only exist during the attach
320phase. This task will call the ``ENTER_RGDB'' exception. This call will execute
321the Exception Handler that saves a valid context and that notifies a change
322to GDB. After the first CONTINUE command from GDB, this task will continue its
323execution and delete itself,
324
325@item [(I3)]:
326As explained above in the synchronization chapter, we choose to serialize
327events in a way that makes GDB think the system is frozen,
328
329@item [(I4)]:
330As a temporary fix, we have called @emph{rtems_task_suspend} and used
331the context switch contex for tasks that are unknown to RGDBSD,
332
333@item [(I5)]:
334Not Implemented yet. If I remember correctly, setting the frame pointer
335to 0 at task initialization for CISC processor solves this problem (ebp = 0x0
336on Intel or a6 = 0x0 on 680x0). This should be done in rtems_task_create function
337in the path to really starts the task for the first time. The processor/system
338specific stop condition can be found as macros in the GDB source tree.
339@end table
340
341@section Output of a Debug Session with the Prototype
342
343This is a sample session with the remote debugging prototype.  Note that
344some lines have been broken so they would print properly when printed.
345
346@example
347GNU gdb 4.17
348Copyright 1998 Free Software Foundation, Inc.
349GDB is free software, covered by the GNU General Public License,
350and you are welcome to change it and/or distribute copies of it
351under certain conditions.  Type "show copying" to see the conditions.
352There is absolutely no warranty for GDB.
353Type "show warranty" for details.
354This GDB was configured as --host=i686-pc-linux-gnu --target=i386-rtems.
355Attaching remote machine across net...
356Connected to net-test.
357Now the "run" command will start a remote process.
358Setting up the environment for debugging gdb.
359(gdb) attach 1
360Attaching program: /build-rtems/pc386/tests/debug.exe pid 1
3610x230715 in enterRdbg ()
362(gdb) info threads
363There are 8 threads:
364Id.       Name   Detached   Suspended
365134283273 Rini   No         No <= current target thread
3660x230715 in enterRdbg ()
367134283272 Evnt   No         No
368_Thread_Dispatch () at /rtems/cpukit/score/src/thread.c:315
369134283271 SPE2   No         No
370_Thread_Dispatch () at /rtems/cpukit/score/src/thread.c:315
371134283270 SPE1   No         No
372_Thread_Handler  () at /rtems/cpukit/score/src/thread.c:1107
373134283269 RDBG   No         No
3740x230715 in enterRdbg ()
375134283268 SCrx   No         No
376_Thread_Dispatch () at /rtems/cpukit/score/src/thread.c:315
377134283267 SCtx   No         No
378_Thread_Dispatch () at /rtems/cpukit/score/src/thread.c:315
379134283266 ntwk   No         No
380_Thread_Dispatch () at /rtems/cpukit/score/src/thread.c:315
381(gdb) b init.c:89
382Breakpoint 1 at 0x200180: file \
383    /rtems/c/src/tests/samples/debug/init.c, line 89.
384(gdb) c
385Continuing.
386Thread 134283273 (Rini) has been deleted.
387[Switching to Rtems thread 134283271 (Not suspended) \
388    ( <= current target thread )]
389Breakpoint 1, example2 (argument=4) at \
390    /rtems/c/src/tests/samples/debug/init.c:89 
39189          tuto += tuti; 
392(gdb) s 
39390          if (print_enable2) 
394(gdb) c 
395Continuing.
396Breakpoint 1, example2 (argument=4) at \
397    /rtems/c/src/tests/samples/debug/init.c:89 
39889          tuto += tuti; 
399(gdb) b init.c:66 
400Breakpoint 2 at 0x200128: file \
401    /rtems/c/src/tests/samples/debug/init.c, line 66.
402(gdb) c
403Continuing.
404Switching to Rtems thread 134283270 (Not suspended) \
405    ( <= current target thread )]
406Breakpoint 2, example1 (argument=4) at \
407    /rtems/c/src/tests/samples/debug/init.c:66 
40866          toto += titi; 
409(gdb) c 
410Continuing. 
411[Switching to Rtems thread 134283271 (Not suspended) \
412    ( <= current target thread )]
413Breakpoint 1, example2 (argument=4) at \
414    /rtems/c/src/tests/samples/debug/init.c:89 
41589          tuto += tuti; 
416(gdb) bt 
417#0  example2 (argument=4) 
418    at /rtems/c/src/tests/samples/debug/init.c:89 
419#1  0xf0009bd0 in ?? () 
420(gdb) thread target 134283270
421thread 134283270 [SPE1], _Thread_Dispatch () at \
422    /rtems/cpukit/score/src/thread.c:315 
423315         executing = _Thread_Executing; 
424(gdb) c 
425Continuing.
426Breakpoint 2, example1 (argument=4) at \
427    /rtems/c/src/tests/samples/debug/init.c:66 
42866          toto += titi; 
429(gdb) detach 
430Detaching program: /build-rtems/pc386/tests/debug.exe pid 1 
431Warning: the next command will be done localy! \
432    If you want to restart another remote 
433program, reuse the target command 
434(gdb) 
435@end example
436
437
Note: See TracBrowser for help on using the repository browser.