Bug in stdio using dynamic_reent

J. Johnston jjohnstn@redhat.com
Wed Apr 2 22:40:00 GMT 2003


Grant,

Sorry, haven't seen this.  If I run this (minus the IO_Init()) with my x86-linux
newlib build which uses __DYNAMIC_REENT__, it outputs what glibc does:

----Testing default process----
A
Hello, BWorld!
CAnd again I say hello!D
----Testing process 1----
E
Hello, FWorld!
GAnd again I say hello!H
----Testing process 2----
I
Hello, JWorld!
KAnd again I say hello!L
----Testing default process----
M
Hello, NWorld!
OAnd again I say hello!P

Have you tried debugging printf to see how the buffer is being filled?
What does your IO_Init() routine do?

-- Jeff J.

Likely, Grant wrote:
> I've got newlib compiled with __DYNAMIC_REENT__ and REENT_SYSCALLS_PROVIDED
> defined and __getreent() commented out.  If I link it with the following
> code and run it the putchar() and printf() output is out of order (the
> putchar is unbuffered, but the printf is).  If I don't call setvbuf, then
> the printf works, bug putchar doesn't output anything at all.  Has anyone
> else seen this behaviour?
> 
> Thanks,
> g.
> 
> /**********************************************************************
> *
> *  File:       main.c
> *
> *  Date:       Dec, 2001
> *
> *  Author:     Henk Kroon
> *
> *  Project:    BIDS HTS Coldfire
> *
> *  Purpose:    Sample main() for object debugging
> *  
> *  Copyright (c) Computing Devices Canada (2001)
> *
> *  Updated:   
> *
> *  Date        Version     Author         Changes
> *  ----------  ---------   ------------   ----------------------------
> *  2001/12/01  1.0         Henk Kroon     Creation
> *
> **********************************************************************/
> 
> // *******************************
> // Include files
> // *******************************
> #include <reent.h>
> #include <stdlib.h>
> #include <stdio.h>
> 
> const int rovar = 0x1234;
> int rwvar = 0x5678;
> int blank_var;
> 
> /*
>  * Reentrancy support
>  */
> struct _reent impure1 = _REENT_INIT(impure1);
> struct _reent impure2 = _REENT_INIT(impure2);
> struct _reent *curr_impure_ptr = &impure1;
> 
> struct _reent *__getreent(void)
> {
>     return curr_impure_ptr;
> }
> 
> void init_file(__FILE *f)
> {
>     f->_p = _NULL;
>     f->_r = 0;
>     f->_w = 0;
>     f->_flags = 0;
>     f->_file = 0;
>     f->_lbfsize = 0;
>     f->_data = _NULL;
> }
> 
> void printtest(int off)
> {
>     putchar('A'+off);
>     printf("\r\nHello, ");
>     putchar('B'+off);
>     printf("World!\r\n");
>     putchar('C'+off);
>     printf("And again I say hello!");
>     putchar('D'+off);
> }
> int main( void )
> {
>     char *msg;
> 
>     IO_Init();
> 
>     msg = "\r\n----Testing default process----\r\n";
>     curr_impure_ptr = _impure_ptr;
>     _write_r(NULL, 0, msg, strlen(msg));
>     setvbuf(stdout, NULL, _IONBF, 0);
>     printtest(0);
> 
>     msg = "\r\n----Testing process 1----\r\n";
>     curr_impure_ptr = &impure1;
>     _write_r(NULL, 0, msg, strlen(msg));
>     setvbuf(stdout, NULL, _IONBF, 0);
>     printtest(4);
> 
>     msg = "\r\n----Testing process 2----\r\n";
>     curr_impure_ptr = &impure2;
>     _write_r(NULL, 0, msg, strlen(msg));
>     setvbuf(stdout, NULL, _IONBF, 0);
>     printtest(8);
> 
>     msg = "\r\n----Testing default process----\r\n";
>     curr_impure_ptr = _impure_ptr;
>     _write_r(NULL, 0, msg, strlen(msg));
>     //setvbuf(stdout, NULL, _IONBF, 0);
>     printtest(12);
> 
>     msg = "\r\n----Flushing default process----\r\n";
>     curr_impure_ptr = _impure_ptr;
>     fflush(stdout);
>     msg = "\r\n----Flushing default process----\r\n";
>     curr_impure_ptr = &impure1;
>     fflush(stdout);
>     msg = "\r\n----Flushing default process----\r\n";
>     curr_impure_ptr = &impure2;
>     fflush(stdout);
>     while(1);
> }
> 
> 




More information about the Newlib mailing list