core/dynamo.c
/* FIXME: even with -single_privileged_thread, we aren't fully protected,
 * because there's a window between us resuming the other threads and
 * returning to our caller where another thread could clobber our return
 * address or something.
 */
even with -single_privileged_thread, we aren't fully protected,
because there's a window between us resuming the other threads and
returning to our caller where another thread could clobber our return
address or something.
even with - single_privileged_thread we aren ' t fully protected because there ' s a window between us resuming the other threads and returning to our caller where another thread could clobber our return address or something .
static void
dynamorio_protect(void)
{
    ASSERT(SELF_PROTECT_ON_CXT_SWITCH);
    LOG(GLOBAL, LOG_DISPATCH, 4, "dynamorio_protect thread=%d\n", get_thread_id());
    mutex_lock(&protect_info->lock);
    ASSERT(protect_info->num_threads_unprot > 0);
    if (protect_info->num_threads_unprot <= 0) {
        protect_info->num_threads_unprot = 0;
        mutex_unlock(&protect_info->lock);
        return;
    }
    protect_info->num_threads_unprot--;
    if (protect_info->num_threads_unprot > 0) {
        LOG(GLOBAL, LOG_DISPATCH, 4, "dynamorio_protect: not last thread => nop\n");
        mutex_unlock(&protect_info->lock);
        return;
    }
    SELF_PROTECT_GLOBAL(READONLY);
    if (INTERNAL_OPTION(single_privileged_thread)) {
        if (protect_info->num_threads_suspended > 0) {
            thread_record_t *tr;
            int i, num = 0;
            for (i = 0; i < HASHTABLE_SIZE(ALL_THREADS_HASH_BITS); i++) {
                for (tr = all_threads[i]; tr; tr = tr->next) {
                    if (tr->under_dynamo_control) {
                        thread_resume(all_threads[i]);
                        num++;
                    }
                }
            }
            ASSERT(num == protect_info->num_threads_suspended);
            protect_info->num_threads_suspended = 0;
        }
        mutex_unlock(&thread_initexit_lock);
    }
    SELF_PROTECT_DATASEC(DATASEC_FREQ_PROT);
    SELF_PROTECT_DATASEC(DATASEC_CXTSW_PROT);
    mutex_unlock(&protect_info->lock);
}
static void dynamorio_protect ( void ) { ASSERT ( SELF_PROTECT_ON_CXT_SWITCH ) ; LOG ( GLOBAL , LOG_DISPATCH , 4 , " \n " , get_thread_id ( ) ) ; mutex_lock ( & protect_info -> lock ) ; ASSERT ( protect_info -> num_threads_unprot > 0 ) ; if ( protect_info -> num_threads_unprot <= 0 ) { protect_info -> num_threads_unprot = 0 ; mutex_unlock ( & protect_info -> lock ) ; return ; } protect_info -> num_threads_unprot -- ; if ( protect_info -> num_threads_unprot > 0 ) { LOG ( GLOBAL , LOG_DISPATCH , 4 , " \n " ) ; mutex_unlock ( & protect_info -> lock ) ; return ; } SELF_PROTECT_GLOBAL ( READONLY ) ; if ( INTERNAL_OPTION ( single_privileged_thread ) ) { if ( protect_info -> num_threads_suspended > 0 ) { thread_record_t * tr ; int i , num = 0 ; for ( i = 0 ; i < HASHTABLE_SIZE ( ALL_THREADS_HASH_BITS ) ; i ++ ) { for ( tr = all_threads [ i ] ; tr ; tr = tr -> next ) { if ( tr -> under_dynamo_control ) { thread_resume ( all_threads [ i ] ) ; num ++ ; } } } ASSERT ( num == protect_info -> num_threads_suspended ) ; protect_info -> num_threads_suspended = 0 ; } mutex_unlock ( & thread_initexit_lock ) ; } SELF_PROTECT_DATASEC ( DATASEC_FREQ_PROT ) ; SELF_PROTECT_DATASEC ( DATASEC_CXTSW_PROT ) ; mutex_unlock ( & protect_info -> lock ) ; }
FIXME: even with -single_privileged_thread, we aren't fully protected,
 because there's a window between us resuming the other threads and
 returning to our caller where another thread could clobber our return
 address or something.
FIXME : even with - single_privileged_thread we aren ' t fully protected because there ' s a window between us resuming the other threads and returning to our caller where another thread could clobber our return address or something .
/* we don't protect local heap here, that's done lazily */ /* FIXME: nice to also catch double enters but would need to track more info */ /* Defensive code to prevent crashes from double exits (the theory
         * for case 7631/8030).  However, this precludes an extra exit+enter
         * pair from working properly (though an extra enter+exit will continue
         * to work), though such a pair would have crashed if another thread
         * had entered in the interim anyway.
         */ /* other threads still in DR, cannot protect global memory */ /* FIXME: want to resume threads and allow thread creation only
         * _after_ protect data segment, but lock is in data segment!
         */ /* we do not need to grab the all_threads_lock because
             * no threads can be added or removed so who cares if we
             * access the data structure simultaneously with another
             * reader of it
             */ /* thread init/exit can proceed now */ /* FIXME case 8073: temporary until we put in unprots in the
     * right places.  if we were to leave this here we'd want to combine
     * .fspdata and .cspdata for more efficient prot changes.
     */