WIP: Emit a warning in case of possible memory leaks#428
WIP: Emit a warning in case of possible memory leaks#428antocuni wants to merge 27 commits intoheavyai:mainfrom
Conversation
…e memory leaks and warns the user
…because the old one didn't work with @omnisci
pearu
left a comment
There was a problem hiding this comment.
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.
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 ado 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:
AutoFreeBuffersandfree_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=Trueto the@rjitdecorator.Possible follow-ups/improvements:
disable_leak_warningsflag (suggestions are welcome)