source: rtems/c/src/lib/librdbg/_servtgt.c @ 0162910

4.104.114.84.95
Last change on this file since 0162910 was 4721cf1, checked in by Joel Sherrill <joel.sherrill@…>, on 12/03/98 at 23:54:14

Patch from Emmanuel Raguet <raguet@…> to add remote debug server
and RPC support to RTEMS. Thanks. :) Email follows:

Hello,

For Xmas, here is the Remote Debugger on RTEMS !

Here are 2 patches for the Remote Debugger on RTEMS for pc386 from Linux
host :

  • one for RTEMS it self,
  • one for GDB-4.17.

1/ RTEMS patch
--------------

This patch adds 2 libraries :

  • a simplified SUN RPC library
  • the Remote Debugger library

The configuration command is the following :
../rtems4/configure --target=i386-rtemself --enable-rtemsbsp=pc386
--enable-rdbg

The SUN RPC library is built only if networking is set.
The RDBG library is built if networking and enable-rdbg are set.

The function used to initialize the debugger is :

rtems_rdbg_initialize ();

A special function has been created to force a task to be
in a "debug" state : enterRdbg().
The use of this function is not mandatory.

2/ GDB-4.17 patch
-----------------

This patch create a new RTEMS target for GDB-4.17.

The configuration command is the following :
./configure --enable-shared --target=i386RTEMS

To connect to a target, use :

target rtems [your_site_address]

Then, attach the target using : attach 1

And... Debug ;)

You can obtain the original GDB-4.17 on
ftp://ftp.debian.org/debian/dists/stable/main/source/devel/gdb_4.17.orig.tar.gz

This has been tested from a Debian 2.0.1 linux host.

  • Property mode set to 100644
