Discussion:
printf() stops working after some time
Josef Wolf
2018-10-19 10:19:57 UTC
Permalink
Hello,

I am using newlib (and its printf) for more than 15 years now.

Now I upgraded to 3.0.0 and see that printf() stops working once write()
returns an error. Looks like printf() sets an error flag on the stream which
needs to be cleared by clearerr().

Unfortunaltey, GCC optimizes printf calls with constant format strings to use
puts() instead of printf. And puts() does NOT honor this error flag.

The result is that, once write() returns an error, only those optimized
printf() 'calls' will be output.

Why are printf/puts inconsisten on the error handling?

Is there a way to "auto-clear" this error flag?

I have not seen this in older newlib releases.


PS: As I investigated the above issue, I've seen that printf() and friends are
using malloc/realloc and things. I'm getting pretty nervous about malloc
usage, since this is an embedded system which is supposed to run for
really long term (years/decades) and fragmentation would be a major issue.

Is it possible to disable malloc usage when compiling newlib?
--
Josef Wolf
***@raven.inka.de
Jie Zheng
2018-10-19 10:33:20 UTC
Permalink
Oh that's sad to hear.

On 10/19/18, 6:20 PM, "newlib-***@sourceware.org on behalf of Josef Wolf" <newlib-***@sourceware.org on behalf of ***@raven.inka.de> wrote:

Hello,

I am using newlib (and its printf) for more than 15 years now.

Now I upgraded to 3.0.0 and see that printf() stops working once write()
returns an error. Looks like printf() sets an error flag on the stream which
needs to be cleared by clearerr().

Unfortunaltey, GCC optimizes printf calls with constant format strings to use
puts() instead of printf. And puts() does NOT honor this error flag.

The result is that, once write() returns an error, only those optimized
printf() 'calls' will be output.

Why are printf/puts inconsisten on the error handling?

Is there a way to "auto-clear" this error flag?

I have not seen this in older newlib releases.


PS: As I investigated the above issue, I've seen that printf() and friends are
using malloc/realloc and things. I'm getting pretty nervous about malloc
usage, since this is an embedded system which is supposed to run for
really long term (years/decades) and fragmentation would be a major issue.

Is it possible to disable malloc usage when compiling newlib?

--
Josef Wolf
***@raven.
Josef Wolf
2018-10-23 05:45:29 UTC
Permalink
No opinions on this one?
Post by Josef Wolf
Hello,
I am using newlib (and its printf) for more than 15 years now.
Now I upgraded to 3.0.0 and see that printf() stops working once write()
returns an error. Looks like printf() sets an error flag on the stream which
needs to be cleared by clearerr().
Unfortunaltey, GCC optimizes printf calls with constant format strings to use
puts() instead of printf. And puts() does NOT honor this error flag.
The result is that, once write() returns an error, only those optimized
printf() 'calls' will be output.
Why are printf/puts inconsisten on the error handling?
Is there a way to "auto-clear" this error flag?
I have not seen this in older newlib releases.
PS: As I investigated the above issue, I've seen that printf() and friends are
using malloc/realloc and things. I'm getting pretty nervous about malloc
usage, since this is an embedded system which is supposed to run for
really long term (years/decades) and fragmentation would be a major issue.
Is it possible to disable malloc usage when compiling newlib?
--
Josef Wolf
--
Josef Wolf
***@raven.inka.de
Keith Packard
2018-10-23 17:11:16 UTC
Permalink
Post by Josef Wolf
PS: As I investigated the above issue, I've seen that printf() and friends are
using malloc/realloc and things. I'm getting pretty nervous about malloc
usage, since this is an embedded system which is supposed to run for
really long term (years/decades) and fragmentation would be a major issue.
I had similar concerns, along with concerns about large RAM requirements
and have replaced the whole stdio section of newlib with one from the
GCC AVR project which does no dynamic memory allocation and uses only a
few bytes of RAM for a bit of state.

https://salsa.debian.org/electronics-team/toolchains/newlib-nano
Post by Josef Wolf
Is it possible to disable malloc usage when compiling newlib?
Yes, using the above version.
--
-keith
Dave McGuire
2018-10-23 17:14:42 UTC
Permalink
Post by Keith Packard
Post by Josef Wolf
PS: As I investigated the above issue, I've seen that printf() and friends are
using malloc/realloc and things. I'm getting pretty nervous about malloc
usage, since this is an embedded system which is supposed to run for
really long term (years/decades) and fragmentation would be a major issue.
I had similar concerns, along with concerns about large RAM requirements
and have replaced the whole stdio section of newlib with one from the
GCC AVR project which does no dynamic memory allocation and uses only a
few bytes of RAM for a bit of state.
https://salsa.debian.org/electronics-team/toolchains/newlib-nano
Post by Josef Wolf
Is it possible to disable malloc usage when compiling newlib?
Yes, using the above version.
This is wonderful. Has this been/will this be integrated into the
standard newlib releases?

