OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [doc/] [rgdb_specs/] [daemon.t] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.