Skip to content

Resolve strdup memory leak with GetPathBaseName#1106

Merged
xusheng6 merged 2 commits into
Vector35:devfrom
SmoothHacker:resolve-basename-memory-leak
Jul 3, 2026
Merged

Resolve strdup memory leak with GetPathBaseName#1106
xusheng6 merged 2 commits into
Vector35:devfrom
SmoothHacker:resolve-basename-memory-leak

Conversation

@SmoothHacker

Copy link
Copy Markdown
Contributor

Whenever DebugModule::GetPathBaseName and ModuleNameAndOffset::GetPathBaseName is called a memory leak the size of the c string version of the path parameter is created because of strdup(). The fix involves using std::filesystem. We create a std::filesystem::path object and then return the steam of that path.

…Name and ModuleNameAndOffset::GetPathBaseName
@CLAassistant

CLAassistant commented Jun 28, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

stem() strips the final extension, changing behavior from the original
POSIX basename() and the Windows branch (which both keep the extension).
This would mangle module names like libc.so.6 -> libc.so and break
module-name matching. filename() preserves the full final component.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@xusheng6

xusheng6 commented Jul 3, 2026

Copy link
Copy Markdown
Member

Thanks for fixing the strdup leak — that's a real leak worth removing. 👍

I pushed a one-line follow-up to your branch (627f0fa) changing .stem() to .filename().string(). Wanted to explain the reasoning:

stem() and basename() aren't equivalent. std::filesystem::path::stem() returns the filename with the final extension stripped, whereas the POSIX basename() you're replacing — and the Windows _splitpath_s branch, which returns baseName + ext — both keep the full final path component including the extension. So stem() silently changed the non-Windows behavior:

input old basename() / Windows branch stem() filename()
/usr/lib/libc.so.6 libc.so.6 libc.so libc.so.6
/usr/lib/libssl.so.1.1 libssl.so.1.1 libssl.so.1 libssl.so.1.1
/lib/foo.dll foo.dll foo foo.dll

GetPathBaseName is used only for module-name matching (IsSameBaseModule, StringsEqual, and setting m_short_name on Windows), so stripping the extension would have (a) made Linux/macOS inconsistent with the Windows branch, and (b) risked false matches like libfoo.so vs libfoo.dylib both collapsing to libfoo. filename() returns the full final component and matches the original semantics exactly.

I also added the explicit .string() since filename() returns a std::filesystem::path; the implicit conversion to std::string works on POSIX but being explicit is clearer.

The extra includes and the leak fix itself look good. One optional suggestion: a small unit test for GetPathBaseName (a versioned .so, a .dll, and an extensionless name) would guard this behavior going forward, especially now that the repo builds test binaries.

@xusheng6 xusheng6 merged commit 2d68ef3 into Vector35:dev Jul 3, 2026
1 check passed
@xusheng6

xusheng6 commented Jul 3, 2026

Copy link
Copy Markdown
Member

Thanks! @SmoothHacker

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants