Do not initialize pointers to original functions in (libc_)free#1956
Conversation
src/tbbmalloc_proxy/proxy.cpp
Outdated
|
|
||
| struct initOrigPointers { | ||
| initOrigPointers() { | ||
| if (!doInitOrigPointers) { |
There was a problem hiding this comment.
If I'm not mistaken, doInitOrigPointers is either always true or always false, depending on MALLOC_UNIXLIKE_OVERLOAD_ENABLED. Which means, doInitOrigPointers can be removed and this constructor should be empty unless MALLOC_UNIXLIKE_OVERLOAD_ENABLED is defined. If so, I would remove doInitOrigPointers and move the initOrigPointers class definition above the macro checks and define the constructor in the MALLOC_UNIXLIKE_OVERLOAD_ENABLED and MALLOC_ZONE_OVERLOAD_ENABLED sections.
There was a problem hiding this comment.
I removed doInitOrigPointers and used a preprocessor directive instead in order to keep the whole implementation in one place.
Done.
a4fc276 to
f6e3c2a
Compare
f6e3c2a to
76eabbf
Compare
|
@Lastique Does this patch fix your issue? |
|
If I remember correctly, it was done via initialization on 1st use because some overloaded malloc were called before static ctor runs. In the suggested code, are we sure that initOrigPointers::free etc contain 0 because they sit in bss? |
I didn't test this yet. I will probably have a chance to test it later this week.
The C++ standard guarantees that namespace-scope static variables are zero-initialized before constructors are run.
|
OK. I have verified this fix using the reproducer provided by @Lastique in #1907 (comment) and it works: root@dnp-02:/build/tbb/obj-x86_64-linux-gnu# make -j128 test ARGS\+=--verbose ARGS\+=-j128
[...]
100% tests passed, 0 tests failed out of 140
Total Test time (real) = 480.15 sec
root@dnp-02:/build/tbb/obj-x86_64-linux-gnu# ctest -I 137,140
Test project /build/tbb/obj-x86_64-linux-gnu
Start 137: test_malloc_atexit
1/4 Test #137: test_malloc_atexit ............... Passed 0.01 sec
Start 138: test_malloc_overload
2/4 Test #138: test_malloc_overload ............. Passed 0.02 sec
Start 139: test_malloc_overload_disable
3/4 Test #139: test_malloc_overload_disable ..... Passed 0.01 sec
Start 140: test_malloc_new_handler
4/4 Test #140: test_malloc_new_handler .......... Passed 0.01 sec
100% tests passed, 0 tests failed out of 4
Total Test time (real) = 0.05 sec |
So, free() is no-op, that is acceptable, but |
Do not initialize pointers to original functions in (libc_)free() because dlsym() calls (libc_)free() internally, what can cause the infinite recursion: (libc_)free -> InitOrigPointers -> dlsym -> (libc_)free. This patch fixes this issue. Fixes: uxlfoundation#1907 Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
76eabbf to
7f802d0
Compare
If no-op free() is acceptable then there is a much simpler fix that addresses the above mentioned issue. |
|
Note that the original code is not thread-safe, as accesses to This doesn't mean this has to be fixed in this PR, just an observation. Also, one other alternative to consider is the |
@Lastique There is a comment: |
|
@Alexandr-Konovalov @lplewa @KFilipek please re-review. |
|
@Alexandr-Konovalov @isaevil Can you merge it? |
|
My local TBB package build with the current version of this PR applied passed. Thanks. |
Description
Do not initialize pointers to original functions in
(libc_)free(),because
dlsym()calls(libc_)free()internally, what can causethe infinite recursion:
(libc_)free -> InitOrigPointers -> dlsym -> (libc_)free(see #1907).This patch fixes this issue.
Fixes: #1907
Type of change
Tests
Documentation
Breaks backward compatibility
Notify the following users
@Lastique