-
Notifications
You must be signed in to change notification settings - Fork 10
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
WIP: Emit a warning in case of possible memory leaks #428
base: main
Are you sure you want to change the base?
Conversation
…e memory leaks and warns the user
…because the old one didn't work with @omnisci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this looks good. Thanks, @antocuni!
I committed a change that includes some information about the function where a possible memory leak is detected. Feel free to adjust this change if needed.
I have a couple of concerns that should be addressed before merging the PR.
First, this PR disables automatic memory management of buffers and replaces it with a detection method of possible memory leaks. There are a number of tests that rely on automatic memory management and by disabling it, the PR actually may introduce memory leaks in cases where the automatic memory management worked. All these tests eject memory leak warnings and are therefore easy to locate.
Could you revise all the memory leak detection warnings reported in CI and updated the corresponding test functions to manage memory correctly?
Second, there exists false positive detection of possible memory leaks in cases where a function constructs a buffer object and returns it. For example, a false positive memory leak is detected in
https://github.com/xnd-project/rbc/blob/6d6ad969cb0de338f111d95695852c9a869432e7/rbc/tests/test_omnisci_text.py#L125-L133
Would it be possible to extend the memory detection method to the case where a buffer is constructed and no free
is called then the return
of the buffer will qualify as the existence of free
call?
…warn', 'fail' or 'ignore'
…n't emit MissingFree warnings
…est_omnisci_caller
…c into antocuni/detect-missing-free
class MissingFreeWarning(Warning): | ||
|
||
_msg = """ | ||
Possible memory leak detected in function `{}` defined in {}#{}! | ||
|
||
In RBC, arrays and buffers must be freed manually by calling the method | ||
.free() or the function free_buffer(): see the relevant docs. | ||
""" | ||
|
||
def __init__(self, functionname, filename, firstlineno): | ||
msg = self.make_message(functionname, filename, firstlineno) | ||
Warning.__init__(self, msg) | ||
|
||
@classmethod | ||
def make_message(cls, functionname, filename, firstlineno): | ||
return cls._msg.format(functionname, filename, firstlineno) | ||
|
||
|
||
class MissingFreeError(Exception): | ||
|
||
def __init__(self, functionname, filename, firstlineno): | ||
msg = MissingFreeWarning.make_message(functionname, filename, firstlineno) | ||
Exception.__init__(self, msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move those to rbc/errors.py
?
689a87d
to
f45b032
Compare
f45b032
to
055a060
Compare
42a9397
to
82e54bd
Compare
brilliant idea, thank you!
good point. To address it, I slightly changed the behavior: I removed the option
yes, I think it's possible and also a good idea but it's not completely straightforward. For example, consider this artificial case: def foo(flag):
a = Array(10)
if flag:
a = Array(20)
return a do we want RBC to emit a warning or not? |
Status update The tests keep failing as soon as they run
Some info on my machine:
I temporarily pushed commit 82e54bd which keeps only test_abs and dumps the llvm IR:
the two dumps look a bit differently, in particular the second seems to do more in the
i.e., the buffer is allocated by calling So, at the moment I have no clue about what's wrong. |
Highlights of this PR:
AutoFreeBuffers
andfree_all_other_buffers
: as discussed previously, they are broken and cannot be possibly fixedThe warning is triggered under very specific conditions, i.e. if inside a certain function:
xp.Array()
) ANDArray.free()
orfree_buffer(buf)
.The idea is that by doing this way, the casual user will learn that they needs to manage memory manually as soon as they starts to use arrays, but then they are on their own.
If the function emits a spurious warning, it is possible to disable it by passing
disable_leak_warnings=True
to the@rjit
decorator.Possible follow-ups/improvements:
disable_leak_warnings
flag (suggestions are welcome)