View Issue Details

IDProjectCategoryView StatusLast Update
0005229NoesisGUIC++ SDKpublic2026-10-16 12:18
Reporterianneufeld Assigned Tojsantos  
PrioritynormalSeverityminor 
Status assignedResolutionopen 
Product Version4.0 
Target Version4.0.2 
Summary0005229: Better control over TRACK_ALIVE_OBJECTS, CRTDBG_LEAK_CHECK, etc
Description

Currently a number of defines that enable debugging features (e.g. for tracking memory leaks) similar are defined in specific .cpp files (BaseObject.cpp, Memory.cpp, etc).

This makes it hard to build multiple versions of dlls/libs for different use cases (e.g. an internal Debug/Profile version and an external Release version) without tedious manual edits to files when preparing the binaries or undesirable deviations from the "clean" source code.

It would be preferable to have these be passed in as project-level preprocessor definitions so that it's easy to enable/disable them for different build configurations.

PlatformAny

Activities

jsantos

jsantos

2026-09-30 13:33

manager   ~0012676

Last edited: 2026-09-30 13:33

The defines that are expected to change per build are located in BuildSettings.h. Each define is guarded by #ifndef, so you can override them globally in your project settings.

#ifndef NS_TRACK_XAML_SOURCE
    #define NS_TRACK_XAML_SOURCE 1
#endif

The defines in Memory.cpp and BaseObject.cpp are more local and are not intended to be configured per build. They are mainly there for local testing when investigating memory leaks. For example, CRTDBG_BREAK_ALLOC requires you to specify a particular allocation ID.

I could guard these defines with #ifndef as well, which would allow you to override them from your project settings. But I recommend handling memory leak detection on your side and using your own memory allocator.

ianneufeld

ianneufeld

2026-10-01 18:53

reporter   ~0012687

Last edited: 2026-10-01 19:01

While we do intend to have our own alloc implementation, the MemoryCallbacks.gAlloc function does not get information on the usage of the memory it's allocating, just that it's being asked to allocate a particular number of bytes. So it doesn't know if the memory it's going to give back will become a BaseObject, a string, or an array of integers.

This is distinct from the functionality in BaseObject which stores data in gAliveObjects where it knows that it's instantiating an object of a particular type and so can reliably use that information during shutdown to display the table of leaking objects. Being able to activate that functionality and/or inject equivalent logic in the same place would be ideal.

jsantos

jsantos

2026-10-06 13:24

manager   ~0012709

I’m attaching a patch that should solve this issue. With this patch, you can define TRACK_ALIVE_OBJECTS and other related macros at the project level.

Please let me know if this works for you.

Src.patch (934 bytes)   
Index: BaseObject.cpp
===================================================================
--- BaseObject.cpp	(revision 18137)
+++ BaseObject.cpp	(working copy)
@@ -13,7 +13,9 @@
 using namespace Noesis;
 
 
-#define TRACK_ALIVE_OBJECTS 0
+#ifndef TRACK_ALIVE_OBJECTS
+    #define TRACK_ALIVE_OBJECTS 0
+#endif
 
 
 #if TRACK_ALIVE_OBJECTS
Index: Memory.cpp
===================================================================
--- Memory.cpp	(revision 18137)
+++ Memory.cpp	(working copy)
@@ -4,10 +4,15 @@
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 
-#define CRTDBG_LEAK_CHECK 0
-#define CRTDBG_BREAK_ALLOC -1
+#ifndef CRTDBG_LEAK_CHECK
+    #define CRTDBG_LEAK_CHECK 0
+#endif
 
+#ifndef CRTDBG_BREAK_ALLOC
+    #define CRTDBG_BREAK_ALLOC -1
+#endif
 
+
 #if _DEBUG && CRTDBG_LEAK_CHECK
 #define _CRTDBG_MAP_ALLOC
 #include <stdlib.h>
Src.patch (934 bytes)   
ianneufeld

ianneufeld

2026-10-06 20:37

reporter   ~0012716

Thank you, yes that works.
If you have time, it would also be great to extend the functionality of NSProject.py to allow per-config defines (rather than having defines be for all configs), but that's just a nice little addition :)

jsantos

jsantos

2026-10-07 13:51

manager   ~0012724

it would also be great to extend the functionality of NSProject.py to allow per-config defines

As a workaround, you can inject your own header using the NS_CUSTOM_BUILD_SETTINGS_HEADER define:

#ifndef __CORE_BUILDSETTINGS_H__
#define __CORE_BUILDSETTINGS_H__

// Give the chance to customize default values
#ifdef NS_CUSTOM_BUILD_SETTINGS_HEADER
    #include NS_CUSTOM_BUILD_SETTINGS_HEADER
#endif

Then, in your custom header, you can define whatever you need based on the appropriate conditions.

Would this work for you?

ianneufeld

ianneufeld

2026-10-07 18:58

reporter   ~0012729

I have a workaround currently (I modified NSProject.py to automatically add the define when handling the "Debug" config options). I'm not sure the custom header solution is ideal, but it would work.

The hesitation is that without modifying additional code, there isn't much an injected header could influence beyond adjusting the preprocessor directives that the code already knows about. It could allow for a little bit of finetuning (e.g. only enable it on Debug + Windows) but I think your .conf files already take care of those cases since we would be using different .conf files to generate a new project for the other platforms. But if we're at the point of modifying code to add new functionality for the injected header to interact with, we could just insert additional logic where it was needed (or add the include manually without relying on the .conf file to pass it along).

jsantos

jsantos

2026-10-08 17:36

manager   ~0012736

Yes, but I was referring to "per-config defines." This can be implemented using a custom include, right?

But yeah, this should be a straightforward improvement.

ianneufeld

ianneufeld

2026-10-08 20:00

reporter   ~0012740

Agreed, would work but not ideal.
Would be preferable to just be able to write
DEFINE_DEBUG = TRACK_ALIVE_OBJECTS=1
in the .conf file instead of
CUSTOM_BUILD_HEADER = CustomBuildHeader.h
and also maintain a file on disk.

Of course, having both options could also be good for the dev who needs the more fine-tuned approach.

Issue History

Date Modified Username Field Change
2026-09-30 02:11 ianneufeld New Issue
2026-09-30 10:27 sfernandez Assigned To => jsantos
2026-09-30 10:27 sfernandez Status new => assigned
2026-09-30 10:27 sfernandez Target Version => 4.0.1
2026-09-30 13:33 jsantos Note Added: 0012676
2026-09-30 13:33 jsantos Status assigned => feedback
2026-09-30 13:33 jsantos Note Edited: 0012676
2026-10-01 18:53 ianneufeld Note Added: 0012687
2026-10-01 18:53 ianneufeld Status feedback => assigned
2026-10-01 19:01 ianneufeld Note Edited: 0012687
2026-10-01 19:01 ianneufeld Note Edited: 0012687
2026-10-06 13:24 jsantos Note Added: 0012709
2026-10-06 13:24 jsantos File Added: Src.patch
2026-10-06 13:24 jsantos Status assigned => feedback
2026-10-06 20:37 ianneufeld Note Added: 0012716
2026-10-06 20:37 ianneufeld Status feedback => assigned
2026-10-07 13:51 jsantos Note Added: 0012724
2026-10-07 13:51 jsantos Status assigned => feedback
2026-10-07 18:58 ianneufeld Note Added: 0012729
2026-10-07 18:58 ianneufeld Status feedback => assigned
2026-10-08 17:36 jsantos Note Added: 0012736
2026-10-08 20:00 ianneufeld Note Added: 0012740
2026-10-16 12:18 jsantos Target Version 4.0.1 => 4.0.2