-Dave
--
Dave McGuire, AK4HZ
New Kensington, PA
Keith Packard
2018-10-23 19:14:05 UTC
Permalink
Post by Dave McGuire
This is wonderful. Has this been/will this be integrated into the
standard newlib releases?
I have posted a couple of notes about it, but there doesn't seem to be
much interest in the upstream project.

I have packaged it for debian, and (when it escapes the 'New' queue), it
will be available for general use there. I continue to track upstream
changes and merge them into this version.

It would be great to have it merged together so that users would have
the choice of a smaller system without having to go elsewhere, but I
also understand the ongoing costs of incorporating code into a project
of this size.
--
-keith
Josef Wolf
2018-10-23 20:40:01 UTC
Permalink
Post by Keith Packard
Post by Dave McGuire
This is wonderful. Has this been/will this be integrated into the
standard newlib releases?
I have posted a couple of notes about it, but there doesn't seem to be
much interest in the upstream project.
I guess the gcc based code is gpl and as thus not compatible with newlib's
(mostly?) bsd style license?
--
Josef Wolf
***@raven.inka.de
Keith Packard
2018-10-23 21:43:09 UTC
Permalink
Post by Josef Wolf
I guess the gcc based code is gpl and as thus not compatible with newlib's
(mostly?) bsd style license?
Nope, the AVR libc bits are all under a similar BSD compatible license.

Oh, in order to avoid messing up the regular library, I created a
parallel meson-based build system for this work. That means I'm not
touching any upstream files when switching to this new stdio code, which
makes merging upstream changes in quite simple.
--
-keith
Dave McGuire
2018-10-24 18:37:14 UTC
Permalink
Post by Keith Packard
Post by Dave McGuire
This is wonderful. Has this been/will this be integrated into the
standard newlib releases?
I have posted a couple of notes about it, but there doesn't seem to be
much interest in the upstream project.
That's unfortunate. I wonder why that would be.
Post by Keith Packard
I have packaged it for debian, and (when it escapes the 'New' queue), it
will be available for general use there. I continue to track upstream
changes and merge them into this version.
It would be great to have it merged together so that users would have
the choice of a smaller system without having to go elsewhere, but I
also understand the ongoing costs of incorporating code into a project
of this size.
I agree 100%. I use newlib all over the place, and would love this
enhancement.

-Dave
--
Dave McGuire, AK4HZ
New Kensington, PA
Josef Wolf
2018-10-26 08:27:42 UTC
Permalink
Hallo again,

this thread has drifted to the malloc() issue.
Post by Josef Wolf
Why are printf/puts inconsisten on the error handling?
Is there a way to "auto-clear" this error flag?
I have not seen this in older newlib releases.
--
Josef Wolf
***@raven.inka.de
Jeff Johnston
2018-10-30 23:09:38 UTC
Permalink
Hi Josef,

Can you provide more details about the original error? What does perror()
say after the call?
If it is a write error, do you know what the underlying write error is?

Also, what are your configuration options?

Looking at the vfprintf.c code, there is no check for the _SERR flag being
set so it isn't blatantly obvious why this problem is occurring
for you.
.
-- Jeff J.
Post by Josef Wolf
Hallo again,
this thread has drifted to the malloc() issue.
Post by Josef Wolf
Why are printf/puts inconsisten on the error handling?
Is there a way to "auto-clear" this error flag?
I have not seen this in older newlib releases.
--
Josef Wolf
Josef Wolf
2018-10-31 12:31:45 UTC
Permalink
Hello,
Post by Jeff Johnston
Can you provide more details about the original error? What does perror()
say after the call?
perror says "Success". =:-()
Post by Jeff Johnston
If it is a write error, do you know what the underlying write error is?
write() returns 0, because the rts/cts handshake stopped the serial line and
its output buffer is full.
Post by Jeff Johnston
Also, what are your configuration options?
--enable-install-libbfd
--enable-languages=c
--with-gnu-ld
--with-gnu-as
--with-newlib
--with-system-zlib
--enable-commonbfdlib
--enable-interwork
--disable-shared
--disable-libssp
--nfp
--gas
--v
--target=m68k-unknown-elf

I use the same set of options to compile binutils, gcc and newlib.
Post by Jeff Johnston
Looking at the vfprintf.c code, there is no check for the _SERR flag being
set so it isn't blatantly obvious why this problem is occurring
for you.
Yes, its somewhat strange. I've not seen this behavior in older newlib
releases.
--
Josef Wolf
***@raven.inka.de
Loading...