[uClinux-dev] gdbserver kills the shell?

John Williams jwilliams at itee.uq.edu.au
Wed Oct 5 22:49:19 EDT 2005


Hi Stuart,

Stuart Hughes wrote:
> Here's a patch based on Miles Bader's.  I've removed the v850 sections
> to try to make it just a nommu patch.
> 
> Again, this is against vanilla gdb-6.0.

The version of gdb now in the uClinux-dist (/usr/gdb) appears to be 6.3.
 I manually merged Miles' older patches into this without too much
trouble, and it seems to work ok for microblaze at least.  The main
changes are the fork->vrofk, adding config.srv target, and introducing
support for the qOffset remote packet type.

What's odd is the way this was done in his original patches is quite
different in form (if not function) to the patch that you have sent.

One notable difference in the version you have is use of hard coded
ptrace(PTRACE_PEEKUSR,...)  offsets for the TEXT, DATA and BSS queries,
rather than the PT_TEXT_ADDR, _DATA_ADDR and _BSS_ADDR macros that are
defined in linux-2.4.x/include/asm/ptrace.h

I guess this is just versionitis, both on patches and base gdb versions.
 I agree with DaveM's sentiments that we should track the latest,
whatever that may be.  From where I'm sitting, that looks like gdb6.3
that is currently in uClinux-dist.  I've attached my patches, can you
try them at your end, and see how they look?

Regards,

John

