ts-7000
[Top] [All Lists]

[ts-7000] Bug in libsdtc++ (?)

To:
Subject: [ts-7000] Bug in libsdtc++ (?)
From: Christian Gagneraud <>
Date: Fri, 23 Jan 2009 17:50:48 +0000
Hi all,

I'm using a ts7800, and discover (what i think is) a bug when using 
the OABI cross-toolchain . The bug only shows when a thread run with 
the SCHED_FIFO policy.
If i use the EABI toolchain, the bug never show.
If i build natively the test program on the ts7800, the bug shows.

Attached is an example program that will show the bug.
In short, it seems there's a race condition in the libstdc++, 
actually, there is at least one in std::iostream (showed with the 
attach program), and another one in std::string (i was not able to 
reproduce that one with a simple program, but i notice that threads 
was blocked in std::string::_Rep::_M_refcopy and/or 
std::string::_Rep::_M_dispose).

When 2 threads are busy writing on std::cout, the program will ends 
with a screwed-up output, where each thread is slowly writing one 
character at a time, one thread after each other. The normal behavior 
would be to "quickly" write a block of characters one after each other.


Does anyone on this mailing list had encourted this kind of problem in 
the past?

Would Technologic system's people consider investigating this? And 
possibly come with a fix?

With best regards,
Chris

PS1: Here is a sample output from the test program:
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF200132 abcdefghijklmnopqrstuvwxyz
GHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
[...]
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ
ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVW1X9Y9Z7A1B6C 
DaEbFcGdHeIfJgKhLiMjNkOlPmQnRoSpTqUrVsWtXuYvZwAxByCzD
E7F2G0H0I3J5K LaMbNcOdPeQfRgShTiUjVkWlXmYnZoApBqCrDsEtFuGvHwIxJyKzL
M7N4O0P3Q0R8S TaUbVcWdXeYfZg
hijklAmBnCoDpEqFrGsHtIuJvKwLxMyNzO
P7Q1R0S0T1U3V WaXbYcZdAeBfCgDhEiFjGkHlImJnKoLpMqNrOsPtQuRvSwTxUyVzW
X7Y0Z0A0B1C0D EaFbGcHdIeJfKgLhMiNjOkPlQmRnSoTpUqVrWsXtYuZvAwBxCyDzE
F7G0H9I9J9K5L MaNbOcPdQeRfSgThUiVjWkXlYmZnAoBpCqDrEsFtGuHvIwJxKyLzM
N7O2P0Q0R0S5T UaVbWcXdYeZf
ghijAkBlCmDnEoFpGqHrIsJtKuLvMwNxOyPzQ
R7S0T9U9V3W7X YaZbAcBdCeDfEgFhGiHjIkJlKmLnMoNpOqPrQsRtSuTvUwVxWyXzY
Z7A0B0C0D2E8F GaHbIcJdKeLfMgNhOiPjQkRlSmTnUoVpWqXrYsZtAuBvCwDxEyFzG
H7I2J9K9L8M7N OaPbQcRdSeTfUgVhWiXjYkZlAmBnCoDpEqFrGsHtIuJvKwLxMyNzO
[...]


PS2: The following backtrace for both threads show that there are 
fighting for a mutex in the stdlib.

----

#0  0x40026d80 in __pthread_sigsuspend () from /lib/libpthread.so.0
#1  0x40025a7c in __pthread_wait_for_restart_signal () from 
/lib/libpthread.so.0
#2  0x40028b54 in __pthread_alt_lock () from /lib/libpthread.so.0
#3  0x400255a0 in pthread_mutex_lock () from /lib/libpthread.so.0
#4  0x400d66e0 in std::locale::locale () from /usr/lib/libstdc++.so.5
#5  0x400be1c0 in std::basic_filebuf<char, std::char_traits<char> 
 >::_M_convert_to_external ()
    from /usr/lib/libstdc++.so.5
#6  0x400be088 in std::basic_filebuf<char, std::char_traits<char> 
 >::_M_really_overflow ()
    from /usr/lib/libstdc++.so.5
#7  0x400bdf88 in std::basic_filebuf<char, std::char_traits<char> 
 >::overflow ()
    from /usr/lib/libstdc++.so.5
#8  0x40123030 in std::basic_streambuf<char, std::char_traits<char> 
 >::xsputn ()
    from /usr/lib/libstdc++.so.5
#9  0x4010efec in std::operator<< <char, std::char_traits<char>, 
std::allocator<char> > ()
    from /usr/lib/libstdc++.so.5
#10 0x000092e4 in routine_2 (arg=0x0) at test.cc:66
#11 0x40023fb0 in pthread_start_thread () from /lib/libpthread.so.0

----

#0  0x4002b6dc in nanosleep () from /lib/libpthread.so.0
#1  0x40028a90 in __pthread_acquire () from /lib/libpthread.so.0
#2  0x40028c60 in __pthread_alt_unlock () from /lib/libpthread.so.0
#3  0x4002519c in pthread_mutex_unlock () from /lib/libpthread.so.0
#4  0x400d6708 in std::locale::locale () from /usr/lib/libstdc++.so.5
#5  0x400be1c0 in std::basic_filebuf<char, std::char_traits<char> 
 >::_M_convert_to_external ()
    from /usr/lib/libstdc++.so.5
#6  0x400be088 in std::basic_filebuf<char, std::char_traits<char> 
 >::_M_really_overflow ()
    from /usr/lib/libstdc++.so.5
