[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
C++ ctors, cdtest.exe, printf and termios oh my!
- Date: Wed, 4 Aug 1999 16:15:49 -0700 (PDT)
- From: tonya at ece.ubc.ca (Tony R. Ambardar)
- Subject: C++ ctors, cdtest.exe, printf and termios oh my!
Hello everyone,
I recently converted my BSP (ts_386ex) to ELF in order to get better
debug support and C++ exceptions working. However, I've run into a
problem with the cdtest.exe RTEMS sample. Basically, the program hangs
during the printf called from the first global ctor. On the console I
see only the first "H" of what should be "Hey I'm in
constructor...". For reference, I'm using egcs-1.1.2, binutils-2.9.1
(why do some people use 2.9.1.0.25?), and newlib-1.8.1, with the
latest RTEMS snapshot and patches.
I'll describe what I think I've figured out after following ~15 levels
of function calls from the printf down to rtems_termios_write and its
ilk, and hopefully this will ring bells for someone.
The following code fragment is from osend() in termios.c:
newHead = (newHead + 1) % RAW_OUTPUT_BUFFER_SIZE;
rtems_interrupt_disable (level);
while (newHead == tty->rawOutBufTail) {
tty->rawOutBufState = rob_wait;
rtems_interrupt_enable (level);
sc = rtems_semaphore_obtain (tty->rawOutBufSemaphore,
RTEMS_WAIT,
RTEMS_NO_TIMEOUT);
if (sc != RTEMS_SUCCESSFUL)
rtems_fatal_error_occurred (sc);
rtems_interrupt_disable (level);
}
tty->rawOutBuf[tty->rawOutBufHead] = *buf++;
tty->rawOutBufHead = newHead;
Once 64 characters have been sent by the printf in the global ctor,
the termios raw output buffer (size 64) will be full and newHead ==
tty->rawOutBufTail. Thus, the while loop spins and waits for a termios
device driver to output some characters from the raw buffer to the
serial port and update the volatile tty->rawOutBufTail variable.
It looks like no driver clears the buffer and this loop ends up
spinning forever. Why the ISR isn't working is not clear to me. The
same goes for why it only prints the first "H" of the printf call.
A few observations:
Global ctors are run in the _init() function, which is called in
boot_card(), between rtems_initialize_executive_early and
rtems_initialize_executive_late. Between these two initialize
functions, ISR's appear to be disabled. So it doesn't seem a good idea
to me to use printf statements in a global ctor when using interrupt
driven I/O. Note that the RTEMS cdtest.exe sample works perfectly for
me when I use printk() instead of printf(). How about making this a
permanent change?
Non-global ctors using printf() work fine.
A printf() call (with less than 64 chars) from a global ctor, followed
by another printf() from a non-global ctor, results in everything
working OK. Since the non-global ctor runs after
rtems_initialize_executive_late, this suggests that the latter
function fixes things up somehow. Not clear how...
I'd appreciate hearing from anyone with insight into this. I'm getting
frustrated to the point now where I'd rather just avoid printf in
global ctors, since otherwise C++ exceptions and ctors/dtors seem to
be working OK.
Thanks,
Tony Ambardar
____________________________________________________________
/ \
| Tony R. Ambardar | Department of Electrical & |
| M.Sc., M.Eng. | Computer Engineering |
| Email: tonya at ece.ubc.ca | University of British Columbia |
| Ph: (604) 822-2872 | 2356 Main Mall, Vancouver B.C. |
| Fax:(604) 822-5949 | V6T 1Z4 CANADA |
\____________________________________________________________/
p.s. Thanks to Rosimildo for his help getting the debugger working.
p.p.s. Has anyone else noticed weird source-line offsets when running
under GDB?