44
44
#include " CvDllUnit.h"
45
45
46
46
#if defined(MOD_DEBUG_MINIDUMP)
47
+ #ifdef WIN32
48
+ #include " ../commit_id.inc"
47
49
#include < dbghelp.h>
48
- #endif
50
+ #endif // WIN32
51
+ #endif // defined(MOD_DEBUG_MINIDUMP)
49
52
50
53
// must be included after all other headers
51
54
#include " LintFree.h"
@@ -2408,11 +2411,6 @@ CvGlobals::~CvGlobals()
2408
2411
uninit ();
2409
2412
}
2410
2413
2411
- #ifdef STACKWALKER
2412
- MyStackWalker gStackWalker ;
2413
- lua_State* gLuaState = NULL ;
2414
- #endif
2415
-
2416
2414
// cannot use GC.getGame().getActivePlayer() in observer mode
2417
2415
PlayerTypes GetCurrentPlayer ()
2418
2416
{
@@ -2426,6 +2424,7 @@ PlayerTypes GetCurrentPlayer()
2426
2424
}
2427
2425
2428
2426
#if defined(MOD_DEBUG_MINIDUMP)
2427
+ #ifdef WIN32
2429
2428
/* ***********************************************************************************************/
2430
2429
/* MINIDUMP_MOD 04/10/11 terkhen */
2431
2430
/* See http://www.debuginfo.com/articles/effminidumps.html */
@@ -2434,51 +2433,131 @@ PlayerTypes GetCurrentPlayer()
2434
2433
/* See http://forums.civfanatics.com/showthread.php?t=498919 */
2435
2434
/* ***********************************************************************************************/
2436
2435
2437
- #pragma comment (lib, "dbghelp.lib")
2438
- void CreateMiniDump (EXCEPTION_POINTERS *pep)
2439
- {
2440
- #ifdef STACKWALKER
2441
- {
2442
- /* Try to log the callstack */
2443
- FILogFile* pLog=LOGFILEMGR.GetLog ( " Callstack.log" , FILogFile::kDontTimeStamp );
2444
- if (pLog)
2445
- {
2446
- pLog->Msg (" Gamecore Callstack\n " );
2447
-
2448
- gStackWalker .SetLog (pLog);
2449
- gStackWalker .ShowCallstack (INT_MAX, GetCurrentThread (), pep ? pep->ContextRecord : NULL );
2450
- gStackWalker .SetLog (NULL );
2451
-
2452
- pLog->Msg (" \n Lua Callstack\n " );
2453
- if (gLuaState )
2454
- LuaSupport::DumpCallStack (gLuaState ,pLog);
2455
-
2456
- pLog->Close ();
2436
+ #pragma comment(lib, "dbghelp.lib")
2437
+ void CreateMiniDump (EXCEPTION_POINTERS* pep)
2438
+ {
2439
+ // Initialize debug symbols
2440
+ HANDLE hProcess = GetCurrentProcess ();
2441
+ SymInitialize (hProcess, NULL , TRUE );
2442
+
2443
+ // Get timestamp
2444
+ SYSTEMTIME st;
2445
+ GetLocalTime (&st);
2446
+ TCHAR szTimestamp[64 ];
2447
+ _stprintf_s (szTimestamp, sizeof (szTimestamp) / sizeof (TCHAR),
2448
+ _T (" %04d%02d%02d_%02d%02d%02d" ),
2449
+ st.wYear , st.wMonth , st.wDay ,
2450
+ st.wHour , st.wMinute , st.wSecond );
2451
+
2452
+ // Extract just version number and commit hash from CURRENT_GAMECORE_VERSION
2453
+ char shortVersion[64 ];
2454
+ const char * fullVersion = CURRENT_GAMECORE_VERSION;
2455
+ const char * versionStart = strchr (fullVersion, ' -' );
2456
+ if (versionStart) {
2457
+ versionStart++; // Skip the '-'
2458
+ const char * spaceAfterVersion = strchr (versionStart, ' ' );
2459
+ if (spaceAfterVersion) {
2460
+ // Copy just the version number (e.g. "4.16")
2461
+ size_t versionLen = spaceAfterVersion - versionStart;
2462
+ strncpy_s (shortVersion, sizeof (shortVersion), versionStart, versionLen);
2463
+ shortVersion[versionLen] = ' \0 ' ;
2464
+
2465
+ // Add the commit hash if present
2466
+ const char * commitHash = spaceAfterVersion + 1 ;
2467
+ const char * nextSpace = strchr (commitHash, ' ' );
2468
+ if (nextSpace) {
2469
+ strcat_s (shortVersion, sizeof (shortVersion), " _" );
2470
+ strncat_s (shortVersion, sizeof (shortVersion), commitHash, nextSpace - commitHash);
2471
+ }
2457
2472
}
2458
2473
}
2474
+ else {
2475
+ strcpy_s (shortVersion, sizeof (shortVersion), " unknown" );
2476
+ }
2477
+
2478
+ // Generate dump filename with version, commit hash and build type
2479
+ TCHAR szDumpPath[MAX_PATH];
2480
+ _stprintf_s (szDumpPath, MAX_PATH, _T (" CvMiniDump_%s_%hs_%s.dmp" ),
2481
+ szTimestamp,
2482
+ shortVersion,
2483
+ #ifdef VPDEBUG
2484
+ _T (" Debug" )
2485
+ #else
2486
+ _T (" Release" )
2459
2487
#endif
2488
+ );
2489
+
2490
+ HANDLE hFile = CreateFile (szDumpPath, GENERIC_READ | GENERIC_WRITE,
2491
+ 0 , NULL , CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
2460
2492
2461
- /* Open a file to store the minidump. */
2462
- HANDLE hFile = CreateFile (_T (" CvMiniDump.dmp" ), GENERIC_READ | GENERIC_WRITE, 0 , NULL , CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
2463
- if ((hFile == NULL ) || (hFile == INVALID_HANDLE_VALUE)) {
2464
- _tprintf (_T (" CreateFile failed. Error: %lu \n " ), GetLastError ());
2493
+ if ((hFile == NULL ) || (hFile == INVALID_HANDLE_VALUE)) {
2465
2494
return ;
2466
2495
}
2467
2496
2468
- /* Create the minidump. */
2469
2497
MINIDUMP_EXCEPTION_INFORMATION mdei;
2470
- mdei.ThreadId = GetCurrentThreadId ();
2471
- mdei.ExceptionPointers = pep;
2472
- mdei.ClientPointers = FALSE ;
2498
+ mdei.ThreadId = GetCurrentThreadId ();
2499
+ mdei.ExceptionPointers = pep;
2500
+ mdei.ClientPointers = FALSE ;
2501
+
2502
+ // Configure dump type based on build
2503
+ MINIDUMP_TYPE mdt;
2504
+ #ifdef VPDEBUG
2505
+ OutputDebugString (_T (" Creating Debug minidump\n " ));
2506
+ mdt = (MINIDUMP_TYPE)(
2507
+ MiniDumpWithFullMemory | // Complete memory snapshot
2508
+ MiniDumpWithFullMemoryInfo | // Memory state information
2509
+ MiniDumpWithHandleData | // Handle usage
2510
+ MiniDumpWithUnloadedModules | // Track unloaded DLLs
2511
+ MiniDumpWithThreadInfo | // Extended thread information
2512
+ MiniDumpWithProcessThreadData | // Process thread data
2513
+ MiniDumpWithCodeSegs | // Code segments
2514
+ MiniDumpWithDataSegs | // Data segments
2515
+ MiniDumpWithPrivateReadWriteMemory | // Private memory
2516
+ MiniDumpWithFullAuxiliaryState | // Auxiliary state (handles, GDI objects)
2517
+ MINIDUMP_TYPE (0x00000040 ) | // MiniDumpWithTokenInformation
2518
+ MINIDUMP_TYPE (0x00000400 ) | // MiniDumpWithPrivateWriteCopyMemory
2519
+ MINIDUMP_TYPE (0x00020000 ) | // MiniDumpIgnoreInaccessibleMemory
2520
+ MiniDumpWithIndirectlyReferencedMemory | // Memory referenced by locals
2521
+ MINIDUMP_TYPE (0x00000800 ) // MiniDumpWithModuleHeaders
2522
+ );
2523
+ #else
2524
+ OutputDebugString (_T (" Creating Release minidump\n " ));
2525
+ mdt = (MINIDUMP_TYPE)(
2526
+ MiniDumpNormal | // Basic info
2527
+ MiniDumpWithThreadInfo | // Thread information
2528
+ MINIDUMP_TYPE (0x00020000 ) // MiniDumpIgnoreInaccessibleMemory
2529
+ );
2530
+ #endif
2531
+
2532
+ // Add version info
2533
+ MINIDUMP_USER_STREAM_INFORMATION additional_streams;
2534
+ MINIDUMP_USER_STREAM user_streams[1 ];
2535
+ char version_info[256 ];
2536
+
2537
+ sprintf_s (version_info, sizeof (version_info),
2538
+ " Version: %s" , CURRENT_GAMECORE_VERSION);
2539
+
2540
+ user_streams[0 ].Type = 0x00000003 ; // MinidumpCommentStreamA
2541
+ user_streams[0 ].Buffer = version_info;
2542
+ user_streams[0 ].BufferSize = static_cast <ULONG>(strlen (version_info) + 1 );
2473
2543
2474
- MINIDUMP_TYPE mdt = MiniDumpNormal;
2544
+ additional_streams.UserStreamCount = 1 ;
2545
+ additional_streams.UserStreamArray = user_streams;
2475
2546
2476
- MiniDumpWriteDump (GetCurrentProcess (), GetCurrentProcessId (), hFile, mdt, (pep != NULL ) ? &mdei : NULL , NULL , NULL );
2547
+ // Write the dump
2548
+ MiniDumpWriteDump (
2549
+ GetCurrentProcess (),
2550
+ GetCurrentProcessId (),
2551
+ hFile,
2552
+ mdt,
2553
+ (pep != NULL ) ? &mdei : NULL ,
2554
+ &additional_streams,
2555
+ NULL );
2477
2556
2478
2557
CloseHandle (hFile);
2479
2558
}
2480
2559
2481
- LONG WINAPI CustomFilter (EXCEPTION_POINTERS * ExceptionInfo)
2560
+ LONG WINAPI CustomFilter (EXCEPTION_POINTERS* ExceptionInfo)
2482
2561
{
2483
2562
CreateMiniDump (ExceptionInfo);
2484
2563
return EXCEPTION_EXECUTE_HANDLER;
@@ -2491,10 +2570,14 @@ LONG WINAPI CustomFilter(EXCEPTION_POINTERS *ExceptionInfo)
2491
2570
void CvGlobals::init ()
2492
2571
{
2493
2572
#if defined(MOD_DEBUG_MINIDUMP)
2494
- /* Enable our custom exception that will write the minidump for us. */
2495
2573
SetUnhandledExceptionFilter (CustomFilter);
2496
- CUSTOMLOG (" MiniDump exception handler installed" );
2574
+ #ifdef VPDEBUG
2575
+ OutputDebugString (_T (" Debug MiniDump handler installed\n " ));
2576
+ #else
2577
+ OutputDebugString (_T (" Release MiniDump handler installed\n " ));
2497
2578
#endif
2579
+ #endif // WIN32
2580
+ #endif // defined(MOD_DEBUG_MINIDUMP)
2498
2581
2499
2582
//
2500
2583
// These vars are used to initialize the globals.
0 commit comments