This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Is this a bug?
- From: massimiliano cialdi <massimiliano dot cialdi at powersoft dot it>
- To: newlib at sourceware dot org
- Date: Wed, 24 May 2017 16:10:24 +0200
- Subject: Is this a bug?
- Authentication-results: sourceware.org; auth=none
- Authentication-results: sourceware.org; dkim=none (message not signed) header.d=none;sourceware.org; dmarc=none action=none header.from=powersoft.it;
- Spamdiagnosticmetadata: NSPM
- Spamdiagnosticoutput: 1:99
I'm experiencing a problem with newlib (tag newlib-snapshot-20160923,
but I think it is the same in master):
file newlib/libc/stdio/nano-vfprintf.c line 401:
394 _NOINLINE_STATIC int
395 _DEFUN(__sfputc_r, (ptr, c, fp),
396 struct _reent *ptr _AND
397 int c _AND
398 FILE *fp)
399 {
400 if (--fp->_w >= 0 || (fp->_w >= fp->_lbfsize && (char)c != '\n'))
401 return (*fp->_p++ = c);
402 else
403 return (__swbuf_r(ptr, c, fp));
404 }
fp is NULL. On my microcontroller (STM32F410RB) address 0x00000000 is
valid, but not mapped to RAM. fp->_p is an invalid address, so the
instruction raise a busfault.
I have investigated and I think the problem is in file
newlib/libc/stdio/findfp.c function __sinit()
207 _VOID
208 _DEFUN(__sinit, (s),
209 struct _reent *s)
210 {
211 __sinit_lock_acquire ();
212
213 if (s->__sdidinit)
214 {
215 __sinit_lock_release ();
216 return;
217 }
218
219 /* make sure we clean up on exit */
220 s->__cleanup = _cleanup_r; /* conservative */
221
222 s->__sglue._next = NULL;
223 #ifndef _REENT_SMALL
224 s->__sglue._niobs = 3;
225 s->__sglue._iobs = &s->__sf[0];
226 #else
227 s->__sglue._niobs = 0;
228 s->__sglue._iobs = NULL;
229 /* Avoid infinite recursion when calling __sfp for
_GLOBAL_REENT. The
230 problem is that __sfp checks for _GLOBAL_REENT->__sdidinit
and calls
231 __sinit if it's 0. */
232 if (s == _GLOBAL_REENT)
233 s->__sdidinit = 1;
234 s->_stdin = __sfp(s);
235 s->_stdout = __sfp(s);
236 s->_stderr = __sfp(s);
237 #endif
238
239 std (s->_stdin, __SRD, 0, s);
240
241 /* On platforms that have true file system I/O, we can verify
242 whether stdout is an interactive terminal or not, as part of
243 __smakebuf on first use of the stream. For all other platforms,
244 we will default to line buffered mode here. Technically, POSIX
245 requires both stdin and stdout to be line-buffered, but tradition
246 leaves stdin alone on systems without fcntl. */
247 #ifdef HAVE_FCNTL
248 std (s->_stdout, __SWR, 1, s);
249 #else
250 std (s->_stdout, __SWR | __SLBF, 1, s);
251 #endif
252
253 /* POSIX requires stderr to be opened for reading and writing, even
254 when the underlying fd 2 is write-only. */
255 std (s->_stderr, __SRW | __SNBF, 2, s);
256
257 s->__sdidinit = 1;
258
259 __sinit_lock_release ();
260 }
at lines 234, 235, 236: pointers are assigned to stdin, stdout and
stderr, but I have no room space (actually I use heap_4 allocatore from
FreeRTOS, that uses almost all free memory). __sfp() returns NULL, but
no check is done. The subsequent call to std() function uses these NULL
pointer, that I think is unsafe behaviour.
Unfortunately I do not know what the expected behavior should be in case
__sfp() returns NULL.
Is this a bug, or am I wrong in uses of newlib-nano in this context
(embedded system with FreeRTOS, heap_4 allocator, and uses of printf())?
There is a way to preallocate memory? How to pass to framework?
best regards
--
Powersoft logo <http://www.powersoft.it>
*Massimiliano Cialdi |*Senior Firmware Engineer
*skype:* mci.pws *| email:* massimiliano.cialdi@powersoft.it
<mailto:massimiliano.cialdi@powersoft.it>
*HQ Italy:* Via E. Conti, 5 *|* 50018 Scandicci (FI) Italy
*direct phone:* +39 055 0153429 *| Fax:* +39 055 735 6235
*web site:* www.powersoft.it <http://www.powersoft.it>
Green Audio Power