-
Notifications
You must be signed in to change notification settings - Fork 196
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
Segmentation fault when building with ENABLE_OVERRIDE=1 and linking it statically #297
Comments
Did you build w/ |
No, as you can see from the CMake excerpt. It makes no sense semantically to have to add it because I am not preloading it but statically linking it. I tested it and adding (Fortunately, memory allocation was only performance-critical at one location and I could make use of rpmalloc by defining a |
I can't reproduce this in either |
I can still reproduce the same segfault like this: git clone --recursive [email protected]:mxmlnkn/rapidgzip.git
cd rapidgzip
git checkout rapidgzip-v0.11.1
sed -i 's|ENABLE_OVERRIDE=0|ENABLE_OVERRIDE=1|' src/CMakeLists.txt
mkdir build
cd build
cmake ..
make rapidgzip
gdb -ex r -ex bt --args src/tools/rapidgzip --help I'm currently using it with |
You can try the |
The issue in your case is that the global c++ constructors tries to new/delete - and that rpmalloc is not yet initialized. |
Thank you for figuring that out. The rewrite branch does not segfault on a simple startup! It seems I've also head similar initialization order issues without class RpmallocInit
{
public:
RpmallocInit()
{
rpmalloc_initialize();
}
~RpmallocInit()
{
rpmalloc_finalize();
}
};
/* It must be the very first static variable so that rpmalloc is initialized before any usage of malloc
* when overriding operator new (when including rpnew.h). And, this only works if everything is header-only
* because else the static variable initialization order becomes undefined across different compile units.
* That's why we avoid overriding operators new and delete and simply use it as a custom allocator in the
* few places we know to be performance-critical */
inline static const RpmallocInit rpmallocInit{}; |
Yeah, unfortunately the order of global constructors like that is not well defined, there is no guarantee that it will be the first thing called. Give the rewrite a try, I am running some additional test and will promote it to the develop branch shortly if all looks good, heading for a 2.0 release early next year. |
Some questions for the proper upgrade procedure:
I have pushed this change to my CI: commit 08ef8ca31caf3be97a11effe8de477c0d4f12c2b (HEAD -> zlib-support, origin/zlib-support)
Author: mxmlnkn <[email protected]>
Date: Sat Dec 23 10:55:15 2023 +0100
[wip][build] Update to rpmalloc rewrite
diff --git a/src/core/FasterVector.hpp b/src/core/FasterVector.hpp
index 8c4847f4..019d8d94 100644
--- a/src/core/FasterVector.hpp
+++ b/src/core/FasterVector.hpp
@@ -12,7 +12,7 @@ class RpmallocInit
public:
RpmallocInit()
{
- rpmalloc_initialize();
+ rpmalloc_initialize( nullptr );
}
~RpmallocInit()
diff --git a/src/core/JoiningThread.hpp b/src/core/JoiningThread.hpp
index 0040ff6e..78a2a5d9 100644
--- a/src/core/JoiningThread.hpp
+++ b/src/core/JoiningThread.hpp
@@ -19,7 +19,7 @@ public:
~RpmallocThreadInit()
{
- rpmalloc_thread_finalize( /* release caches */ true );
+ rpmalloc_thread_finalize();
}
};
#endif
diff --git a/src/external/rpmalloc b/src/external/rpmalloc
index f4732ee2..395b352a 160000
--- a/src/external/rpmalloc
+++ b/src/external/rpmalloc
@@ -1 +1 @@
-Subproject commit f4732ee2b8a5a838cf52cfcd6bc4a44bdc084ef2
+Subproject commit 395b352a3ebd8d2c4298e20702b40abf7e9942ac Rpmalloc does not build on the Windows CI anymore: rpmalloc-windows.log My other CI tests with and without sanitizers run fine on Linux. |
C doesn't have default values for arguments, so would require an extra entry point. In general the rewrite branch doesn't require to explicitly use any of the initialize/finalize entry points unless you want to do it at specific points. It uses thread or fiber local ctor/dtor to do it internally. Can still be used for explicit thread init/fini if you plan to use thread pools or similar and don't want idle thread to hang on to heaps. Thread finalize does not have any similar concept of cache release as the thread heaps work differently now. rpmalloc_initialize can as you say just take a null pointer for default values of everything and use OS mmap/unmap to grab memory. Will look at making the arg const, good point. |
The rewrite branch uses the C11 built in atomics, which for Microsoft toolchain requires the compiler flags |
That sounds awesome! I see that this would make a class JoiningThread
{
public:
template<class Function, class... Args>
explicit
JoiningThread( Function&& function, Args&&... args ) :
#ifdef WITH_RPMALLOC
m_thread( [=] () {
static const thread_local RpmallocThreadInit rpmallocThreadInit{};
function( std::forward<Args>( args )... );
} )
#else
m_thread( std::forward<Function>( function ), std::forward<Args>( args )... )
#endif
{}
...
private:
std::thread m_thread;
}; |
Yeah, you should be able to remove that and have ENABLE_OVERRIDE=1 (which it is by default on that branch) |
Did you have a chance to try out the rewrite branch? |
Not much further than in my earlier comment #297 (comment). It seemed to work fine, though. I did try to add |
I thought I had a pretty simple setup. I'm building rpmalloc with
ENABLE_OVERRIDE
and then link it into my program. My program does not even include rpmalloc.h or calls from rpmalloc. It only contains a simple main that returns 0. And I still get this SIGSEV error:CMake excerpt for rpmalloc:
I'm not sure whether I'm using it wrong or whether it is a bug. Some example setups would have been helpful.
I'm making heavy use of static initialization. I'm not sure whether that might be triggering this problem. I can try to minimize the example if the backtrace doesn't ring a bell for you.
The text was updated successfully, but these errors were encountered: