<- Manual.html | Back to main page

Title: Troubleshooting

*
If your program crashes with segmentation faults, start by replacing pointers with SafePointer and building the program in debug mode.

In the Builder build system, debug mode is activated by writing 'Debug' in the *.DsrProj project file, which declares the Debug variable and assigns it to one.

For other build systems, give -DDEBUG to the compiler to define the DEBUG macro.
Make sure that the release flag -DNDEBUG is not also active.

Then memory.h will enable the SAFE_POINTER_CHECKS macro from detecting debug mode.
Then SafePointer.h will store the permitted region in each SafePointer and perform bound checks when data is accessed using SafePointer.

---
Title2: Getting random memory crashes.

*
If your program is getting random memory corruption despite using SafePointer and debug mode, continue by enabling the EXTRA_SAFE_POINTER_CHECKS macro.

In the Builder build system, extra safe memory checks can be enabled for debug mode by writing 'CompilerFlag "-DEXTRA_SAFE_POINTER_CHECKS"' in the *.DsrProj project file.
EXTRA_SAFE_POINTER_CHECKS can also be defined as a macro in settings.h or by giving -DEXTRA_SAFE_POINTER_CHECKS to a different build system.

Then SafePointer will check that the allocation has not been replaced by another allocation in heap.cpp.
SafePointer will also check that no thread is trying to access virtual stack memory allocated by another thread.

*
If your program does not crash but your image filters do not work as expected, create a debug window showing internal images or debug overlays with coordinates on top of the program's existing graphics.

*
Make sure that all your multi-threading can be turned off easily when finding the root cause.

*
Create a basic reference implementation without dangerous optimizations for every advanced feature.
Both for finding the cause of instability and being able to remove a feature without sending emergency patches in panic with more bugs.
Image filters are first written using lambdas returning the color of a pixel based on the pixel coordinate and exception-free pixel sampling.
Then one can make an optimized version using SafePointer and SIMD vectors.

---
Title2: Getting memory leaks.

In debug mode, terminating the program should print "All heap memory was freed without leaks.".
If it does not, you might have a memory leak for memory allocated by the framework in heap.cpp.
Due to the non-deterministic release order for global variables in C++, it is not possible to print a warning when there is a memory leak without redefining the _start function.

*
Avoid using manual memory management (malloc, free, new, delete...), use dsr::Handle for object handles.

*
Make sure that no reference counted object can create a cycle of reference counted pointers back to itself, because then none of them would be unused according to reference counting.

*
Use the dsr::Buffer object instead of C allocation calls, to let it automatically free your memory when nobody keeps the reference counted handle.
You can then work on its memory using SafePointer, which provides bound checks in debug mode, but must be kept close to the buffer's reference counted handle to keep the data it points to alive.
<- Buffers.html | Read about the Buffer API

*
Remember that a reference in C++ is a pointer under the C++ syntax, which can also cause crashes if taken from a location in memory that may be freed during the call.
If you passed "const SomeClass &object" from "List<SomeClass>" to a function that can reallocate the list that the object is stored in, this can cause a crash by referring to a memory location that got replaced by the list.
If you instead pass "SomeClass object" from "List<SomeClass>", the object will be copied in the call instead of referring to freed memory.
Returning a reference to a stack allocated variable, can also cause crashes with references.

---
Title2: The application crashes, but the debugger does not detect it.

Use a debugger directly on the application with debug symbols enabled when compiling.
Connecting Valgrind to the script used to run your application will catch memory leaks, but not invalid memory access.
Without debug symbols, you can see which method crashed, but not the line.
---

Title2: Getting linker errors when creating a new project without a window.

Linking to a window manager without using it may cause linker errors because the renderer library makes a call to outside of the library.
If you have linked with guiAPI.cpp, you need to import DFPSR.DsrHead in your *.DsrProj build script.
If the Graphics variable is default assigned to 1 before DFPSR.DsrHead is imported, a window manager will be selected based on which system you are compiling for.
If the Graphics variable did not exist, was accidentally placed after the DFPSR.DsrHead import, or you assigned it to 0, then NoWindow.cpp will be used as a stub implementation to throw an exception if someone tries to actually create a window.
---
