elements
elements copied to clipboard
Segfault on Alpine 3.18.5
OS: Alpine 3.18.5 Arch: x86_64 Elements version: v23.2.1
When testing a PeerSwap swap (patched with https://github.com/ElementsProject/peerswap/pull/257) , elementsd segfaults.
The segfault seems to occur when PeerSwap tries to create the initial swap open transaction.
gdb backtrace here:
0x0000555555a89360 in BlindTransaction (input_value_blinding_factors=...,
input_asset_blinding_factors=..., input_assets=..., input_amounts=...,
out_val_blind_factors=..., out_asset_blind_factors=..., output_pubkeys=...,
issuance_blinding_privkey=..., token_blinding_privkey=..., tx=...,
auxiliary_generators=0x0) at blind.cpp:287
287 {
(gdb) backtrace #0 0x0000555555a89360 in BlindTransaction (input_value_blinding_factors=..., input_asset_blinding_factors=..., input_assets=..., input_amounts=..., out_val_blind_factors=...,
out_asset_blind_factors=..., output_pubkeys=..., issuance_blinding_privkey=..., token_blinding_privkey=..., tx=..., auxiliary_generators=0x0) at blind.cpp:287
#1 0x0000555555a11b98 in wallet::CreateTransactionInternal (wallet=..., vecSend=..., tx=..., nFeeRet=@0x7ffff56e9e18: 0, nChangePosInOut=@0x7ffff56e9e14: 1, error=...,
coin_control=..., fee_calc_out=..., sign=<optimized out>, blind_details=<optimized out>, issuance_details=<optimized out>) at wallet/spend.cpp:1444
#2 0x0000555555a1428b in wallet::CreateTransaction (wallet=..., vecSend=..., tx=..., nFeeRet=@0x7ffff56e9e18: 0, nChangePosInOut=@0x7ffff56e9e14: 1, error=..., coin_control=...,
fee_calc_out=..., sign=false, blind_details=0x7fff9330eb50, issuance_details=0x0) at wallet/spend.cpp:1759
#3 0x0000555555a15453 in wallet::FundTransaction (wallet=..., tx=..., nFeeRet=@0x7ffff56e9e18: 0, nChangePosInOut=@0x7ffff56e9e14: 1, error=...,
lockUnspents=lockUnspents@entry=false, setSubtractFeeFromOutputs=..., coinControl=...) at wallet/spend.cpp:1823
#4 0x0000555555c29220 in wallet::FundTransaction (wallet=..., tx=..., fee_out=@0x7ffff56e9e18: 0, change_position=@0x7ffff56e9e14: 1, options=..., coinControl=...,
solving_data=..., override_min_fee=<optimized out>) at wallet/rpc/spend.cpp:711
#5 0x0000555555c2e37f in operator() (request=..., self=..., __closure=<optimized out>) at /usr/include/c++/12.2.1/bits/shared_ptr_base.h:1665
#6 0x0000555555c2e8b4 in std::__invoke_impl<UniValue, wallet::fundrawtransaction()::<lambda(const RPCHelpMan&, const JSONRPCRequest&)>&, const RPCHelpMan&, const JSONRPCRequest&> (
__f=...) at /usr/include/c++/12.2.1/bits/invoke.h:60
#7 std::__invoke_r<UniValue, wallet::fundrawtransaction()::<lambda(const RPCHelpMan&, const JSONRPCRequest&)>&, const RPCHelpMan&, const JSONRPCRequest&> (__fn=...)
at /usr/include/c++/12.2.1/bits/invoke.h:116
#8 std::_Function_handler<UniValue(const RPCHelpMan&, const JSONRPCRequest&), wallet::fundrawtransaction()::<lambda(const RPCHelpMan&, const JSONRPCRequest&)> >::_M_invoke(const std:
:_Any_data &, const RPCHelpMan &, const JSONRPCRequest &) (__functor=..., __args#0=..., __args#1=...) at /usr/include/c++/12.2.1/bits/std_function.h:291
#9 0x0000555555b2c3af in std::function<UniValue (RPCHelpMan const&, JSONRPCRequest const&)>::operator()(RPCHelpMan const&, JSONRPCRequest const&) const (__args#1=..., __args#0=...,
this=0x7ffff56ea590) at /usr/include/c++/12.2.1/bits/std_function.h:591
#10 RPCHelpMan::HandleRequest (this=this@entry=0x7ffff56ea570, request=...) at rpc/util.cpp:599
#11 0x00005555557c368a in CRPCCommand::CRPCCommand(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, RPCHelpMan (*)())::{lambda(JSONRPCRequest const&, U
niValue&, bool)#1}::operator()(JSONRPCRequest const&, UniValue&, bool) const (request=..., result=..., __closure=<optimized out>) at ./rpc/server.h:109
#12 0x00005555559aa5a3 in std::function<bool (JSONRPCRequest const&, UniValue&, bool)>::operator()(JSONRPCRequest const&, UniValue&, bool) const (__args#2=<optimized out>,
__args#1=..., __args#0=..., this=<optimized out>) at /usr/include/c++/12.2.1/bits/std_function.h:591
#13 operator() (__closure=0x7ffff7990d80, request=..., result=..., last_handler=<optimized out>) at wallet/interfaces.cpp:543
#14 0x0000555555735029 in std::function<bool (JSONRPCRequest const&, UniValue&, bool)>::operator()(JSONRPCRequest const&, UniValue&, bool) const (__args#2=<optimized out>,
__args#1=..., __args#0=..., this=<optimized out>) at /usr/include/c++/12.2.1/bits/std_function.h:591
#15 operator() (__closure=<optimized out>, last_handler=true, result=..., request=...) at node/interfaces.cpp:421
#16 std::__invoke_impl<bool, node::(anonymous namespace)::RpcHandlerImpl::RpcHandlerImpl(const CRPCCommand&)::<lambda(const JSONRPCRequest&, UniValue&, bool)>&, const JSONRPCRequest&,
UniValue&, bool> (__f=...) at /usr/include/c++/12.2.1/bits/invoke.h:61
#17 std::__invoke_r<bool, node::(anonymous namespace)::RpcHandlerImpl::RpcHandlerImpl(const CRPCCommand&)::<lambda(const JSONRPCRequest&, UniValue&, bool)>&, const JSONRPCRequest&, Un
iValue&, bool> (__fn=...) at /usr/include/c++/12.2.1/bits/invoke.h:114
#18 std::_Function_handler<bool(const JSONRPCRequest&, UniValue&, bool), node::(anonymous namespace)::RpcHandlerImpl::RpcHandlerImpl(const CRPCCommand&)::<lambda(const JSONRPCRequest&
, UniValue&, bool)> >::_M_invoke(const std::_Any_data &, const JSONRPCRequest &, UniValue &, bool &&) (__functor=..., __args#0=..., __args#1=..., __args#2=<optimized out>)
at /usr/include/c++/12.2.1/bits/std_function.h:290
#19 0x000055555587bddc in std::function<bool (JSONRPCRequest const&, UniValue&, bool)>::operator()(JSONRPCRequest const&, UniValue&, bool) const (__args#2=<optimized out>,
__args#1=..., __args#0=..., this=0x7ffff7990e18) at /usr/include/c++/12.2.1/bits/std_function.h:591
#20 ExecuteCommand (command=..., request=..., result=..., last_handler=<optimized out>) at rpc/server.cpp:478
#21 0x000055555587c31c in ExecuteCommands (result=..., request=..., commands=...) at rpc/server.cpp:444
#22 CRPCTable::execute (this=0x555556058e60 <tableRPC>, request=...) at rpc/server.cpp:464
#23 0x000055555595a7f0 in HTTPReq_JSONRPC (context=..., req=<optimized out>) at httprpc.cpp:202
#24 0x0000555555968cfd in std::function<bool (HTTPRequest*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::operator()(HTTPRequest*, std::__c
xx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (__args#1=..., __args#0=<optimized out>, this=0x7fff92ab4880)
#25 HTTPWorkItem::operator() (this=0x7fff92ab4850) at httpserver.cpp:54
#26 WorkQueue<HTTPClosure>::Run (this=this@entry=0x7ffff57558c0) at httpserver.cpp:112
#27 0x0000555555963f11 in HTTPWorkQueueRun (queue=0x7ffff57558c0, worker_num=<optimized out>) at httpserver.cpp:344
#28 0x00007ffff7aed1e3 in ?? () from /usr/lib/libstdc++.so.6
#29 0x00007ffff7fb9bc2 in ?? () from /lib/ld-musl-x86_64.so.1
#30 0x0000000000000000 in ?? ()
Can confirm elementsd 22.1.1 segfaults at the same point as well.
Here is a backtrace using 22.1.1 built with --enable-debug
:
Thread 16 "b-httpworker.1" received signal SIGSEGV, Segmentation fault. [Switching to LWP 27449]
0x0000555555ae12c0 in BlindTransaction (input_value_blinding_factors=...,
input_asset_blinding_factors=..., input_assets=..., input_amounts=...,
out_val_blind_factors=..., out_asset_blind_factors=..., output_pubkeys=...,
issuance_blinding_privkey=..., token_blinding_privkey=..., tx=...,
auxiliary_generators=0x0) at blind.cpp:287
287 {
(gdb) backtrace
#0 0x0000555555ae12c0 in BlindTransaction (input_value_blinding_factors=..., input_asset_blinding_factors=..., input_assets=..., input_amounts=..., out_val_blind_factors=..., out_asset_blind_factors=..., output_pubkeys=..., issuance_blinding_privkey=..., token_blinding_privkey=..., tx=..., auxiliary_generators=0x0) at blind.cpp:287
#1 0x0000555555a7382c in CWallet::CreateTransactionInternal (this=this@entry=0x7ffff5743570, vecSend=..., tx=..., nFeeRet=@0x7ffff56d8eb8: 140735612360454,
nChangePosInOut=@0x7ffff56d8eb4: 0, error=..., coin_control=..., fee_calc_out=..., sign=<optimized out>, blind_details=<optimized out>, issuance_details=<optimized out>)
at wallet/spend.cpp:1361
#2 0x0000555555a7513b in CWallet::CreateTransaction (this=this@entry=0x7ffff5743570, vecSend=..., tx=..., nFeeRet=@0x7ffff56d8eb8: 140735612360454,
nChangePosInOut=@0x7ffff56d8eb4: 0, error=..., coin_control=..., fee_calc_out=..., sign=false, blind_details=0x7ffff524a7f0, issuance_details=0x0) at wallet/spend.cpp:1670
#3 0x0000555555a76303 in CWallet::FundTransaction (this=this@entry=0x7ffff5743570, tx=..., nFeeRet=@0x7ffff56d8eb8: 140735612360454, nChangePosInOut=@0x7ffff56d8eb4: 0, error=...,
lockUnspents=lockUnspents@entry=false, setSubtractFeeFromOutputs=..., coinControl=...) at wallet/spend.cpp:1735
#4 0x0000555555a2a779 in FundTransaction (wallet=..., tx=..., fee_out=@0x7ffff56d8eb8: 140735612360454, change_position=@0x7ffff56d8eb4: 0, options=..., coinControl=...,
solving_data=..., override_min_fee=<optimized out>) at wallet/rpcwallet.cpp:3515
#5 0x0000555555a2f7d2 in operator() (request=..., self=..., __closure=<optimized out>) at wallet/rpcwallet.cpp:3631
#6 0x0000555555a2fc84 in std::__invoke_impl<UniValue, fundrawtransaction()::<lambda(const RPCHelpMan&, const JSONRPCRequest&)>&, const RPCHelpMan&, const JSONRPCRequest&> (__f=...)
at /usr/include/c++/12.2.1/bits/invoke.h:60
#7 std::__invoke_r<UniValue, fundrawtransaction()::<lambda(const RPCHelpMan&, const JSONRPCRequest&)>&, const RPCHelpMan&, const JSONRPCRequest&> (__fn=...)
at /usr/include/c++/12.2.1/bits/invoke.h:116
#8 std::_Function_handler<UniValue(const RPCHelpMan&, const JSONRPCRequest&), fundrawtransaction()::<lambda(const RPCHelpMan&, const JSONRPCRequest&)> >::_M_invoke(const std::_Any_da
ta &, const RPCHelpMan &, const JSONRPCRequest &) (__functor=..., __args#0=..., __args#1=...) at /usr/include/c++/12.2.1/bits/std_function.h:291
#9 0x0000555555b7e05f in std::function<UniValue (RPCHelpMan const&, JSONRPCRequest const&)>::operator()(RPCHelpMan const&, JSONRPCRequest const&) const (__args#1=..., __args#0=...,
this=0x7ffff56d95a0) at /usr/include/c++/12.2.1/bits/std_function.h:591
#10 RPCHelpMan::HandleRequest (this=this@entry=0x7ffff56d9580, request=...) at rpc/util.cpp:588
#11 0x00005555557a2c7a in CRPCCommand::CRPCCommand(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, RPCHelpMan (*)())::{lambda(JSONRPCRequest const&, U
niValue&, bool)#1}::operator()(JSONRPCRequest const&, UniValue&, bool) const (request=..., result=..., __closure=<optimized out>) at ./rpc/server.h:110
#12 0x00005555559814b3 in std::function<bool (JSONRPCRequest const&, UniValue&, bool)>::operator()(JSONRPCRequest const&, UniValue&, bool) const (__args#2=<optimized out>,
__args#1=..., __args#0=..., this=<optimized out>) at /usr/include/c++/12.2.1/bits/std_function.h:591
#13 operator() (__closure=0x7ffff7972990, request=..., result=..., last_handler=<optimized out>) at wallet/interfaces.cpp:530
#14 0x000055555571c7b9 in std::function<bool (JSONRPCRequest const&, UniValue&, bool)>::operator()(JSONRPCRequest const&, UniValue&, bool) const (__args#2=<optimized out>,
__args#1=..., __args#0=..., this=<optimized out>) at /usr/include/c++/12.2.1/bits/std_function.h:591
#15 operator() (__closure=<optimized out>, last_handler=true, result=..., request=...) at node/interfaces.cpp:397
#16 std::__invoke_impl<bool, node::(anonymous namespace)::RpcHandlerImpl::RpcHandlerImpl(const CRPCCommand&)::<lambda(const JSONRPCRequest&, UniValue&, bool)>&, const JSONRPCRequest&,
UniValue&, bool> (__f=...) at /usr/include/c++/12.2.1/bits/invoke.h:61
#17 std::__invoke_r<bool, node::(anonymous namespace)::RpcHandlerImpl::RpcHandlerImpl(const CRPCCommand&)::<lambda(const JSONRPCRequest&, UniValue&, bool)>&, const JSONRPCRequest&, Un
iValue&, bool> (__fn=...) at /usr/include/c++/12.2.1/bits/invoke.h:114
#18 std::_Function_handler<bool(const JSONRPCRequest&, UniValue&, bool), node::(anonymous namespace)::RpcHandlerImpl::RpcHandlerImpl(const CRPCCommand&)::<lambda(const JSONRPCRequest&, UniValue&, bool)> >::_M_invoke(const std::_Any_data &, const JSONRPCRequest &, UniValue &, bool &&) (__functor=..., __args#0=..., __args#1=..., __args#2=<optimized out>)
at /usr/include/c++/12.2.1/bits/std_function.h:290
#19 0x0000555555856f2c in std::function<bool (JSONRPCRequest const&, UniValue&, bool)>::operator()(JSONRPCRequest const&, UniValue&, bool) const (__args#2=<optimized out>,
__args#1=..., __args#0=..., this=0x7ffff7972a28) at /usr/include/c++/12.2.1/bits/std_function.h:591
#20 ExecuteCommand (command=..., request=..., result=..., last_handler=<optimized out>) at rpc/server.cpp:478
#21 0x000055555585746c in ExecuteCommands (result=..., request=..., commands=...) at rpc/server.cpp:444
#22 CRPCTable::execute (this=0x555555fe5aa0 <tableRPC>, request=...) at rpc/server.cpp:464
#23 0x000055555592f2de in HTTPReq_JSONRPC (context=..., req=<optimized out>) at httprpc.cpp:202
#24 0x000055555593dced in std::function<bool (HTTPRequest*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>::operator()(HTTPRequest*, std::__c--Type <RET> for more, q to quit, c to continue without paging--
xx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (__args#1=..., __args#0=<optimized out>, this=0x7fff92bab630)
at /usr/include/c++/12.2.1/bits/std_function.h:591
#25 HTTPWorkItem::operator() (this=0x7fff92bab600) at httpserver.cpp:49
#26 WorkQueue<HTTPClosure>::Run (this=this@entry=0x7ffff573c060) at httpserver.cpp:107
#27 0x0000555555938eb7 in HTTPWorkQueueRun (queue=0x7ffff573c060, worker_num=<optimized out>) at httpserver.cpp:337
#28 0x00007ffff7aed1e3 in ?? () from /usr/lib/libstdc++.so.6
#29 0x00007ffff7fb9bc2 in ?? () from /lib/ld-musl-x86_64.so.1
#30 0x0000000000000000 in ?? ()
Does this also happen with 0.21 ?
When did testing with Alpine/musl begin (has it ever worked?)
Just trying to figure out if it's a new or existing issue.
Will dig into it and try reproduce.
I can't seem to build 0.21 on Alpine 3.18 so not sure there. I just started testing unfortunately.
Managed to compile, and ran the functional test suite. There are about 100 different functional tests failing, so presumably Elements has never worked completely on Alpine Linux.
I will work on figuring out what is causing these issues.
my current suspicion is the Alpine Linux thread stack size, which is much lower than gnu/linux: https://serverfault.com/a/1123054
https://ariadne.space/2021/06/25/understanding-thread-stack-sizes-and-how-alpine-is-different/
Looks like we could maybe try to detect if using Alpine/musl and adjust the LDFLAGS
when building?
yeah that sounds like it might work, i’m busy trying the docker env var above.
I compiled with LDFLAGS="-Wl,-z,stack-size=1024768"
and elementsd
did not crash when attempting a swap.