#7  0x400bdf88 in std::basic_filebuf<char, std::char_traits<char> 
 >::overflow ()
    from /usr/lib/libstdc++.so.5
#8  0x40123030 in std::basic_streambuf<char, std::char_traits<char> 
 >::xsputn ()
    from /usr/lib/libstdc++.so.5
#9  0x4010efec in std::operator<< <char, std::char_traits<char>, 
std::allocator<char> > ()
    from /usr/lib/libstdc++.so.5
#10 0x00009090 in routine_1 (arg=0x0) at test.cc:48
#11 0x40023fb0 in pthread_start_thread () from /lib/libpthread.so.0

----

------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/ts-7000/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/ts-7000/join
    (Yahoo! ID required)

<*> To change settings via email:
     
    

<*> To unsubscribe from this group, send an email to:
    

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/

/*
** @file test.cc
** @author Christian Gagneraud <> 
** @date Fri Jan 23 11:03:20 2009
**
** @brief
**
** With oabi, the programm will bug, not with the eabi toolchain:
** arm-linux-g++ -DSHOW_BUG=1 -Wall -g -O2 test.cc -static -lpthread -o test
** 
** Programs run OK with both oabi and eabi toochain:
** arm-linux-g++ -DSHOW_BUG=0 -Wall -g -O2 test.cc -static -lpthread -o test
*/

#include <iostream>
#include <iomanip> 
#include <string>

#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <assert.h>

#define ASSERT(cmd) do { int rc = cmd; assert (rc == 0); } while (0)

pthread_attr_t attr_1;
pthread_t thread_1;
void* routine_1 (void* arg)
{
  
  struct itimerval timer;
  sigset_t timersigset;
  int timersig = SIGALRM;
  timer.it_interval.tv_sec = 0;
  timer.it_interval.tv_usec = 200000; // 200 ms
  timer.it_value = timer.it_interval;
  ASSERT( sigemptyset(&timersigset) );
  ASSERT( sigaddset(&timersigset, timersig) );
  ASSERT( setitimer(ITIMER_REAL, &timer, NULL) );
  struct timeval before, now;
  ASSERT( gettimeofday (&before, NULL) );
  while (true)
    {
      ASSERT( sigwait(&timersigset, &timersig) );
      assert (timersig == SIGALRM);
      ASSERT( gettimeofday (&now, NULL) );      
      std::cout << std::setw(6)
                << ((now.tv_usec > before.tv_usec) ? (now.tv_usec - 
before.tv_usec) : (1000000L + now.tv_usec - before.tv_usec))
                << " abcdefghijklmnopqrstuvwxyz" << std::endl;
      before = now;
    }
  return NULL;
}


pthread_attr_t attr_2;
pthread_t thread_2;
void* routine_2 (void* arg)
{
  while (true)
    {
      std::string str;
      // The more we have to print on the screen, the more likely the
      // bug will show
      for (int i=0; i<5; ++i)
        str += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      std::cout << str << std::endl;
      
#ifdef SLEEP_MS
      // nanosleep () has the advantage of not affecting any signals
      // Here we sleep for between 1 and SLEEP_MS ms
      // The less we sleep here the sooner the bug will show...
      struct timespec tm;
      tm.tv_sec = 0;
      tm.tv_nsec = 1000*1000*(1 + (int) (SLEEP_MS * 1.0 * (rand() / (RAND_MAX + 
1.0))));
      int rc = nanosleep (&tm, NULL);
      if (rc != 0 && errno != EINTR)
        std::cout << "ERROR: " << rc << " " << errno
                  << " " << tm.tv_sec << "." << tm.tv_nsec << std::endl;
#endif
    }
}

void create_thread (pthread_t * p_thread, pthread_attr_t *p_attr,
                    void* (*routine)(void*),
                    int sched_policy = SCHED_OTHER,
                    int sched_priority = sched_get_priority_min(SCHED_OTHER))
{
  ASSERT( pthread_attr_init(p_attr) );
  ASSERT( pthread_attr_setschedpolicy(p_attr, sched_policy) );
  struct sched_param sparam;
  sparam.sched_priority = sched_priority;
  ASSERT( pthread_attr_setschedparam(p_attr, &sparam) );
  ASSERT( pthread_create (p_thread, p_attr, routine, NULL) );
}

int main (int argc, char **argv)
{
  // Threads will inherit our sigmask
  sigset_t mask, oldmask;
  sigemptyset(&mask);
  sigaddset(&mask, SIGALRM);
  ASSERT( pthread_sigmask(SIG_BLOCK, &mask, &oldmask) );

#if SHOW_BUG
  // Running with SCHED_FIFO will show the bug
  create_thread(&thread_1, &attr_1, routine_1, SCHED_FIFO,
                sched_get_priority_max(SCHED_FIFO)-2);
#else
  create_thread(&thread_1, &attr_1, routine_1);
#endif
  
  create_thread(&thread_2, &attr_2, routine_2);

  // We'll be blocked forever here...
  pthread_join (thread_1, NULL);
}
<Prev in Thread] Current Thread [Next in Thread>
  • [ts-7000] Bug in libsdtc++ (?), Christian Gagneraud <=
Admin

Disclaimer: Neither Andrew Taylor nor the University of NSW School of Computer and Engineering take any responsibility for the contents of this archive. It is purely a compilation of material sent by many people to the birding-aus mailing list. It has not been checked for accuracy nor its content verified in any way. If you wish to get material removed from the archive or have other queries about the archive e-mail Andrew Taylor at this address: andrewt@cse.unsw.EDU.AU