Skip to content

Add malloc free leak detector scripts #59

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

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

magne-hov
Copy link

@magne-hov magne-hov commented Mar 5, 2025

This PR adds scripts implementing a malloc/free leak detector to the addons repository.

This feature was originally implemented by Chris Croft-White.

@magne-hov magne-hov requested a review from barisione March 5, 2025 18:23
all: memchecker.undo

clean:
rm *.undo *.pyc memchecker
Copy link
Collaborator

@barisione barisione Mar 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any recent Python would create .pyc files in the same directory. They should go in __pycache__.

Removing all recordings is a bit scary as it may remove things customers put in there and didn't want deleted. Maybe just remove memchecker and memchecker.undo?

int *addr = (int *)malloc(10 * sizeof(int));
printf("Address allocated: %p\n", addr);

if (!(i % 10 == 0))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why !(something == something) instead of something != something? Am I missing something silly?

A comment explaining what this is doing could also be useful to users.


print(
f"""\
The {script.name!r} script can be run outside of UDB:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use textwrap.dedent.

gdb.Breakpoint("free")

# Declare allocations dictionary structure.
allocations = collections.OrderedDict()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just use a dict as it has been ordered since Python 3.6 (I think).

if udb.time.get().bbcount >= end_of_time:
break

# Use the $PC output to get the symbol and idenfity whether execution has stopped
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo indefity.

# Do "continue" until we have gone through the whole recording, potentially
# hitting the breakpoints several times.
end_of_time = udb.get_event_log_extent().end
while True:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is likely to break if there are signals in the recording. I guess it doesn't particularly matter, but maybe we should expose signals_suspended from our internal API.


print(f"{time}: malloc() called: {size} byte(s) allocated at {addr}.")

elif re.search("free", mypc):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here.


if addr:
# Store details in the dictionary.
allocations[hex(addr)] = time, size
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be cleanear if the address was stored as an integer rather than its string representation.

else:
print("--- INFO: Free called with null address")

# with redirect_to_launcher_output():
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete this commented out line?

for location, (time, size) in allocations.items():
total += size
print("===============================================================================")
print(f"{time}: {size} bytes was allocated at {location}, but never freed.")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And then here location can be printed as {location:#x}.

@barisione
Copy link
Collaborator

There's nothing that really needs addressing here, but I made a few suggestions. Let me know which ones you don't think are worth addressing.

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.

2 participants