Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Printing to stderr attempts a write into flash #176

Open
AlessandroA opened this issue Mar 4, 2016 · 2 comments
Open

Printing to stderr attempts a write into flash #176

AlessandroA opened this issue Mar 4, 2016 · 2 comments
Labels

Comments

@AlessandroA
Copy link

A call of the form:

fprintf(stderr, "Some error: %d", 42);

causes a write to flash, as stderr is defined as __sf_fake_stderr, a symbol in flash.

Writes to flash through a str instruction do not trigger a fault, so the instruction is run without problems (of course the write is not performed).

Note:

This was observed while the libC had not completed its initialization.

The following is a simplified backtrace.

#0  0x000141ea in __swsetup_r ()
#1  0x00013398 in _vfprintf_r ()
#2  0x000130b6 in fprintf ()
#3  0x00009c38 in core_util_assert_internal (expr=0x15ce8 "primask & 0x1", file=0x15c88 "/Users/aleang01/code/AlessandroA/uvisor-helloworld/yotta_modules/core-util/source/critical.c", line=61,
    msg=0x0 <__isr_vector>)
#4  0x00009b92 in core_util_critical_section_exit () at /Users/aleang01/code/AlessandroA/uvisor-helloworld/yotta_modules/core-util/source/critical.c:61
#5  0x00008858 in mbed::util::CriticalSectionLock::~CriticalSectionLock (this=0x1fffad14, __in_chrg=<optimized out>)
#6  0x000148c0 in mbed::util::atomic_cas<unsigned long> (ptr=0x1fffafd8 <mbed_sbrk_diff>, expectedCurrentValue=0x1fffad3c, desiredValue=212480)
#7  0x0001479a in mbed_sbrk (size=1968)
#8  0x0000f100 in sys_alloc (m=0x1fffb868 <_gm_>, nb=432)
#9  0x00011076 in dlmalloc (bytes=428)
#10 0x0000e024 in mbed_ualloc_internal (bytes=428, traits=..., caller=0x1495b <__wrap__malloc_r+22>)
#11 0x0000e090 in mbed_ualloc (bytes=428, traits=...)
#12 0x0001495a in __wrap__malloc_r (r=0x1fffaf68 <impure_data>, size=428)
#13 0x00014af8 in __sfmoreglue ()
#14 0x00012fca in __sfp ()
#15 0x00012f5a in __sinit ()
#16 0x00012faa in __sfp ()
#17 0x00013028 in _fopen_r ()
#18 0x00007364 in mbed::Stream::Stream (this=0x1fffb134 <pc+212>, name=0x0 <__isr_vector>)
#19 0x000072aa in mbed::Serial::Serial (this=0x1fffb060 <pc>, tx=PTB17, rx=PTB16, name=0x0 <__isr_vector>)
#20 0x00006e44 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535)
#21 0x00006ec2 in _GLOBAL__sub_I___reserved_stack ()
#22 0x0001326e in __libc_init_array ()
#23 0x000062ee in _start ()

In that case, the offending write was done in __swsetup_r:

strh r3, [r4, #12]

with r4 = 0x16970, which is in flash.

In case it was confirmed that the error only occurs at initialization time (stderr is set correctly after that), this still needs fixing as uVisor will throw an exception on an attempt to write to flash.

@bremoran @0xc0170 @bogdanm

@ciarmcom
Copy link
Member

ciarmcom commented Mar 4, 2016

ARM Internal Ref: IOTSFW-2222

@0xc0170
Copy link
Contributor

0xc0170 commented Mar 4, 2016

I was going through the backtrace, because I would assume that stderr would get initialized first time it's used. I am going through newlib nano (https://github.com/32bitmicro/newlib-nano-1.0) ,the code snippets are taken from there.

The last function (top in the backtrace) :

int
_DEFUN(__swsetup_r, (ptr, fp),
       struct _reent *ptr _AND
       register FILE * fp)
{
  /* Make sure stdio is set up.  */

  CHECK_INIT (_REENT, fp);
// more code here, not relevant probably.....
#ifdef _REENT_SMALL
#define CHECK_INIT(ptr, fp) \
  do                        \
    {                       \
      if ((ptr) && !(ptr)->__sdidinit)      \
    __sinit (ptr);              \
      if ((fp) == (FILE *)&__sf_fake_stdin) \
    (fp) = _stdin_r(ptr);           \
      else if ((fp) == (FILE *)&__sf_fake_stdout) \
    (fp) = _stdout_r(ptr);          \
      else if ((fp) == (FILE *)&__sf_fake_stderr) \
    (fp) = _stderr_r(ptr);          \
    }                       \
  while (0)
#else /* !_REENT_SMALL   */
#define CHECK_INIT(ptr, fp) \
  do                        \
    {                       \
      if ((ptr) && !(ptr)->__sdidinit)      \
    __sinit (ptr);              \
    }                       \
  while (0)
#endif /* !_REENT_SMALL  */

The version of newlib-nano shipped in the gcc arm should be without _REENT_SMALL. Anyway in both cases, it should set fp to the real stderr in our case. We might need to fire up gdb to see more.

Update: i overlooked the line 15 in the backtrace, it seems stdio gets into initialization phase, where it allocates and where it fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants