test_exception_storage.cpp revision 61b898e4f717ecb3ce6aaa2652f7da712452d693
161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <cstdlib>
261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <algorithm>
361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <iostream>
461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include <pthread.h>
561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#include "cxa_exception.hpp"
761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowtypedef __cxxabiv1::__cxa_eh_globals globals_t ;
961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
1061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowvoid *thread_code (void *parm) {
1161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    size_t *result = (size_t *) parm;
1261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    globals_t *glob1, *glob2;
1361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
1461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    glob1 = __cxxabiv1::__cxa_get_globals ();
1561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    if ( NULL == glob1 )
1661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        std::cerr << "Got null result from __cxa_get_globals" << std::endl;
1761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
1861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    glob2 = __cxxabiv1::__cxa_get_globals_fast ();
1961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    if ( glob1 != glob2 )
2061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        std::cerr << "Got different globals!" << std::endl;
2161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
2261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    *result = (size_t) glob1;
2361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    sleep ( 1 );
2461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    return parm;
2561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    }
2661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
2761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
2861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow#define NUMTHREADS  10
2961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowsize_t      thread_globals [ NUMTHREADS ] = { 0 };
3061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowpthread_t   threads        [ NUMTHREADS ];
3161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
3261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowvoid print_sizes ( size_t *first, size_t *last ) {
3361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    std::cout << "{ " << std::hex;
3461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( size_t *iter = first; iter != last; ++iter )
3561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        std::cout << *iter << " ";
3661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    std::cout << "}" << std::dec << std::endl;
3761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    }
3861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
3961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clowint main ( int argc, char *argv [] ) {
4061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    int retVal = 0;
4161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
4261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow//  Make the threads, let them run, and wait for them to finish
4361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( int i = 0; i < NUMTHREADS; ++i )
4461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        pthread_create( threads + i, NULL, thread_code, (void *) (thread_globals + i));
4561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( int i = 0; i < NUMTHREADS; ++i )
4661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        pthread_join ( threads [ i ], NULL );
4761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
4861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( int i = 0; i < NUMTHREADS; ++i )
4961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        if ( 0 == thread_globals [ i ] ) {
5061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            std::cerr << "Thread #" << i << " had a zero global" << std::endl;
5161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            retVal = 1;
5261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            }
5361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
5461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow//  print_sizes ( thread_globals, thread_globals + NUMTHREADS );
5561b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    std::sort ( thread_globals, thread_globals + NUMTHREADS );
5661b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    for ( int i = 1; i < NUMTHREADS; ++i ) {
5761b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow        if ( thread_globals [ i - 1 ] == thread_globals [ i ] )
5861b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            std::cerr << "Duplicate thread globals (" << i-1 << " and " << i << ")" << std::endl;
5961b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            retVal = 2;
6061b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow            }
6161b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow//  print_sizes ( thread_globals, thread_globals + NUMTHREADS );
6261b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow
6361b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    return retVal;
6461b898e4f717ecb3ce6aaa2652f7da712452d693Marshall Clow    }
65