File size: 9.9 KB
Line 
1/*
2 ============================================================================
3 _SERVTGT
4 ============================================================================
5*/
6
7
8#include <string.h>             
9#include <rtems.h>
10#include <rtems/error.h>
11
12#include <rdbg/rdbg.h>
13#include <rdbg/rdbg_f.h>
14#include <rdbg/servrpc.h>       
15#include <errno.h>
16#include <sys/socket.h>         
17#include <assert.h>
18#include <rtems/score/cpu.h>
19
20extern void rtems_exception_prologue_50();
21
22
23#ifdef DDEBUG
24#define Ptrace  TgtDbgPtrace
25#else
26#define Ptrace  TgtRealPtrace
27#endif
28
29extern int errno;
30
31rtems_id eventTaskId;
32rtems_id serializeSemId;
33rtems_id wakeupEventSemId;
34
35CPU_Exception_frame Idle_frame;
36
37cpuExcHandlerType old_currentExcHandler;
38
39/* -----------------------------------------------------------------
40   TgtRealPtrace - lowest level ptrace() wrapper
41   ----------------------------------------------------------------- */
42
43    int
44TgtRealPtrace(int req, PID aid, char* addr, int d, void* addr2)
45{
46    return ptrace(req, aid, addr, d, addr2);
47}
48
49
50/* -----------------------------------------------------------------
51   Maping of hardware exceptions into Unix-like signal numbers.
52   It is identical to the one used by the PM and the AM.
53   ----------------------------------------------------------------- */
54
55    int
56ExcepToSig (int excep)
57{
58    switch (excep) {
59     
60    case I386_EXCEPTION_MATH_COPROC_UNAVAIL:
61    case I386_EXCEPTION_I386_COPROC_SEG_ERR:
62    case I386_EXCEPTION_FLOAT_ERROR:
63    case I386_EXCEPTION_BOUND:
64        return SIGFPE;
65
66    case I386_EXCEPTION_DEBUG:
67    case I386_EXCEPTION_BREAKPOINT:
68    case I386_EXCEPTION_ENTER_RDBG:
69        return SIGTRAP;
70
71    case I386_EXCEPTION_OVERFLOW:
72    case I386_EXCEPTION_DIVIDE_BY_ZERO:
73    case I386_EXCEPTION_ILLEGAL_INSTR: 
74        return SIGILL;
75
76    case I386_EXCEPTION_SEGMENT_NOT_PRESENT:
77    case I386_EXCEPTION_STACK_SEGMENT_FAULT:
78    case I386_EXCEPTION_GENERAL_PROT_ERR:
79    case I386_EXCEPTION_PAGE_FAULT:
80        return SIGSEGV;
81
82    default:
83        break;
84    }
85    return SIGKILL;
86}
87
88/* -----------------------------------------------------------------------
89   TgtChange() is called when the system stops.
90   It informs the generic layers must be informed of
91   that fact.
92   ----------------------------------------------------------------------- */
93
94    static int
95TgtChange (PID pid, CPU_Exception_frame* ctx, int status)
96{
97
98    if (TgtHandleChildChange (pid, &status, NULL, ctx)) {
99      TgtNotifyWaitChange (pid, status, -1);
100    }
101
102    return 0;
103}
104
105/* -----------------------------------------------------------------------
106   eventTask
107   ----------------------------------------------------------------------- */
108
109rtems_task eventTask( rtems_task_argument pid)
110{
111  Exception_context *ctx;
112
113  DPRINTF (("event task: pid %d\n", pid));
114
115 
116  /*
117   * we spend all our time waiting for a semaphore.
118   * If wait change, we send info
119   */
120 
121  for (;;){     
122    DPRINTF (("Event Task: wait event\n"));
123    rtems_semaphore_obtain(wakeupEventSemId, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
124    DPRINTF (("Event Task: wake up !!!!!!!!!!!!!\n"));
125   
126    errno = 0;
127    ctx = GetExceptCtx(currentTargetThread);
128
129    CheckForSingleStep(ctx->ctx);
130
131    TgtChange(pid, ctx->ctx,STS_MAKESIG(ExcepToSig(ctx->ctx->idtIndex)));
132     
133  }
134}
135
136/* -------------------------------------------------------------------
137   MyThreadIdle -
138
139   This task is used to initiate the exception mechanism:
140   It calls the enterDebug function with justSaveContext=1
141   only to push a first valid context in the list
142   ---------------------------------------------------------------------*/
143
144rtems_task MyThreadIdle(rtems_task_argument argument)
145{
146  enterRdbg();
147  rtems_task_delete( RTEMS_SELF );
148}
149
150/* -----------------------------------------------------------------------
151   TgtAttach - attach to a process that is running without control.
152
153   Notes:
154      - this function performs a ptrace ATTACH equivalent (attaching to a
155        process that we do not control now).
156   ----------------------------------------------------------------------- */
157
158Boolean TgtAttach(
159  int           conn_idx,       /* client that is requesting */
160  PID           pid)            /* process to attach to */
161{
162  rtems_name task_name;
163  rtems_status_code status;
164  rtems_id debugId;
165  interrupt_gate_descriptor      *currentIdtEntry;
166  unsigned                       limit;
167  unsigned                       level;
168 
169  errno = 0;
170
171  DPRINTF (("TgtAttach pid=%d\n",pid));
172 
173  Ptrace(RPT_ATTACH, pid, NULL, 0, NULL);
174  if (errno)
175    return(False);              /* failed */
176
177  TgtCreateNew(pid, conn_idx, 0, NULL, False);
178
179
180  /*
181   *  Connect the Exception used to debug
182   */
183  i386_get_info_from_IDTR (&currentIdtEntry, &limit);
184 
185  _CPU_ISR_Disable(level);
186  create_interrupt_gate_descriptor (&currentIdtEntry[50], rtems_exception_prologue_50);
187  _CPU_ISR_Enable(level);
188
189  old_currentExcHandler = _currentExcHandler;
190  _currentExcHandler = BreakPointExcHdl ;
191
192
193  /*
194   * Create the attach debuger task
195   */
196  task_name = rtems_build_name( 'E', 'v', 'n', 't' );
197  if ((status = rtems_task_create( task_name, 10, 24576,
198                                   RTEMS_INTERRUPT_LEVEL(0),
199                                   RTEMS_DEFAULT_ATTRIBUTES | RTEMS_SYSTEM_TASK,
200                                   &eventTaskId ))
201      != RTEMS_SUCCESSFUL){
202    printf("status = %d\n",status);
203    rtems_panic ("Can't create task.\n");
204  }
205 
206  status = rtems_task_start(eventTaskId, eventTask, pid);
207
208  status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 's'),
209                                   1,
210                                   RTEMS_FIFO |
211                                   RTEMS_COUNTING_SEMAPHORE |
212                                   RTEMS_NO_INHERIT_PRIORITY |
213                                   RTEMS_NO_PRIORITY_CEILING |
214                                   RTEMS_LOCAL,
215                                   0,
216                                   &serializeSemId);
217  if (status != RTEMS_SUCCESSFUL)
218    rtems_panic ("Can't create serialize semaphore: `%s'\n",rtems_status_text(status));
219
220  status = rtems_semaphore_create (rtems_build_name('D', 'B', 'G', 'w'),
221                                   0,
222                                   RTEMS_FIFO |
223                                   RTEMS_COUNTING_SEMAPHORE |
224                                   RTEMS_NO_INHERIT_PRIORITY |
225                                   RTEMS_NO_PRIORITY_CEILING |
226                                   RTEMS_LOCAL,
227                                   0,
228                                   &wakeupEventSemId);
229  if (status != RTEMS_SUCCESSFUL)
230    rtems_panic ("Can't create wakeup semaphore: `%s'\n",rtems_status_text(status));
231
232  /*
233   * Create the MyThreadIdle task to init Exception mechanism
234   */
235  task_name = rtems_build_name( 'R', 'i', 'n', 'i' );
236  if ((status = rtems_task_create( task_name, 10, 24576,
237                                   RTEMS_INTERRUPT_LEVEL(0),
238                                   RTEMS_DEFAULT_ATTRIBUTES,
239                                   &debugId ))
240      != RTEMS_SUCCESSFUL){
241    printf("status = %d\n",status);
242    rtems_panic ("Can't create task.\n");
243  }
244
245  status = rtems_task_start(debugId, MyThreadIdle, pid);
246
247  return(True);
248}
249
250/* -----------------------------------------------------------------------
251   TgtPtrace - handle ptrace requests for server.
252   ----------------------------------------------------------------------- */
253
254int TgtPtrace(         
255  int           req,
256  PID           pid,
257  char          *addr,
258  int           data,
259  void          *addr2)
260{
261  if ((req == RPT_SINGLESTEP || req == RPT_CONT)
262  &&  addr2)                    /* clear then step */
263  {                             /* addr2 is the old value */
264    int         ret;
265
266    errno = 0;
267    TgtBreakRestoreOrig (pid, addr, addr2);
268    ret = Ptrace(RPT_SINGLESTEP, pid, addr, data, NULL); /* step over */
269    if (ret)            /* error, cannot single-step */
270    {
271      int pid_idx = FindPidEntry (pid);
272      TgtBreakCancelStep (&pid_list [pid_idx]);
273    }
274    return(ret);                /* failed or done */
275  }
276  else
277    return(Ptrace(req, pid, addr, data, addr2)); /* normal call */
278}
279
280/* -----------------------------------------------------------------
281   TgtGetThreadName - get thread name
282   --------------------------------------------------------------- */
283
284int TgtGetThreadName (
285   PID_LIST     *plst,          /* Process entry */
286   unsigned     Id,             /* Thread ID */
287   char         *ThrName)               /* Thread name */
288{
289    int index;
290    unsigned name;
291   
292    if ( Id <_Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id &&
293         Id >_Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id) {
294
295      index = Id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
296      name = *(unsigned*)(_Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index]->name);
297      ThrName[0] = (char)((name >> 24) & 0xFF );
298      ThrName[1] = (char)((name >> 16) & 0xFF );
299      ThrName[2] = (char)((name >> 8)  & 0xFF );
300      ThrName[3] = (char)( name        & 0xFF );
301      ThrName[4] = 0x0;
302      return 0;
303    }
304     
305    if ( Id <_Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id &&
306         Id >_Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id) {
307
308      index = Id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
309      name = *(unsigned*)(_Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index]->name);
310      ThrName[0] = (char)((name >> 24) & 0xFF );
311      ThrName[1] = (char)((name >> 16) & 0xFF );
312      ThrName[2] = (char)((name >> 8)  & 0xFF );
313      ThrName[3] = (char)( name        & 0xFF );
314      ThrName[4] = 0x0;
315      return 0;
316    }
317     
318       
319    return -1;
320
321}
322
323/* -----------------------------------------------------------------
324   TgtThreadList - return all the threads in the system
325   ----------------------------------------------------------------- */
326
327    int
328TgtThreadList (
329  PID_LIST* plst,               /* Process entry */
330  unsigned* threads,            /* Output buffer */
331  unsigned size)                /* Output buffer size */
332{
333    int curr = 0;
334    Objects_Id  id;     
335    unsigned index;
336
337    id = _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
338
339    while (id < _Objects_Information_table[OBJECTS_RTEMS_TASKS]->maximum_id){
340      index = id - _Objects_Information_table[OBJECTS_RTEMS_TASKS]->minimum_id;
341      if ( _Objects_Information_table[OBJECTS_RTEMS_TASKS]->local_table[1+index] != NULL){
342      threads[curr] = (unsigned) id;
343      curr++;
344      }
345      id ++;
346    }
347       
348    id = _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
349
350    while (id < _Objects_Information_table[OBJECTS_POSIX_THREADS]->maximum_id){
351      index = id - _Objects_Information_table[OBJECTS_POSIX_THREADS]->minimum_id;
352      if ( _Objects_Information_table[OBJECTS_POSIX_THREADS]->local_table[1+index] != NULL){
353      threads[curr] = (unsigned) id;
354      curr++;
355      }
356      id ++;
357    }
358       
359    return curr;
360}
Note: See TracBrowser for help on using the repository browser.