Beispiel #1
0
BOOL RaiseExceptionOnAssert(RaiseOnAssertOptions option = rTestAndRaise)
{
    STATIC_CONTRACT_NOTHROW;
    STATIC_CONTRACT_GC_NOTRIGGER;
    STATIC_CONTRACT_DEBUG_ONLY;
    STATIC_CONTRACT_FORBID_FAULT;
    STATIC_CONTRACT_SUPPORTS_DAC;

    // ok for debug-only code to take locks
    CONTRACT_VIOLATION(TakesLockViolation);

    DWORD fRet = 0;

#if !defined(DACCESS_COMPILE)
    static ConfigDWORD fRaiseExceptionOnAssert;
    //
    // we don't want this config key to affect mscordacwks as well!
    //
    EX_TRY
    {
        fRet = fRaiseExceptionOnAssert.val(CLRConfig::INTERNAL_RaiseExceptionOnAssert);
    }
    EX_CATCH
    {
    }
    EX_END_CATCH(SwallowAllExceptions);

    if (option == rTestAndRaise && fRet != 0)
    {
        DoRaiseExceptionOnAssert(fRet);
    }
#endif // !DACCESS_COMPILE

    return fRet != 0;
}
Beispiel #2
0
BOOL DebugBreakOnAssert()
{
    STATIC_CONTRACT_NOTHROW;
    STATIC_CONTRACT_GC_NOTRIGGER;
    STATIC_CONTRACT_DEBUG_ONLY;
    STATIC_CONTRACT_FORBID_FAULT;
    STATIC_CONTRACT_SUPPORTS_DAC;

    // ok for debug-only code to take locks
    CONTRACT_VIOLATION(TakesLockViolation);

    BOOL fRet = FALSE;

#ifndef DACCESS_COMPILE  
    static ConfigDWORD fDebugBreak;
    //
    // we don't want this config key to affect mscordacwks as well!
    //
    EX_TRY
    {
        fRet = fDebugBreak.val(CLRConfig::INTERNAL_DebugBreakOnAssert);
    }
    EX_CATCH
    {
    }
    EX_END_CATCH(SwallowAllExceptions);
#endif // DACCESS_COMPILE

    return fRet;
}
Beispiel #3
0
int logf(const char* fmt, ...)
{
    va_list args;
    static bool logToEEfailed = false;
    int written = 0;
    //
    // We remember when the EE failed to log, because vlogf()
    // is very slow in a checked build.
    //
    // If it fails to log an LL_INFO1000 message once 
    // it will always fail when logging an LL_INFO1000 message.
    //
    if (!logToEEfailed)
    {
        va_start(args, fmt);
        if (!vlogf(LL_INFO1000, fmt, args))
            logToEEfailed = true;
        va_end(args);
    }
    
    if (logToEEfailed)
    {
        // if the EE refuses to log it, we try to send it to stdout
        va_start(args, fmt);
        written = logf_stdout(fmt, args);
        va_end(args);
    }
#if 0  // Enable this only when you need it
    else
    {
        //
        // The EE just successfully logged our message
        //
        static ConfigDWORD fJitBreakOnDumpToken;
        DWORD breakOnDumpToken = fJitBreakOnDumpToken.val(CLRConfig::INTERNAL_BreakOnDumpToken);
        static DWORD forbidEntry = 0;
        
        if ((breakOnDumpToken != 0xffffffff) && (forbidEntry == 0)) 
        {
            forbidEntry = 1;
            
            // Use value of 0 to get the dump
            static DWORD currentLine = 1;
            
            if (currentLine == breakOnDumpToken) 
            {
                assert(!"Dump token reached");
            }
            
            printf("(Token=0x%x) ", currentLine++);
            forbidEntry = 0;
        }
    }
#endif // 0
    va_end(args);

    return written;
}
Beispiel #4
0
BOOL NoGuiOnAssert()
{
    STATIC_CONTRACT_NOTHROW;
    STATIC_CONTRACT_GC_NOTRIGGER;
    STATIC_CONTRACT_DEBUG_ONLY;

    static ConfigDWORD fNoGui;
    return fNoGui.val(CLRConfig::INTERNAL_NoGuiOnAssert);
}
Beispiel #5
0
void noWayAssertAbortHelper(const char * cond, const char * file, unsigned line)
{
    // Show the assert UI.
    static ConfigDWORD fJitEnableNoWayAssert;
    if (fJitEnableNoWayAssert.val(CLRConfig::INTERNAL_JitEnableNoWayAssert))
    {
        assertAbort(cond, file, line);
    }
}
Beispiel #6
0
void  __cdecl   assertAbort(const char *why, const char *file, unsigned line)
{
    const char* msg = why;
    LogEnv* env = LogEnv::cur();
    const int BUFF_SIZE = 8192;
    char *buff = (char*)alloca(BUFF_SIZE);
    if (env->compiler) {
        _snprintf_s(buff, BUFF_SIZE, _TRUNCATE, "Assertion failed '%s' in '%s' (IL size %d)\n", why, env->compiler->info.compFullName, env->compiler->info.compILCodeSize);
        msg = buff;
    }
    printf("");         // null string means flush

#if FUNC_INFO_LOGGING
    if (Compiler::compJitFuncInfoFile != NULL)
    {
        fprintf(Compiler::compJitFuncInfoFile, "%s - Assertion failed (%s:%d - %s)\n",
            (env == NULL) ? "UNKNOWN" : env->compiler->info.compFullName,
            file,
            line,
            why);
    }
#endif // FUNC_INFO_LOGGING

    if (env->compHnd->doAssert(file, line, msg))
        DebugBreak(); 

#ifdef ALT_JIT
    // If we hit an assert, and we got here, it's either because the user hit "ignore" on the
    // dialog pop-up, or they set COMPLUS_ContinueOnAssert=1 to not emit a pop-up, but just continue.
    // If we're an altjit, we have two options: (1) silently continue, as a normal JIT would, probably
    // leading to additional asserts, or (2) tell the VM that the AltJit wants to skip this function,
    // thus falling back to the fallback JIT. Setting COMPLUS_AltJitSkipOnAssert=1 chooses this "skip"
    // to the fallback JIT behavior. This is useful when doing ASM diffs, where we only want to see
    // the first assert for any function, but we don't want to kill the whole ngen process on the
    // first assert (which would happen if you used COMPLUS_NoGuiOnAssert=1 for example).
    static ConfigDWORD fAltJitSkipOnAssert;
    if (fAltJitSkipOnAssert.val(CLRConfig::INTERNAL_AltJitSkipOnAssert) != 0)
    {
        fatal(CORJIT_SKIPPED);
    }
#elif defined(_TARGET_ARM64_)
    // TODO-ARM64-NYI: remove this after the JIT no longer asserts during startup
    //
    // When we are bringing up the new Arm64 JIT we set COMPLUS_ContinueOnAssert=1 
    // We only want to hit one assert then we will fall back to the interpreter.
    //
    static ConfigDWORD s_InterpreterFallback;

    bool interpreterFallback = (s_InterpreterFallback.val(CLRConfig::INTERNAL_InterpreterFallback) != 0);

    if (interpreterFallback)
    {
        fatal(CORJIT_SKIPPED);
    }
#endif 
}
Beispiel #7
0
unsigned SsaStressHashHelper()
{
    // hash = 0: turned off, hash = 1: use method hash, hash = *: use custom hash.
    static ConfigDWORD fJitSsaStress;
    unsigned hash = fJitSsaStress.val(CLRConfig::INTERNAL_JitSsaStress);

    if (hash == 0)
    {
        return hash;
    }
    if (hash == 1)
    {
        return GetTlsCompiler()->info.compMethodHash();
    }
    return ((hash >> 16) == 0) ? ((hash << 16) | hash) : hash;
}
Beispiel #8
0
void DECLSPEC_NORETURN fatal(int errCode)
{
#ifdef DEBUG
    if (errCode != CORJIT_SKIPPED) // Don't stop on NYI: use COMPLUS_AltJitAssertOnNYI for that.
    {
        static ConfigDWORD fDebugBreakOnVerificationFailure;
        if (fDebugBreakOnVerificationFailure.val(CLRConfig::INTERNAL_DebugBreakOnVerificationFailure))
        {
            DebugBreak();
        }
    }
#endif // DEBUG

    ULONG_PTR exceptArg = errCode;
    RaiseException(FATAL_JIT_EXCEPTION, EXCEPTION_NONCONTINUABLE, 1, &exceptArg);
    UNREACHABLE();
}
Beispiel #9
0
int logf_stdout(const char* fmt, va_list args)
{
    //
    // Fast logging to stdout
    //
    const int BUFF_SIZE = 8192;
    char buffer[BUFF_SIZE];
    int written = _vsnprintf_s(&buffer[0], BUFF_SIZE, _TRUNCATE, fmt, args);

    static ConfigDWORD fJitDumpToDebugger;
    if (fJitDumpToDebugger.val(CLRConfig::INTERNAL_JitDumpToDebugger))
    {
        OutputDebugStringA(buffer);
    }

    if (fmt[0] == 0)                // null string means flush
    {
        fflush(stdout);
    }
    else
    {
#if defined(CROSSGEN_COMPILE) && !defined(PLATFORM_UNIX)
        // Crossgen has forced stdout into UNICODE only mode:
        //     _setmode(_fileno(stdout), _O_U8TEXT); 
        //
        wchar_t wbuffer[BUFF_SIZE];

        // Convert char* 'buffer' to a wchar_t* string.
        size_t convertedChars = 0;
        mbstowcs_s(&convertedChars, &wbuffer[0], BUFF_SIZE, buffer, _TRUNCATE);

        fputws(&wbuffer[0], stdout);
#else // CROSSGEN_COMPILE
        //
        // We use fputs here so that this executes as fast a possible
        //
        fputs(&buffer[0], stdout);
#endif // CROSSGEN_COMPILE
    }

    return written;
}
Beispiel #10
0
void DECLSPEC_NORETURN noWayAssertBody()
{
#if MEASURE_FATAL
    fatal_noWayAssertBody += 1;
#endif // MEASURE_FATAL

#ifndef DEBUG
    // Even in retail, if we hit a noway, and we have this variable set, we don't want to fall back
    // to MinOpts, which might hide a regression. Instead, hit a breakpoint (and crash). We don't
    // have the assert code to fall back on here.
    // The debug path goes through this function also, to do the call to 'fatal'.
    // This kind of noway is hit for unreached().
    static ConfigDWORD fJitEnableNoWayAssert;
    if (fJitEnableNoWayAssert.val(CLRConfig::INTERNAL_JitEnableNoWayAssert))
    {
        DebugBreak();
    }
#endif // !DEBUG

    fatal(CORJIT_RECOVERABLEERROR);
}
Beispiel #11
0
void debugError(const char* msg, const char* file, unsigned line) 
{
    const char* tail = strrchr(file, '\\');
    if (tail) file = tail+1;

    LogEnv* env = LogEnv::cur();

    logf(LL_ERROR, "COMPILATION FAILED: file: %s:%d compiling method %s reason %s\n", file, line, env->compiler->info.compFullName, msg);

    static ConfigDWORD fJitRequired;
    // We now only assert when user explicitly set ComPlus_JitRequired=1
    // If ComPlus_JitRequired is 0 or is not set, we will not assert.
    if (fJitRequired.val(CLRConfig::INTERNAL_JITRequired) == 1 || getBreakOnBadCode())
    {
            // Don't assert if verification is done.
        if (!env->compiler->tiVerificationNeeded || getBreakOnBadCode())
            assertAbort(msg, "NO-FILE", 0);
    }

    BreakIfDebuggerPresent();
}
Beispiel #12
0
bool   norls_allocator::nraInit(IEEMemoryManager* pMemoryManager, size_t pageSize, int preAlloc)
{
    bool    result = false;

    nraMemoryManager = pMemoryManager;

    nraPageList  =
    nraPageLast  = 0;

    nraFreeNext  =
    nraFreeLast  = 0;

    assert(THE_ALLOCATOR_BASE_SIZE != 0);

    nraPageSize  = pageSize ? pageSize : THE_ALLOCATOR_BASE_SIZE;

#ifdef DEBUG
    static ConfigDWORD fShouldInjectFault;
    nraShouldInjectFault = fShouldInjectFault.val(CLRConfig::INTERNAL_InjectFault) != 0;
#endif    

    if  (preAlloc)
    {
        /* Grab the initial page(s) */

        setErrorTrap(NULL, norls_allocator *, pThis, this)  // ERROR TRAP: Start normal block
        {
            pThis->nraAllocNewPage(0);
        }
        impJitErrorTrap()  // ERROR TRAP: The following block handles errors
        {
            result = true;
        }
        endErrorTrap()  // ERROR TRAP: End
    }

    return  result;
}
Beispiel #13
0
DWORD getBreakOnBadCode()
{
    static ConfigDWORD fBreakOnBadCode;
    return fBreakOnBadCode.val_DontUse_(CLRConfig::INTERNAL_JitBreakOnBadCode, false);
}
Beispiel #14
0
void notYetImplemented(const char * msg, const char * filename, unsigned line)
{
#if FUNC_INFO_LOGGING
#ifdef DEBUG
    LogEnv* env = LogEnv::cur();
    if (env != NULL)
    {
        const Compiler* const pCompiler = env->compiler;
        if (pCompiler->verbose)
        {
            printf("\n\n%s - NYI (%s:%d - %s)\n", pCompiler->info.compFullName,
                filename,
                line,
                msg);
        }
    }
    if (Compiler::compJitFuncInfoFile != NULL)
    {
        fprintf(Compiler::compJitFuncInfoFile, "%s - NYI (%s:%d - %s)\n",
            (env == NULL) ? "UNKNOWN" : env->compiler->info.compFullName,
            filename,
            line,
            msg);
        fflush(Compiler::compJitFuncInfoFile);
    }
#else // !DEBUG
    if (Compiler::compJitFuncInfoFile != NULL)
    {
        fprintf(Compiler::compJitFuncInfoFile, "NYI (%s:%d - %s)\n",
            filename,
            line,
            msg);
        fflush(Compiler::compJitFuncInfoFile);
    }
#endif // !DEBUG
#endif // FUNC_INFO_LOGGING

    static ConfigDWORD fAltJitAssertOnNYI;

    DWORD value = fAltJitAssertOnNYI.val(CLRConfig::INTERNAL_AltJitAssertOnNYI);

    // 0 means just silently skip
    // If we are in retail builds, assume ignore
    // 1 means popup the assert (abort=abort, retry=debugger, ignore=skip)
    // 2 means silently don't skip (same as 3 for retail)
    // 3 means popup the assert (abort=abort, retry=debugger, ignore=don't skip)
    if (value & 1)
    {
#ifdef DEBUG
        assertAbort(msg, filename, line);
#endif
    }

    if ((value & 2) == 0)
    {
#if MEASURE_FATAL
        fatal_NYI += 1;
#endif // MEASURE_FATAL

        fatal(CORJIT_SKIPPED);
    }
}
Beispiel #15
0
BOOL DebugBreakOnAssert()
{
    static ConfigDWORD fDebugBreak;
    return fDebugBreak.val(L"DebugBreakOnAssert", 0);
}
Beispiel #16
0
BOOL NoGuiOnAssert()
{
    static ConfigDWORD fNoGui;
    return fNoGui.val(L"NoGuiOnAssert", 0);
}