Closed gogoex closed 1 year ago
If you want to call mclBnG1_clear for a static variable, then it is not necessary because mclBnG1 is an array of uint64_t and it will be filled with zero.
I prepared a minimum example that can reproduce the problem: https://github.com/gogoex/mcl-bls-sample
That sample does not call mclBnG1_clear, so the problem does not reproduce.
If there is one file to have static variables, how about calling blsInit
in the other static variable?
#include "./mcl_wrapper.h"
struct Init {
Init()
{
int ret = blsInit(MCL_BLS12_381, MCLBN_COMPILED_TIME_VAR);
printf("ret=%d\n", ret);
}
} s_init; // the constructor will be called at first before the other static variables.
mclBnG1 MclWrapper::m_p;
If you want to call mclBnG1_clear for a static variable, then it is not necessary because mclBnG1 is an array of uint64_t and it will be filled with zero.
The problem is that even if we don't call any Mcl function, if mclBnG1 variable is declared as a static variable, mcl::FpT<mcl::bn::local::FpTag, 384ul>::clear is called while static variables are instantiated.
I prepared a minimum example that can reproduce the problem: https://github.com/gogoex/mcl-bls-sample
That sample does not call mclBnG1_clear, so the problem does not reproduce. If there is one file to have static variables, how about calling
blsInit
in the other static variable?#include "./mcl_wrapper.h" struct Init { Init() { int ret = blsInit(MCL_BLS12_381, MCLBN_COMPILED_TIME_VAR); printf("ret=%d\n", ret); } } s_init; // the constructor will be called at first before the other static variables. mclBnG1 MclWrapper::m_p;
Thanks. We have actually tried the idea in our actual codebase, and that solved the problem. But for some reason that caused memory leaks and made address sanitizer checks fail. I will try to reproduce the situation using the minimum example.
The problem is that even if we don't call any Mcl function, if mclBnG1 variable is declared as a static variable, mcl::FpT<mcl::bn::local::FpTag, 384ul>::clear is called while static variables are instantiated.
It seems strange. I tested your code, but it does not show any error.
diff --git a/src/main.cpp b/src/main.cpp
index 03e4e60..ed87c57 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,6 +1,8 @@
#include "./mcl_wrapper.h"
+#include <stdio.h>
int main() {
MclWrapper x;
+ puts("ok");
return 0;
g++ -g -O2 -Wall -I/usr/local/include -Isrc/bls/include -Isrc/bls/mcl/include -I/usr/local/lib -I/usr/local/include -I/usr/local/include -c main.cpp -o main.o
main.cpp: In function 'int main()':
main.cpp:5:16: warning: unused variable 'x' [-Wunused-variable]
5 | MclWrapper x;
| ^
mcl-bls-sample% ./test
ok
Ubuntu 22.04.2 LTS + g++-11.3.0 + Intel CPU with -O0 and -O2 option.
Could you try libbls384_256.a in https://github.com/herumi/bls-eth-go-binary/tree/master/bls/lib/linux/amd64 ? This is a compiled library with BLS_ETH=1, which contains libmcl.a, so you don't need link libmcl.a.
Thank you. I tried but I'm still seeing the seg fault. My environment is Ubuntu 20.04 LTS + g++-9.4.0 + AMD Ryzen 9 with -O0 option. Do you have any idea?
g++ main.o mcl_wrapper.o herumi/libbls384_256.a src/bls/mcl/lib/libmcl.a -lpthread -o test
ryzen (gogoex: main): ~/repos/mcl-bls-sample
$ make run
./test
make: *** [Makefile:38: run] Segmentation fault (core dumped)
ryzen (gogoex: main): ~/repos/mcl-bls-sample
$ g++ --version
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
g++ main.o mcl_wrapper.o herumi/libbls384_256.a src/bls/mcl/lib/libmcl.a -lpthread -o test
src/bls/mcl/lib/libmcl.a
is not necessary for https://github.com/herumi/bls-eth-go-binary/blob/master/bls/lib/linux/amd64/libbls384_256.a .
Can you make the binary by g++ main.o main.o mcl_wrapper.o -o test
?
main.cpp
and mcl_wrapper.cpp
do not call any mcl functions, so I can build test
without linking mcl library.
Sorry. I realized that my make clean
was not deleting object files and because of that, an older version of mcl_wrapper.o
that calls mclBnG1_clear
in the constructor had been used. Now I don't see segmentation fault either.
Following your first comment, I will try to remove mclBnG1_clear
call from a class constructor that is instantiated with a static variable.
I could confirm that not calling mclBnG1_clear
resolves the segfault problem. Thank you for your help. I will close this issue.
But for some reason, I observe that the initial values change when we try with our codebase. I will create a minimum code to confirm it and if needed, I will create a issue.
When
mclBnG1
instance is created as (or under) a static variable,mcl::FpT<mcl::bn::local::FpTag, 384ul>::clear
is called during the static initialization phase the main function is called. Then that results in a segmentation fault.From experiments, I found in non-static context, calling
blsInit
before instantiatingmclBnG1
instance solves the problem. But I haven't been able to find a way to do it in static context.To build the library, I'm using:
and the library is used this way:
GDB back trace:
The environment:
I prepared a minimum example that can reproduce the problem: https://github.com/gogoex/mcl-bls-sample