> 
> Regards, Stuart
> 
> Stuart Hughes wrote:
> 
>> Hi John,
>>
>> I'm in the process of forward porting the patches for gdbserver that
>> are in uClinux-dist-test-20050906.tar.bz2 to gdb-6.0.  I've attached a
>> patch that works, but needs a bit of clean-up.  I also found the Miles
>> Bader patch gdbserver-v850.bin which looks like it may be more
>> generic, so I'll probably make adjustments.
>>
>> Although this won't slot directly into uClinux-dist, hopefully this
>> may help you.
>>
>> Regards, Stuart
>>
>> John Williams wrote:
>>
>>> David McCullough wrote:
>>>
>>>> I would have thought Miles patches would apply fairly cleanly to the
>>>> new
>>>> gdb/gdbserver source.
>>>
>>>
>>>
>>>
>>> Yep, I've done that and looks good at first glance.
>>>
>>> Dare I ask, what's the plan for the current uClinux-dist CVS?  My
>>> memory is that the current CVS is officially still a test-release.
>>>
>>> It works pretty well for microblaze right now, but if Gerg is still
>>> taking patches before the next real cut I've got some stuff here
>>> (uClinux-ifying the new gdbserver included).
>>>
>>> Greg?  :)
>>>
>>> Thx,
>>>
>>> John
>>> _______________________________________________
>>> uClinux-dev mailing list
>>> uClinux-dev at uclinux.org
>>> http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
>>> This message was resent by uclinux-dev at uclinux.org
>>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> diff --exclude CVS -uNr gdb-6.0/gdb/gdbserver/linux-low.c
>> gdb-6.0.modified/gdb/gdbserver/linux-low.c
>> --- gdb-6.0/gdb/gdbserver/linux-low.c    Sun Jun 29 05:03:04 2003
>> +++ gdb-6.0.modified/gdb/gdbserver/linux-low.c    Wed Oct  5 14:15:56
>> 2005
>> @@ -69,6 +69,12 @@
>>  static int use_regsets_p = 1;
>>  #endif
>>  
>> +#if defined(EMBED) ||  defined(__UCLIBC__) &&
>> !defined(__UCLIBC_HAS_MMU__)
>> +static unsigned int code_end;
>> +static unsigned int code_start;
>> +static unsigned int data_start;
>> +static unsigned int bss_start;
>> +#endif
>>  extern int errno;
>>  
>>  int debug_threads = 0;
>> @@ -139,7 +145,11 @@
>>    void *new_process;
>>    int pid;
>>  
>> +#if defined(EMBED) ||  defined(__UCLIBC__) &&
>> !defined(__UCLIBC_HAS_MMU__)
>> +  pid = vfork ();
>> +#else
>>    pid = fork ();
>> +#endif
>>    if (pid < 0)
>>      perror_with_name ("fork");
>>  
>> @@ -1293,3 +1303,38 @@
>>    init_registers ();
>>    linux_init_signals ();
>>  }
>> +
>> +#if defined(EMBED) ||  defined(__UCLIBC__) &&
>> !defined(__UCLIBC_HAS_MMU__)
>> +void
>> +send_area(char *buf)
>> +{
>> +    /*
>> +     * with the new compilers (gcc-2.95.2 this has changed and we
>> need to
>> +     * send back the start of code for everything
>> +     *
>> +     * Of course, the start of code is fairly interesting since there
>> might be a
>> +     * break inserted between code and data segments.  We've got to
>> account for this
>> +     * break by faking a start of data that is the length of the code
>> segment below the
>> +     * real begining of the data segment.
>> +     */
>> +    unsigned int x;
>> +    x = data_start - (code_end - code_start);
>> +    sprintf(buf,"Text=%x;Data=%x;Bss=%x;", code_start, x, x);
>> +}
>> +
>> +void
>> +show_area()
>> +{
>> +    code_start = ptrace (PTRACE_PEEKUSER, inferior_pid,
>> +                 (PTRACE_ARG3_TYPE) 49*4, 0);
>> +    data_start = ptrace (PTRACE_PEEKUSER, inferior_pid,
>> +                 (PTRACE_ARG3_TYPE) 50*4, 0);
>> +    bss_start = data_start;
>> +    code_end = ptrace(PTRACE_PEEKUSER, inferior_pid,
>> +                 (PTRACE_ARG3_TYPE) 51*4, 0);
>> +
>> +    fprintf(stderr,"code at %p - %p, data at %p\n", (void
>> *)code_start, +                                                   
>> (void *)code_end,
>> +                                                    (void *)data_start);
>> +}
>> +#endif
>> diff --exclude CVS -uNr gdb-6.0/gdb/gdbserver/server.c
>> gdb-6.0.modified/gdb/gdbserver/server.c
>> --- gdb-6.0/gdb/gdbserver/server.c    Tue Jun 17 21:28:14 2003
>> +++ gdb-6.0.modified/gdb/gdbserver/server.c    Wed Oct  5 14:00:55 2005
>> @@ -184,6 +184,9 @@
>>        signal = start_inferior (&argv[2], &status);
>>  
>>        /* We are now stopped at the first instruction of the target
>> process */
>> +#if defined(EMBED) ||  defined(__UCLIBC__) &&
>> !defined(__UCLIBC_HAS_MMU__)
>> +      show_area();
>> +#endif
>>      }
>>    else
>>      {
>> @@ -198,6 +201,7 @@
>>      }
>>      }
>>  
>> +
>>    while (1)
>>      {
>>        remote_open (argv[1]);
>> @@ -212,7 +216,21 @@
>>        switch (ch)
>>          {
>>          case 'q':
>> +#if defined(EMBED) ||  defined(__UCLIBC__) &&
>> !defined(__UCLIBC_HAS_MMU__)
>> +          switch (own_buf[1]) {
>> +          case 'C':
>> +                own_buf[0] = '\0';
>> +            break;
>> +          case 'O':
>> +            send_area(own_buf);
>> +                break;
>> +          default:
>> +                own_buf[0] = '\0';
>> +            break;
>> +          }
>> +#else
>>            handle_query (own_buf);
>> +#endif
>>            break;
>>          case 'd':
>>            remote_debug = !remote_debug;
>> @@ -440,3 +458,8 @@
>>      }
>>      }
>>  }
>> +
>> +void _cleanup()
>> +{
>> +}
>> +
>> diff --exclude CVS -uNr gdb-6.0/gdb/gdbserver/server.h
>> gdb-6.0.modified/gdb/gdbserver/server.h
>> --- gdb-6.0/gdb/gdbserver/server.h    Sun Jun 29 05:03:04 2003
>> +++ gdb-6.0.modified/gdb/gdbserver/server.h    Wed Oct  5 13:57:04 2005
>> @@ -162,6 +162,12 @@
>>  void fatal (const char *string,...) ATTR_NORETURN;
>>  void warning (const char *string,...);
>>  
>> +#if defined(EMBED) ||  defined(__UCLIBC__) &&
>> !defined(__UCLIBC_HAS_MMU__)
>> +/* Functions from low-linux.c */
>> +void show_area(void);
>> +void send_area(char *buf);
>> +#endif
>> +
>>  /* Functions from the register cache definition.  */
>>  
>>  void init_registers (void);
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> uClinux-dev mailing list
>> uClinux-dev at uclinux.org
>> http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
>> This message was resent by uclinux-dev at uclinux.org
> 
> 
> 
> ------------------------------------------------------------------------
> 
> Weds Oct 5 2005 Stuart Hughes <stuarth at freescale.com>
> 
> This is a forward port of the patch by Miles Bader "miles at lsi.nec.co.jp
> Wed May 28 09:28:21 EDT 2003",
> http://mailman.uclinux.org/pipermail/uclinux-dev/2003-May/018191.html
> 
> I've removed the parts that were specific to the v850 to try to make the more
> of a stand-alone nommu patch.
> 
> I've only tested this on m68knommu.
> 
> diff --exclude CVS -uNr gdb-6.0/gdb/gdbserver/linux-low.c gdb-6.0.modified/gdb/gdbserver/linux-low.c
> --- gdb-6.0/gdb/gdbserver/linux-low.c	Sun Jun 29 05:03:04 2003
> +++ gdb-6.0.modified/gdb/gdbserver/linux-low.c	Wed Oct  5 15:42:43 2005
> @@ -138,8 +138,12 @@
>  {
>    void *new_process;
>    int pid;
> -
> + 
> +#if defined(EMBED) ||  defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__)
> +  pid = vfork ();
> +#else
>    pid = fork ();
> +#endif
>    if (pid < 0)
>      perror_with_name ("fork");
>  
> @@ -1258,6 +1262,61 @@
>      kill (signal_pid, signum);
>  }
>  
> +#if defined(EMBED) ||  defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__)
> +#if defined(__m68k__)
> +/******************************************************************** 
> +   Note that some architectures define the following in ptrace.h
> +   For an example see: include/asm-v850/ptrace.h in the kernel   
> +*********************************************************************/
> +#define PT_TEXT_ADDR 49*4
> +#define PT_TEXT_LEN  50*4
> +#define PT_DATA_ADDR 51*4
> +#endif
> +
> +/* Some linux-specific handling for extended 'q' packets.  */
> +static int
> +linux_handle_query (char *own_buf)
> +{
> +#if defined(PT_TEXT_ADDR) && defined(PT_DATA_ADDR) && defined(PT_TEXT_LEN)
> +  /* Under uClinux, programs are loaded at non-zero offsets, which we need
> +     to tell gdb about.  */
> +  if (strcmp ("qOffsets", own_buf) == 0)
> +    {
> +      unsigned long text, text_len, real_data;
> +      int pid = get_thread_process (current_inferior)->head.id;
> +
> +      errno = 0;
> +
> +      text = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_ADDR, 0);
> +      text_len = ptrace (PTRACE_PEEKUSER, pid, (long)PT_TEXT_LEN, 0);
> +      real_data = ptrace (PTRACE_PEEKUSER, pid, (long)PT_DATA_ADDR, 0);
> +
> +      if (errno == 0)
> +   {
> +     /* Both text and data offsets produced at compile-time (and so
> +        used by gdb) are relative to the beginning of the program,
> +        with the data segment immediately following the text segment.
> +        However, the actual runtime layout in memory may put the data
> +        somewhere else, so when we send gdb a data base-address, we
> +        use the real data base address and subtract the compile-time
> +        data base-address from it (which is just the length of the
> +        text segment).  BSS immediately follows data in both cases.  */
> +     unsigned long data = real_data - text_len;
> +     unsigned long bss = data;
> +     sprintf (own_buf, "Text=%lx;Data=%lx;Bss=%lx", text, data, bss);
> +   }
> +      else
> +   sprintf (own_buf, "ENN");
> +
> +      return 1;
> +    }
> +#endif
> +
> +  /* Something we don't handle.  */
> +  return 0;
> +}
> +#endif
> +
>  
>  static struct target_ops linux_target_ops = {
>    linux_create_inferior,
> @@ -1272,6 +1331,7 @@
>    linux_read_memory,
>    linux_write_memory,
>    linux_look_up_symbols,
> +  linux_handle_query,
>    linux_send_signal,
>  };
>  
> diff --exclude CVS -uNr gdb-6.0/gdb/gdbserver/server.c gdb-6.0.modified/gdb/gdbserver/server.c
> --- gdb-6.0/gdb/gdbserver/server.c	Tue Jun 17 21:28:14 2003
> +++ gdb-6.0.modified/gdb/gdbserver/server.c	Wed Oct  5 15:39:00 2005
> @@ -88,6 +88,12 @@
>  {
>    static struct inferior_list_entry *thread_ptr;
>  
> +#if defined(EMBED) ||  defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__)
> +  /* First see if the target-specific code wants to deal with this.  */
> +  if (the_target->handle_query && (*the_target->handle_query) (own_buf))
> +    return;
> +#endif
> +
>    if (strcmp ("qSymbol::", own_buf) == 0)
>      {
>        if (the_target->look_up_symbols != NULL)
> diff --exclude CVS -uNr gdb-6.0/gdb/gdbserver/target.h gdb-6.0.modified/gdb/gdbserver/target.h
> --- gdb-6.0/gdb/gdbserver/target.h	Tue Jun 17 21:28:14 2003
> +++ gdb-6.0.modified/gdb/gdbserver/target.h	Wed Oct  5 15:40:16 2005
> @@ -109,6 +109,13 @@
>  
>    void (*look_up_symbols) (void);
>  
> +#if defined(EMBED) ||  defined(__UCLIBC__) && !defined(__UCLIBC_HAS_MMU__)
> +  /* If non-zero, handle a `q' op from gdb, updating OWN_BUF with the result.
> +     Should return 1 if the op was handled, otherwise 0.  */
> +
> +  int (*handle_query) (char *own_buf);
> +#endif
> +
>    /* Send a signal to the inferior process, however is appropriate.  */
>    void (*send_signal) (int);
>  };
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> uClinux-dev mailing list
> uClinux-dev at uclinux.org
> http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
> This message was resent by uclinux-dev at uclinux.org


-- 
Dr John Williams, Research Fellow,
Embedded Systems Group / Reconfigurable Computing
School of ITEE, The University of Queensland, Brisbane, Australia
(p) +61 7 33652185  (f) +61 7 33654999 (m) +61 403969243
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ucdist-gdb.patch
URL: <http://mailman.uclinux.org/pipermail/uclinux-dev/attachments/20051006/b79642d4/attachment.ksh>


More information about the uClinux-dev mailing list