Skip to content

GGMax Bug – CrashHandler() is not creating a stack-trace in Guru-Crash.log #6381

Description

@Dr-Eyeball
Property Value
🔸 Game Engine GameGuru Max
🔸 GGM Build (Public or Private) Public
🔸 Related GGM Build Older Live Build
🔸 GGM Build Version 2026.05.02
Property Value
🔸 Labels Max,Bug
🔸 Subsystem: Gameplay Systems Not applicable
🔸 Subsystem: Editor Tools Not applicable
🔸 Subsystem: Internal Editors/Systems Level Editor,Crash Handler

🔸 Problem Summary

  1. My understanding is that the function LONG CrashHandler() is supposed to generate a call stack trace and other debug information, that can be used to help locate the source of the crash.
  • This is not working.

See Insight or Suspected Cause heading below for useful advice. The other headings are common knowledge.

  1. See Actual Behavior heading below for:
  • screenshot, and
  • info about the missing path for "Guru-Crash.log".

Property Value
🔸 Estimated Priority Normal
🔸 Estimated Severity 2 – Moderate / Functional issue
🔸 Reproducibility 3 – Occasional – takes effort to reproduce
🔸 Estimated Development Effort Medium task — under 1 week
🔸 Integrity of Files I verified my files – it didn't help.
🔸 Crash Log Available? Yes – I will attach it.

🔸 Steps to Reproduce

  1. Cause a crash.

Perform one of these actions?

  1. While modifying existing materials for an object within the editor, if you have a surface texture and click the "Invert Green Channel" checkbox twice, it crashes.
  2. I have found that the copy/paste of groups is currently buggy.
  3. Using copy/paste of an entity (like a floor) lately has randomly resulted in a crash.

🔸 Expected Behaviour

My understanding is that the function LONG CrashHandler() is supposed to generate a call stack trace and other debug information, that can be used to help locate the source of the crash.


🔸 Actual Behaviour

Currently the log only produces this:

==== GAMEGURU MAX CRASH DETECTED ====
Time:            2026-05-10 19:32:02
Build:           GameGuru MAX Build 16-12-2025-17-38 
Exception code:  0x80000003
Module address:  0x7ff6f47a0000
Crash address:   0x7ff6f4e3e553
Base address:    0x7ff6f47a0000
Offset value:    0x69e553
Lookup address:  0x7ff6f4e3e553
=====================================

==== GAMEGURU MAX CRASH DETECTED ====
Time:            2026-05-25 20:07:22
Build:           GameGuru MAX Build 16-12-2025-17-38 
Exception code:  0xc0000005
Module address:  0x7ff71a7e0000
Crash address:   0x7ff71ab3f3d6
Base address:    0x7ff71a7e0000
Offset value:    0x35f3d6
Lookup address:  0x7ff71ab3f3d6
=====================================

It first displays this message box:

  • You will note that the path shows "Guru-Crash.log" and not the full pathname.
    • This indicates that GetModuleFileNameA() is not returning the full/any pathname in CrashHandler().
  • I would suggest you retrieve variable logPath if it is empty, directly from g.fpscrootdir_s, which is prefilled before any stack corruption. (I know, trivial, compared to the rest of this problem.)
    • See Insight heading below for more info.

It then displays this message box:

  • I think this probably relates to SymInitialize() ?

🔸 Insight or Suspected Cause

  • I don't have disablecrashlogsystem = 1 enabled or even present.

AI has some very good C++ code advice:

🛠 What to do in a crash handler (the safe pattern)

  1. ❌Never call SymInitialize() inside the crash handler
    Call it once at program startup, long before any crash.

  2. ❌Never rely on GetModuleFileName() inside a crash handler
    Use:

  • an earlier retrieval, like g.fpscrootdir_s which is prefilled before any stack corruption,
  • or use the AI mentioned PEB fallback shown below as GetExePathFromPEB().
  • AI mentions a PEB-based fallback.
bool GetExePathFromPEB(std::wstring& outPath)
I'll include GetExePathFromPEB() here for ref. (✔ click to view code)
// PEB-based fallback for main EXE path
// Works when GetModuleFileNameW(NULL, ...) is unreliable (e.g. in crash handlers)

#include <windows.h>
#include <winternl.h>   // For PEB, RTL_USER_PROCESS_PARAMETERS, etc.
#include <string>

// Some SDKs don't expose NtCurrentPeb, so we declare it ourselves if needed.
#ifndef NtCurrentPeb
EXTERN_C NTSYSAPI PPEB NTAPI RtlGetCurrentPeb(void);
#define NtCurrentPeb RtlGetCurrentPeb()
#endif

bool GetExePathFromPEB(std::wstring& outPath)
{
    // Get PEB for current process
    PPEB peb = NtCurrentPeb;
    if (!peb)
        return false;

    // ProcessParameters holds ImagePathName
    PRTL_USER_PROCESS_PARAMETERS params = peb->ProcessParameters;
    if (!params)
        return false;

    UNICODE_STRING imagePath = params->ImagePathName;
    if (!imagePath.Buffer || imagePath.Length == 0)
        return false;

    // Length is in bytes, convert to wchar_t count
    size_t wcharCount = imagePath.Length / sizeof(WCHAR);

    outPath.assign(imagePath.Buffer, wcharCount);
    return true;
}
  1. ✔ Use only pre‑initialized DbgHelp state
    DbgHelp is not safe to initialize after a crash.

  2. ✔Use only fixed buffers, no heap allocations
    Heap may be corrupted.

  3. SymInitialize() must NOT be called twice in the same process.
    DbgHelp’s symbol handler is single‑instance per process.

  • Once it is initialized, calling SymInitialize() again — even with the same parameters — is undefined behavior and often fails.
  • Calling it again with different parameters is guaranteed to fail

Metadata

Metadata

Assignees

Labels

CRASH!MaxIssues related to GameGuru Max.Waiting for more information.Not enough information supplied to actionbugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions