Skip to content

[GEN][ZH] Fix Memory Manager initialization issues (old) #1236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

xezon
Copy link

@xezon xezon commented Jul 6, 2025

This change fixes Memory Manager initialization issues.

Problems identified: ClientInstance::initialize and CommandLine::parseCommandLineForStartup both used 'new' allocator before the Memory Manager was initialized, in both Debug and Release. This caused the Memory Manager to actually be created twice, and trigger 1 assert on game launch and 1 assert on game quit.

This is now fixed by fixing initialization ordering and preventing some allocations with 'new'.

This change also uses the stl::malloc_allocator that was added to the pending Pull Request #1066.

TODO

  • Replicate in Generals

@xezon xezon requested a review from helmutbuhler July 6, 2025 20:18
@xezon xezon added Minor Severity: Minor < Major < Critical < Blocker ThisProject The issue was introduced by this project, or this task is specific to this project Memory Is memory related Fix Is fixing something, but is not user facing labels Jul 6, 2025
@helmutbuhler
Copy link

Thanks for investigating this! Your change does indeed fix the issue, but it also adds a lot of complexity. Adding yet another phase to commandline parsing is not the right way to go in my opinion (I think even two is one too many).

I think we can fix this by simply moving the DEBUG_LOG call in preMainInitMemoryManager until after TheMemoryPoolFactory is assigned, thereby avoiding the unwanted recursion.
I tried this out, see the two commits here (based on this branch):
https://github.com/helmutbuhler/CnC_Generals_Zero_Hour/commits/fix-memory-initialization-issues/
It also avoids the need for MallocAllocator.

@xezon
Copy link
Author

xezon commented Jul 13, 2025

This was also one of my tries to fix this, but it was not the right approach, because there is also at least one DEBUG_ASSERTCRASH (which implies logging when hit) in the memory manager initialization. Plus client instance initialization also needs to be done before debug logging and therefore without new/delete, because the instance id affects the name of the log file.

This is quite a bit complicated order of initialization but this change fixes it.

Order:

Command Line parse (parts)
Client Instance
Debug Log
Memory Manager
The Rest

MallocAllocator is needed regardless. There will always be things that want to bypass Memory Manager in rare special cases. Memory Manager itself needs to bypass new/delete :-)

@helmutbuhler
Copy link

This was also one of my tries to fix this, but it was not the right approach, because there is also at least one DEBUG_ASSERTCRASH (which implies logging when hit) in the memory manager initialization.

Where is this DEBUG_ASSERTCRASH?

@xezon
Copy link
Author

xezon commented Jul 13, 2025

DynamicMemoryAllocator::init

@xezon
Copy link
Author

xezon commented Jul 13, 2025

We can move Memory Manager first above all but then need to never use logging in it. We could use assert then.

@xezon
Copy link
Author

xezon commented Jul 13, 2025

I looked deeper, there are more asserts in

MemoryPoolFactory::createMemoryPool
MemoryPoolFactory::findMemoryPool
userMemoryAdjustPoolSize
MemoryPool::createBlob

Moving logging behind memory manager will lose logging/asserting for all of this.

@xezon
Copy link
Author

xezon commented Jul 13, 2025

So yeah we need to decide, is allocation (using new) more important everywhere, or the ability to log/assert everywhere?

@xezon
Copy link
Author

xezon commented Jul 13, 2025

What we can try to do is make DEBUG_CRASH more usable when Debug was not yet initialized. Logging nothing. Do you want that?

@xezon
Copy link
Author

xezon commented Jul 13, 2025

I am working on a new change. Will be done later.

@helmutbuhler
Copy link

DynamicMemoryAllocator::init

Ah, you are right, I must have missed that. Hm.

What we can try to do is make DEBUG_CRASH more usable when Debug was not yet initialized. Logging nothing. Do you want that?

Yes, that sounds pretty good.

Another alternative might be to remove/replace all globals that allocate, not sure if that's feasable.

@helmutbuhler
Copy link

Another alternative might be to remove/replace all globals that allocate, not sure if that's feasable.

Never mind, there are so many globals...

@xezon xezon changed the title [GEN][ZH] Fix Memory Manager initialization issues [GEN][ZH] Fix Memory Manager initialization issues (old) Jul 13, 2025
@xezon
Copy link
Author

xezon commented Jul 13, 2025

Done: #1275

@xezon
Copy link
Author

xezon commented Jul 14, 2025

Obsoleted

@xezon xezon closed this Jul 14, 2025
@xezon xezon deleted the xezon/fix-memory-initialization-issues branch July 14, 2025 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fix Is fixing something, but is not user facing Memory Is memory related Minor Severity: Minor < Major < Critical < Blocker ThisProject The issue was introduced by this project, or this task is specific to this project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix debug memory crash on exit in VS22 due to recent TheGlobalData refactor
2 participants