Esempio n. 1
0
FixedAlloc::~FixedAlloc()
{
    // Free all of the blocks
    while (m_firstBlock) {
#ifdef MEMORY_INFO
        if(m_firstBlock->numAlloc > 0) {
            // go through every memory location, if the fourth 4 bytes cast as
            // an integer isn't 0xedededed then its allocated space and the integer is
            // an index into the stack trace table, the first 4 bytes will contain
            // the freelist pointer for free'd items (which is why the trace index is
            // stored in the second 4)
            // first 4 bytes - free list pointer
            // 2nd 4 bytes - alloc stack trace
            // 3rd 4 bytes - free stack trace
            // 4th 4 bytes - 0xedededed if freed correctly
            unsigned int *mem = (unsigned int*) m_firstBlock->items;
            unsigned int itemNum = 0;
            while(itemNum++ < m_itemsPerBlock) {
                unsigned int fourthInt = *(mem+3);
                if(fourthInt != 0xedededed) {
                    GCDebugMsg(false, "Leaked %d byte item.  Addr: 0x%x\n", GetItemSize(), mem+2);
                    PrintStackTraceByIndex(*(mem+1));
                }
                mem += (m_itemSize / sizeof(int));
            }
            GCAssert(false);
        }

        // go through every item on the free list and make sure it wasn't written to
        // after being poisoned.
        void *item = m_firstBlock->firstFree;
        while(item) {
#ifdef MMGC_64BIT
            for(int i=3, n=(m_firstBlock->size>>2)-3; i<n; i++)
#else
            for(int i=3, n=(m_firstBlock->size>>2)-1; i<n; i++)
#endif
            {
                unsigned int data = ((int*)item)[i];
                if(data != 0xedededed)
                {
                    GCDebugMsg(false, "Object 0x%x was written to after it was deleted, allocation trace:");
                    PrintStackTrace((int*)item+2);
                    GCDebugMsg(false, "Deletion trace:");
                    PrintStackTrace((int*)item+3);
                    GCDebugMsg(true, "Deleted item write violation!");
                }
            }
            // next free item
            item = *((void**)item);
        }
#endif
        FreeChunk(m_firstBlock);
    }
}
Esempio n. 2
0
/** This function gets called just before the "program executed an illegal instruction and will be terminated" or similar.
Its purpose is to create the crashdump using the dbghlp DLLs
*/
static LONG WINAPI LastChanceExceptionFilter(__in struct _EXCEPTION_POINTERS * a_ExceptionInfo)
{
	char * newStack = &g_ExceptionStack[sizeof(g_ExceptionStack) - 1];
	char * oldStack;

	// Use the substitute stack:
	// This code is the reason why we don't support 64-bit (yet)
	_asm
	{
		mov oldStack, esp
		mov esp, newStack
	}

	MINIDUMP_EXCEPTION_INFORMATION  ExcInformation;
	ExcInformation.ThreadId = GetCurrentThreadId();
	ExcInformation.ExceptionPointers = a_ExceptionInfo;
	ExcInformation.ClientPointers = 0;

	// Write the dump file:
	HANDLE dumpFile = CreateFile(g_DumpFileName, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
	g_WriteMiniDump(GetCurrentProcess(), GetCurrentProcessId(), dumpFile, g_DumpFlags, (a_ExceptionInfo) ? &ExcInformation : nullptr, nullptr, nullptr);
	CloseHandle(dumpFile);

	// Print the stack trace for the basic debugging:
	PrintStackTrace();

	// Revert to old stack:
	_asm
	{
		mov esp, oldStack
	}

	return 0;
}
Esempio n. 3
0
/*
 * @unimplemented
 */
LONG
NTAPI
RtlUnhandledExceptionFilter(IN struct _EXCEPTION_POINTERS* ExceptionInfo)
{
    /* This is used by the security cookie checks, and also called externally */
    UNIMPLEMENTED;
    PrintStackTrace(ExceptionInfo);
    return ERROR_CALL_NOT_IMPLEMENTED;
}
Esempio n. 4
0
CString GetStackTrace(HANDLE process, HANDLE thread, DWORD exCode, const CString& imageFile, LPVOID imageBase, DWORD imageSize)
{
  std::ostringstream log;
  log << "Exception code 0x" << std::hex << exCode << std::endl;

#ifdef _WIN64
  // IS the process a 64-bit one, or a 32-bit one running under WOW (Windows On Windows)?
  BOOL isWow64 = FALSE;
  if (::IsWow64Process(process,&isWow64))
  {
    if (isWow64)
    {
      WOW64_CONTEXT context = { 0 };
      context.ContextFlags = CONTEXT_FULL;
      if (::Wow64GetThreadContext(thread,&context))
      {
        PrintStackTrace(process,thread,imageFile,imageBase,imageSize,
          IMAGE_FILE_MACHINE_I386,context.Eip,context.Ebp,context.Esp,&context,log);
      }
    }
    else
    {
      CONTEXT context = { 0 };
      context.ContextFlags = CONTEXT_FULL;
      if (::GetThreadContext(thread,&context))
      {
        PrintStackTrace(process,thread,imageFile,imageBase,imageSize,
          IMAGE_FILE_MACHINE_AMD64,context.Rip,context.Rbp,context.Rsp,&context,log);
      }
    }
  }
#else
  CONTEXT context = { 0 };
  context.ContextFlags = CONTEXT_FULL;
  if (::GetThreadContext(thread,&context))
  {
    PrintStackTrace(process,thread,imageFile,imageBase,imageSize,
      IMAGE_FILE_MACHINE_I386,context.Eip,context.Ebp,context.Esp,&context,log);
  }
#endif

  return CString(log.str().c_str());
}
Esempio n. 5
0
static void NonCtrlHandler(int a_Signal)
{
	LOGD("Terminate event raised from std::signal");
	cRoot::Get()->QueueExecuteConsoleCommand("stop");

	switch (a_Signal)
	{
		case SIGSEGV:
		{
			std::signal(SIGSEGV, SIG_DFL);
			LOGERROR("  D:    | Cuberite has encountered an error and needs to close");
			LOGERROR("Details | SIGSEGV: Segmentation fault");
			#ifdef BUILD_ID
			LOGERROR("Cuberite " BUILD_SERIES_NAME " build id: " BUILD_ID);
			LOGERROR("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME);
			#endif
			PrintStackTrace();
			abort();
		}
		case SIGABRT:
		#ifdef SIGABRT_COMPAT
		case SIGABRT_COMPAT:
		#endif
		{
			std::signal(a_Signal, SIG_DFL);
			LOGERROR("  D:    | Cuberite has encountered an error and needs to close");
			LOGERROR("Details | SIGABRT: Server self-terminated due to an internal fault");
			#ifdef BUILD_ID
			LOGERROR("Cuberite " BUILD_SERIES_NAME " build id: " BUILD_ID);
			LOGERROR("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME);
			#endif
			PrintStackTrace();
			abort();
		}
		case SIGINT:
		case SIGTERM:
		{
			std::signal(a_Signal, SIG_IGN);  // Server is shutting down, wait for it...
			break;
		}
		default: break;
	}
}
Esempio n. 6
0
void ExtendedLogger::Log(LogLevelType level, CArrRef stackTrace,
                         bool escape /* = true */,
                         bool escapeMore /* = false */) {
  assert(!escapeMore || escape);
  ThreadData *threadData = s_threadData.get();
  if (++threadData->message > MaxMessagesPerRequest &&
      MaxMessagesPerRequest >= 0) {
    return;
  }

  if (stackTrace.isNull()) return;

  if (UseLogFile) {
    FILE *f = Output ? Output : GetStandardOut(level);
    PrintStackTrace(f, stackTrace, escape, escapeMore);

    FILE *tf = threadData->log;
    if (tf) {
      PrintStackTrace(tf, stackTrace, escape, escapeMore);
    }
  }
}
Esempio n. 7
0
void ExtendedLogger::Log(bool err, CArrRef stackTrace,
                         bool escape /* = true */,
                         bool escapeMore /* = false */) {
  ASSERT(!escapeMore || escape);
  ThreadData *threadData = s_threadData.get();
  if (++threadData->message > MaxMessagesPerRequest &&
      MaxMessagesPerRequest >= 0) {
    return;
  }

  if (stackTrace.isNull()) return;

  // TODO Should we also send the stacktrace to LogAggregator?
  if (UseLogFile) {
    FILE *f = Output ? Output : (err ? stderr : stdout);
    PrintStackTrace(f, stackTrace, escape, escapeMore);

    FILE *tf = threadData->log;
    if (tf) {
      PrintStackTrace(tf, stackTrace, escape, escapeMore);
    }
  }
}
Esempio n. 8
0
static void CrashSignalHandler(int sig)
{
   // Uninstall this handler, to avoid the possibility of an infinite regress
   signal(SIGSEGV, SIG_DFL);
   signal(SIGBUS,  SIG_DFL);
   signal(SIGILL,  SIG_DFL);
   signal(SIGABRT, SIG_DFL);
   signal(SIGFPE,  SIG_DFL);

   printf("MUSCLE CrashSignalHandler called with signal %i... I'm going to print a stack trace, then kill the process.\n", sig);
   PrintStackTrace();
   printf("Crashed MUSCLE process aborting now.... bye!\n");
   fflush(stdout);
   abort();
}
Esempio n. 9
0
/* eval(source) */
int DuckEval(int argument_count, void* data)
{
    L_TOKEN*      lexing;
    SYNTAX_TREE*  ast;
    char*         buffer;
    int           error = 0;

    VALUE argument = GetRecord("source", gCurrentContext);

    gLastExpression.type = VAL_NIL;
    gLastExpression.data.primitive = 0;

    CLOSURE* currentContext;
    currentContext = gCurrentContext;

    int prev_line_error = line_error;
    SYNTAX_TREE* prev_failed_production = failed_production;

//  if (gCurrentContext->parent) gCurrentContext = gCurrentContext->parent;
    gCurrentContext = gGlobalContext;

    if (argument.type == VAL_STRING) 
    {
        lexing = LexSourceBuffer(argument.data.string, &buffer, CONTEXT_FREE_GRAMMAR);
        if (lexing == NULL) {
            printf("Error lexing source or empty source string.\n");
            FreeLexing(lexing, buffer);
            return 1;
        }
        ast = ParseSource(lexing, PARSE_TABLE, CONTEXT_FREE_GRAMMAR);
        if (ast == NULL) {
            printf("Error parsing source.\n");
            FreeLexing(lexing, buffer);
            return 1;
        }

        /* ReduceProgramAST(&ast); */
        error = InterpretNode(ast);

        if (error)
        {
            printf("%s\n", ErrorMessage(error));
            PrintStackTrace();
            FreeLexing(lexing, buffer);
            FreeParseTree(ast);

            ClearCallStack(&gStackTrace);

            line_error = prev_line_error;
            failed_production = prev_failed_production;

            return 1;
        }

        /* sanitize last expression for use in program */
        //gLastExpression = ReallocStrings(gLastExpression);

        /* free lexing and parse tree */
        //FreeLexing(lexing, buffer);
        //FreeParseTree(ast);
        GCAddLexing(lexing, buffer);
        GCAddParseTree(ast);
    }

    gCurrentContext = currentContext;
    return error;
}