public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
* memory corruption problem
@ 2016-07-09 17:46 Wilkes, John
  2016-07-11 16:13 ` Wilkes, John
  0 siblings, 1 reply; 4+ messages in thread
From: Wilkes, John @ 2016-07-09 17:46 UTC (permalink / raw)
  To: newlib; +Cc: Wilkes, John

I am using a gcc-6.1.0 and newlib-2.4.0 tool chain. FreeRTOS builds with this tool chain and runs all the FreeRTOS demos, so think the newlib port is pretty solid.

However, when running a bare metal program (no OS), I get some memory corruption; a critical variable is overwritten with garbage. I traced the problem to the stdout __FILE pointer.

It looks like the stdout __FILE struct is initialized in _sinit, and "__FILE *_stdout" in the _reent stuct points to the critical variable (i.e. same address). The trashed variable has a fixed address visible in "nm" output, so it doesn't move.

Where in the newlib code is the stdout  __FILE struct allocated/created?

This is a new port with primitive debugging, i.e. no gdb support yet, and no shiny eclipse IDE.

Thanks for any help/insight/suggestions!

John

-- 
John Wilkes | AMD Research |  john.wilkes@amd.com | office: +1 425.586.6412 (x26412)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: memory corruption problem
  2016-07-09 17:46 memory corruption problem Wilkes, John
@ 2016-07-11 16:13 ` Wilkes, John
  2016-07-12  5:27   ` Sebastian Huber
  0 siblings, 1 reply; 4+ messages in thread
From: Wilkes, John @ 2016-07-11 16:13 UTC (permalink / raw)
  To: newlib; +Cc: Wilkes, John

If _REENT_SMALL is defined, the __sinit(struct _reent *s) function sets s->stdout:

#ifndef _REENT_SMALL
  s->__sglue._niobs = 3;
  s->__sglue._iobs = &s->__sf[0];
#else
  s->__sglue._niobs = 0;
  s->__sglue._iobs = NULL;
  /* Avoid infinite recursion when calling __sfp  for _GLOBAL_REENT.  The
     problem is that __sfp checks for _GLOBAL_REENT->__sdidinit and calls
     __sinit if it's 0. */
  if (s == _GLOBAL_REENT)
    s->__sdidinit = 1;
  s->_stdin = __sfp(s);
  s->_stdout = __sfp(s);
  s->_stderr = __sfp(s);
#endif

  std (s->_stdin,  __SRD, 0, s);


If _REENT_SMALL is not defined, where is s->_stdout initialized before the call to __sinit()?

-- 
John Wilkes | AMD Research |  john.wilkes@amd.com | office: +1 425.586.6412 (x26412)

-----Original Message-----
From: Wilkes, John 
Sent: Saturday, July 09, 2016 10:46 AM
To: newlib@sourceware.org
Cc: Wilkes, John
Subject: memory corruption problem

I am using a gcc-6.1.0 and newlib-2.4.0 tool chain. FreeRTOS builds with this tool chain and runs all the FreeRTOS demos, so think the newlib port is pretty solid.

However, when running a bare metal program (no OS), I get some memory corruption; a critical variable is overwritten with garbage. I traced the problem to the stdout __FILE pointer.

It looks like the stdout __FILE struct is initialized in _sinit, and "__FILE *_stdout" in the _reent stuct points to the critical variable (i.e. same address). The trashed variable has a fixed address visible in "nm" output, so it doesn't move.

Where in the newlib code is the stdout  __FILE struct allocated/created?

This is a new port with primitive debugging, i.e. no gdb support yet, and no shiny eclipse IDE.

Thanks for any help/insight/suggestions!

John

-- 
John Wilkes | AMD Research |  john.wilkes@amd.com | office: +1 425.586.6412 (x26412)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: memory corruption problem
  2016-07-11 16:13 ` Wilkes, John
@ 2016-07-12  5:27   ` Sebastian Huber
  2016-07-12 19:38     ` Wilkes, John
  0 siblings, 1 reply; 4+ messages in thread
From: Sebastian Huber @ 2016-07-12  5:27 UTC (permalink / raw)
  To: Wilkes, John, newlib



On 11/07/16 18:13, Wilkes, John wrote:
> If _REENT_SMALL is defined, the __sinit(struct _reent *s) function sets s->stdout:
>
> #ifndef _REENT_SMALL
>    s->__sglue._niobs = 3;
>    s->__sglue._iobs = &s->__sf[0];
> #else
>    s->__sglue._niobs = 0;
>    s->__sglue._iobs = NULL;
>    /* Avoid infinite recursion when calling __sfp  for _GLOBAL_REENT.  The
>       problem is that __sfp checks for _GLOBAL_REENT->__sdidinit and calls
>       __sinit if it's 0. */
>    if (s == _GLOBAL_REENT)
>      s->__sdidinit = 1;
>    s->_stdin = __sfp(s);
>    s->_stdout = __sfp(s);
>    s->_stderr = __sfp(s);
> #endif
>
>    std (s->_stdin,  __SRD, 0, s);
>
>
> If _REENT_SMALL is not defined, where is s->_stdout initialized before the call to __sinit()?

For RTEMS we use something like this:

https://git.rtems.org/rtems/tree/cpukit/libcsupport/src/newlibc_reent.c

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: memory corruption problem
  2016-07-12  5:27   ` Sebastian Huber
@ 2016-07-12 19:38     ` Wilkes, John
  0 siblings, 0 replies; 4+ messages in thread
From: Wilkes, John @ 2016-07-12 19:38 UTC (permalink / raw)
  To: newlib; +Cc: Wilkes, John

Thank you for the helpful replies; they guided me to the root cause, which was my linker script. I hadn't accounted for .bss.* sections; they were placed after my _end symbol, so malloc created the stdout buffer on top of some variables.

If I'd looked at the output of "nm" first, I might have noticed that "_end" wasn't at the very end.  ;-)

John

-----Original Message-----
From: Sebastian Huber [mailto:sebastian.huber@embedded-brains.de] 
Sent: Monday, July 11, 2016 10:28 PM
To: Wilkes, John; newlib@sourceware.org
Subject: Re: memory corruption problem



On 11/07/16 18:13, Wilkes, John wrote:
> If _REENT_SMALL is defined, the __sinit(struct _reent *s) function sets s->stdout:
>
> #ifndef _REENT_SMALL
>    s->__sglue._niobs = 3;
>    s->__sglue._iobs = &s->__sf[0];
> #else
>    s->__sglue._niobs = 0;
>    s->__sglue._iobs = NULL;
>    /* Avoid infinite recursion when calling __sfp  for _GLOBAL_REENT.  The
>       problem is that __sfp checks for _GLOBAL_REENT->__sdidinit and calls
>       __sinit if it's 0. */
>    if (s == _GLOBAL_REENT)
>      s->__sdidinit = 1;
>    s->_stdin = __sfp(s);
>    s->_stdout = __sfp(s);
>    s->_stderr = __sfp(s);
> #endif
>
>    std (s->_stdin,  __SRD, 0, s);
>
>
> If _REENT_SMALL is not defined, where is s->_stdout initialized before the call to __sinit()?

For RTEMS we use something like this:

https://git.rtems.org/rtems/tree/cpukit/libcsupport/src/newlibc_reent.c

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-07-12 19:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-09 17:46 memory corruption problem Wilkes, John
2016-07-11 16:13 ` Wilkes, John
2016-07-12  5:27   ` Sebastian Huber
2016-07-12 19:38     ` Wilkes, John

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).