source: rtems/c/src/lib/librdbg/servtsp.c @ 8548fe0

4.104.114.84.95
Last change on this file since 8548fe0 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.3 KB
Line 
1/*
2 **************************************************************************
3 *
4 *  Component:  RDBG
5 *  Module:     servtsp.c
6 *
7 *  Synopsis:   Transport management for remote debug server.
8 *
9 **************************************************************************
10 */
11
12#include <sys/errno.h>
13#include <rdbg/rdbg.h> 
14#include <rdbg/servrpc.h>
15#include <signal.h>             
16#include <rpc/rpc.h>           
17#include <rpc/svc.h>           
18#include <netinet/in.h>         
19#include <sys/socket.h>         
20
21static int      out_sock;       
22static int      warm_test;     
23
24static void TimeTestHandler(); 
25
26    /*
27     *  TspInit - Initialize the transport system.
28     *
29     */
30
31    void
32TspInit (int id)
33{
34    struct sigaction sa;
35
36        /* setup a socket to send event messages back through */
37    out_sock = socket (PF_INET, SOCK_DGRAM, 0);
38    if (out_sock < 0) {
39        DPRINTF (("TspInit: socket() failed %d errno %d\n",
40                out_sock, getErrno()));
41        return;         /* failed to open socket, let caller deal with */
42    }
43    {
44        struct sockaddr_in addr;
45
46        bzero ((void *)(&addr), sizeof addr);
47        addr.sin_family = AF_INET;
48        addr.sin_port = htons (BackPort);
49        if (bind (out_sock, (struct sockaddr*) &addr, sizeof addr) < 0) {
50            DPRINTF (("TspInit: bind() failed\n"));
51        }
52    }
53    /* setup alarm timer for warm testing */
54    memset (&sa, 0, sizeof (sa));
55    sa.sa_handler = TimeTestHandler;
56    sigaction (SIGALRM, &sa, 0);
57}
58
59    /*
60     *  TspTranslateRpcAddr - translate from an RPC handle to an
61     *                        opaque address.
62     *
63     *  Converts the sender's address into the opaque data structure
64     *  used for network addresses. This is used to look up the sender
65     *  on each call.
66     */
67
68    Boolean
69TspTranslateRpcAddr (struct svc_req* rqstp, NET_OPAQUE* opaque)
70{
71    struct sockaddr_in* addr;   /* used as template to extract net info */
72    unsigned char*      up;
73
74    memset (opaque, 0, sizeof (NET_OPAQUE));
75        /*
76         *  We interpret the remote address as a standard netbuf name.
77         *  The format is 2 bytes of address family (normally AF_INET)
78         *  and then a length (5) and then the IP address.
79         */
80    if (rqstp->rq_xprt->xp_addrlen != 16)
81    {
82        DPRINTF (("TspTranslateRpcAddr: Unknown remote address!!!\n"));
83        setErrno (EPROTONOSUPPORT);
84        return False;           /* invalid, so fails */
85    }
86        /* addr = &rqstp->rq_xprt->xp_raddr; */
87    addr = svc_getcaller (rqstp->rq_xprt);
88        /* verify it is AF_INET */
89    if (addr->sin_family != AF_INET) {          /* no, error */
90        DPRINTF (("TspTranslateRpcAddr: Not an internet address!!\n"));
91        setErrno (EAFNOSUPPORT);/* invalid addr family */
92        return False;
93    }
94        /* good address type */
95    up = (unsigned char *) &addr->sin_addr.s_addr;
96    DPRINTF (("TspTranslateRpcAddr: Sent by %u.%u.%u.%u port #%u\n",
97        up[0], up[1], up[2], up[3], htons (addr->sin_port)));
98    memcpy (opaque, addr, sizeof (struct sockaddr_in));
99    return True;
100}
101
102    /*
103     *  TspValidateAddr - validate a passed in opaque address.
104     *
105     *  Checks that the passed in address is in the format
106     *  expected.
107     */
108
109    Boolean
110TspValidateAddr (NET_OPAQUE* opaque, NET_OPAQUE* sender)
111{
112    struct sockaddr_in* addr;   /* used as template to extract net info */
113
114    addr = (struct sockaddr_in*) opaque;
115        /* Verify it is AF_INET. Should check against sender IP address too */
116    if (addr->sin_family != AF_INET) {
117        DPRINTF (("TspValidateAddr: Back port invalid: %d\n",
118            htons (addr->sin_port)));
119        return False;           /* not valid */
120    }
121        /* otherwise, we copy in the IP address, since client may not know it */
122    addr->sin_addr.s_addr = ((struct sockaddr_in*) sender)->sin_addr.s_addr;
123    DPRINTF (("TspValidateAddr: Back port is %d\n", htons (addr->sin_port)));
124    return True;
125}
126
127    /*
128     *  TspConnGetIndex - lookup an rpc caller's address as a connection entry.
129     *
130     *  Looks up an ip address of a caller to locate the
131     *  connection index in our connection array.
132     */
133
134    int
135TspConnGetIndex (struct svc_req* rqstp)
136{
137    int         conn;
138        /* &rqstp->rq_xprt->xp_raddr; */
139    struct sockaddr_in *addr = svc_getcaller (rqstp->rq_xprt);
140
141    for (conn = 0; conn < conn_list_cnt; conn++) {
142        if (!conn_list[conn].in_use)
143            continue;                   /* not used */
144
145        if (addr->sin_addr.s_addr == ((struct sockaddr_in *)
146                &conn_list [conn].sender)->sin_addr.s_addr
147                &&  addr->sin_port == ((struct sockaddr_in *)
148                &conn_list[conn].sender)->sin_port) {
149            return conn;
150        }
151    }
152    return -1;
153}
154
155
156    /*
157     *  TspSendWaitChange - send wait-change message to clients to
158     *                      notify change.
159     */
160
161    void
162TspSendWaitChange(
163    int         conn,           /* connection to send to */
164    BACK_MSG    msg,            /* BMSG type */
165    UINT16      spec,           /* special information */
166    PID         pid,            /* pid it refers to */
167    UINT32      context,        /* additional context for message */
168    Boolean     force)          /* force into being only message */
169{
170    int                 idx;
171    struct SEND_LIST*   snd_ptr;
172
173    if (force) {
174            /* force to top, which means others gone */
175        idx = 0;
176        conn_list [conn].send_idx = 1;
177        conn_list[conn].retry = 0;
178    } else {
179        for (idx = 0; idx < (int) conn_list[conn].send_idx; idx++) {
180            if (conn_list[conn].send_list[idx].send_type == msg
181                &&  conn_list[conn].send_list[idx].pid == pid)
182            return;                     /* already pended for this pid */
183        }
184        idx = conn_list[conn].send_idx;
185        if (idx+1 > MAX_SEND)
186            return;                     /* we lose it, what should we do??? */
187        conn_list[conn].send_idx++;
188    }
189    snd_ptr = &conn_list[conn].send_list[idx];
190    snd_ptr->send_type = msg;           /* message to send */
191    snd_ptr->retry = TSP_RETRIES;       /* about 1 minute of retries */
192    snd_ptr->spec = htons ((u_short) spec);
193    snd_ptr->pid = htonl (pid);
194    snd_ptr->context = htonl (context);
195    TspSendMessage (conn, False);       /* now do the send */
196}
197
198    /*
199     *  TspSendMessage - send message at top of send list for connection.
200     */
201
202    void
203TspSendMessage( int conn, Boolean resend)
204{
205    struct sockaddr_in  addr;
206    struct UDP_MSG      msg;
207    int                 cnt;
208
209    if (!resend && conn_list[conn].retry)
210        return;                 /* already waiting for reply */
211
212        /*
213         *  Note on above: if no back port we can't remove unless
214         *  someone blows off.
215         */
216    if (!resend) {
217            /* first time, setup. Set retry count: */
218        conn_list[conn].retry = conn_list[conn].send_list[0].retry;
219        conn_list[conn].last_msg_num++; /* new sequence number */
220        if (!warm_test++) {             /* starting, so enable timer */
221            alarm (2);                  /* resend every 2 seconds as needed */
222        }
223    }
224
225    msg.type    = conn_list[conn].send_list[0].send_type;
226    msg.msg_num = conn_list[conn].last_msg_num;
227    msg.spec    = conn_list[conn].send_list[0].spec;
228    msg.pid     = conn_list[conn].send_list[0].pid;
229    msg.context = conn_list[conn].send_list[0].context;
230
231    memset (&addr, 0, sizeof addr);
232    addr.sin_family = AF_INET;
233    addr.sin_port = ((struct sockaddr_in*)&conn_list[conn].back_port)->sin_port;
234    addr.sin_addr.s_addr =
235        ((struct sockaddr_in*)&conn_list[conn].back_port)->sin_addr.s_addr;
236
237    DPRINTF (("TspSendMessage: Sending msg %d (%s) to port %d\n",
238        msg.type, BmsgNames [msg.type], HL_W (addr.sin_port)));
239
240    cnt = sendto (out_sock, &msg, sizeof msg, 0, (struct sockaddr*) &addr,
241                    sizeof addr);
242    if (cnt != sizeof msg) {            /* failed on send */
243        printf ("%s: Failed to send msg %d to conn %d (%d vs. %d)\n",
244            ActName, msg.type, conn, cnt, sizeof msg);
245    }
246}
247
248    /*
249     *  TspMessageReceive - confirmation received, now send next if any.
250     *
251     *  - since UDP is connectionless, we batch up the sends and use
252     *    one at a time until we get a message indicating ready for
253     *    next (from ack).
254     */
255
256    void
257TspMessageReceive (int conn, PID pid)
258{
259        /* We remove the send list entry and use next if any */
260    conn_list[conn].retry = 0;  /* reset */
261    if (!warm_test || !--warm_test) {
262        alarm (0);                      /* reset timer if not used */
263    }
264#ifdef DDEBUG
265    if (conn_list[conn].send_list[0].send_type == BMSG_WARM) {
266        DPRINTF (("TspMessageReceive: Connection reset for conn %d\n", conn));
267    }
268#endif
269        /* Move up by one if needed */
270    if (!--conn_list[conn].send_idx)
271        return;                 /* no more to do */
272
273    memcpy (conn_list[conn].send_list, conn_list[conn].send_list+1,
274        conn_list[conn].send_idx * sizeof(struct SEND_LIST)); /* copy down */
275    TspSendMessage (conn, 0);
276}
277
278    /*
279     *  TspGetHostName - return client's host name.
280     *
281     *  - this routine returns the name of the client's host or the net
282     *    number of unknown.
283     */
284
285    char*
286TspGetHostName (conn_idx)
287    int         conn_idx;       /* client connection number */
288{
289    static char         buff [30];      /* largest net num */
290    unsigned char*      cp;
291
292    cp = conn_list[conn_idx].sender.c+4;
293    sprintf (buff, "%u.%u.%u.%u", cp[0], cp[1], cp[2], cp[3]);
294    return buff;
295}
296
297    /*
298     *  TimeTestHandler - alarm timer handler to resend warm/wait test.
299     */
300
301    static void
302TimeTestHandler()
303{
304    int         conn;
305
306    if (!warm_test)
307        return;                 /* no longer enabled */
308
309    for (conn = 0; conn < conn_list_cnt; conn++) {     
310            /* locate all that are using this */
311        if (!conn_list[conn].in_use)
312            continue;                   /* not used */
313
314        if (!conn_list[conn].retry) continue;
315            /* found one that we are testing */
316        if (!--conn_list[conn].retry) {
317                /*
318                 *  Counted down the retries: blow off.
319                 *  Need to have connection flag to indicate not blowing
320                 *  off for cases where client is stopped due to being
321                 *  debugged.
322                 */
323            ConnDelete (conn, NULL, CLOSE_IGNORE);
324            continue;
325        }
326        TspSendMessage (conn, True);    /* send another message */
327    }
328    alarm (2);                  /* setup for 2 seconds from now */
329}
Note: See TracBrowser for help on using the repository browser.