Programmer
This project implements MemDebugger, a custom memory debugging tool for C++ applications. By overriding the global new and delete operators, it intercepts memory allocation and deallocation calls. The tool tracks each allocation, recording its size, type (single object or array), and the call site address. Upon program termination, it checks for memory blocks that were allocated but never deallocated, reporting these as memory leaks. It also includes logic to detect potential double-delete errors. To aid debugging, particularly on Windows, it utilizes the DbgHelp library to resolve the memory addresses associated with leaks back to the specific source file and line number where the allocation occurred. A key component is the custom Mallocator, designed using malloc and free, which prevents infinite recursion issues that could arise from the debugger's internal data structures using the overridden new operator. The build process uses CMake, incorporating basic considerations for cross-platform compilation. The primary output is a CSV report detailing detected memory issues.
Aug 2023 ~ Jan 2024
My achievements
Implemented Memory Leak Detection: Successfully created functionality to track memory allocations and identify leaks by checking for un-deallocated memory blocks upon program termination. It records allocation information and checks the deallocation status in the destructor.
Symbol Information Retrieval: Utilized the DbgHelp library on Windows to resolve memory allocation and leak addresses to their original source file names and line numbers. This significantly improves debugging efficiency.
Double Delete Detection Logic: Implemented initial logic to detect attempts to deallocate memory that has already been freed (double delete).
Custom Memory Allocator (Mallocator): Developed a custom STL allocator (Mallocator) based on malloc/free to solve the potential infinite recursion problem where standard library containers (like std::vector used internally) might call the overridden new/delete operators. Applying this to internal data structures ensures stability.
Challenges
Complexity of Overriding Global new/delete: Overriding global memory allocation/deallocation operators impacts the entire program and presented challenges in ensuring stability without conflicts or unexpected side effects. Critically, using the Mallocator for the debugger's internal data structures was essential to prevent recursion.
Thread Safety Issues: The current implementation is not thread-safe. Concurrent memory allocations/deallocations from multiple threads could lead to race conditions when accessing the shared allocations vector. Implementing synchronization mechanisms (like mutexes) is necessary for thread safety.
Wonhyeong Chae
