-
Notifications
You must be signed in to change notification settings - Fork 71
Fixed coverity issues in acl_hal_mmd.cpp #227
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
Conversation
In the original code, there is this if-statement starting at line 581:
As you can see, in the even that |
src/acl_hal_mmd.cpp
Outdated
@@ -1168,6 +1169,7 @@ static acl_mmd_dispatch_t *get_msim_mmd_layer() { | |||
return nullptr; | |||
} | |||
auto *sym = my_dlsym(mmd_lib, sym_name, &error_msg); | |||
my_dlclose(mmd_lib); |
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.
Closing the library invalidates the symbol return by dlsym()
, which means calling the function further down is undefined behaviour. These dlopen()
-related leaks are likely nontrivial to fix and require a redesign. You could start with a RAII-safe wrapper, e.g.,
struct dl_wrapper {
dl_wrapper(...) { this->handle = dlopen(...); }
~dl_wrapper() { dlclose(this->handle); }
// prohibit copying to avoid double-close of handle
dl_wrapper(const dl_wrapper &) = delete;
dl_wrapper &operator=(const dl_wrapper &) = delete;
void *sym(...) { return dlsym(this->handle, ...); }
};
The nontrivial part is where to store the wrapper object to ensure the symbols remain valid over the lifetime of their intended use. Maybe there is an easier solution to avoid the resource leak?
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.
The solution I proposes in this PR is to keep track of the opened libraries with a wrapper of a vector of mmd_libs in the global scope. The wrapper would be similar to the one you proposed. The vector would deallocate with the closing of the runtime library, and all the libraries present inside will close themselves through the destructor.
I got this vector idea from std::vector<acl_mmd_dispatch_t> internal_mmd_dispatch
. This vector is where all the symbols end up going and is declared as a global vector in the .cpp file.
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.
Thanks @haoxian2, this is going in the right direction. The RAII wrapper should fully encapsulate the management of the resource; ideally, the constructor acquires the resource, currently my_dlopen()
, and the destructor releases the resource, currently my_dlclose()
.
However, the situation here is slightly more complicated by the presence of two methods to load the library, my_dlopen()
versus my_dlopen_global()
. Let me take a detailed look at this issue before working out a solution.
4fbcebc
to
539f27b
Compare
a11a652
to
e909e10
Compare
e909e10
to
84bf6c3
Compare
f4f66a1
to
aa1b484
Compare
f72927c
to
564b19e
Compare
7a7b907
to
c6df82c
Compare
This is a cosmetic change only to prepare the next commit.
mmd_libraries were not closed after execution, which causes memory leaks. But mmd_libraries cannot be closed trivially since closing the library invalidates the symbol return by dlsym(), which means calling the function further down is undefined behaviour. To solve this issues, I added a `dl_wrapper_t` vector as a global initialized vector that would be deallocated when closing the runtime library. This vector would contain all the opened libraries that would be closed by the destructor of `dl_wrapper_t` once the vector deallocates.
c6df82c
to
ddb091d
Compare
Fixed coverity issues in acl_hal_mmd.cpp: Type: Resource leak (RESOURCE_LEAK)
mmd_libraries were not closed after execution, which causes memory leaks. But mmd_libraries cannot be closed trivially since closing the library invalidates the symbol return by dlsym(), which means calling the function further down is undefined behaviour.
To solve this issues, I added a
dl_wrapper_t
struct as a global initialized wrapper that would be deallocated when closing the runtime library. This wrapper would contain all the opened libraries in a vector that would be closed by the destructor ofdl_wrapper_t
before the vector deallocates.