Skip to content
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

Implement optional pretty printed stacktraces #2420

Merged
merged 8 commits into from
Feb 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ci/matrix.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ elif [ "$BUILD_TARGET" = "linux32" ]; then
export HOST=i686-pc-linux-gnu
export PACKAGES="g++-multilib bc python3-zmq"
export DEP_OPTS="NO_QT=1"
export BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
export BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports --enable-stacktraces LDFLAGS=-static-libstdc++"
export USE_SHELL="/bin/dash"
export PYZMQ=true
export RUN_TESTS=true
elif [ "$BUILD_TARGET" = "linux64" ]; then
export HOST=x86_64-unknown-linux-gnu
export PACKAGES="bc python3-zmq"
export DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1"
export BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports"
export BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports --enable-stacktraces"
export CPPFLAGS="-DDEBUG_LOCKORDER -DENABLE_DASH_DEBUG"
export PYZMQ=true
export RUN_TESTS=true
Expand Down
34 changes: 34 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,13 @@ AC_ARG_ENABLE([debug],
[enable_debug=$enableval],
[enable_debug=no])

# Enable exception stacktraces
AC_ARG_ENABLE([stacktraces],
[AS_HELP_STRING([--enable-stacktraces],
[gather and print exception stack traces (default is no)])],
[enable_stacktraces=$enableval],
[enable_stacktraces=no])

# Turn warnings into errors
AC_ARG_ENABLE([werror],
[AS_HELP_STRING([--enable-werror],
Expand All @@ -211,8 +218,34 @@ if test "x$enable_debug" = xyes; then
if test "x$GXX" = xyes; then
CXXFLAGS="$CXXFLAGS -g3 -O0"
fi
elif test "x$enable_stacktraces" = xyes; then
# Enable debug information but don't turn off optimization
# (stacktraces will be suboptimal, but better than nothing)
if test "x$GCC" = xyes; then
CFLAGS="$CFLAGS -g1 -fno-omit-frame-pointer"
fi

if test "x$GXX" = xyes; then
CXXFLAGS="$CXXFLAGS -g1 -fno-omit-frame-pointer"
fi
fi

AM_CONDITIONAL([ENABLE_STACKTRACES], [test x$enable_stacktraces = xyes])
if test "x$enable_stacktraces" = xyes; then
AC_DEFINE(ENABLE_STACKTRACES, 1, [Define this symbol if stacktraces should be enables])
fi
AX_CHECK_LINK_FLAG([-Wl,-wrap=__cxa_allocate_exception], [LINK_WRAP_SUPPORTED=yes],,,)
AX_CHECK_COMPILE_FLAG([-rdynamic], [RDYNAMIC_SUPPORTED=yes],,,)
AM_CONDITIONAL([STACKTRACE_WRAPPED_CXX_ABI],[test x$LINK_WRAP_SUPPORTED = xyes])
AM_CONDITIONAL([RDYNAMIC_SUPPORTED],[test x$RDYNAMIC_SUPPORTED = xyes])

if test x$LINK_WRAP_SUPPORTED = "xyes"; then
AC_DEFINE(STACKTRACE_WRAPPED_CXX_ABI, 1, [Define this symbol to use wrapped CXX ABIs for exception stacktraces])],
fi

# Needed for MinGW targets when debug symbols are enabled as compiled objects get very large
AX_CHECK_COMPILE_FLAG([-Wa,-mbig-obj], [CXXFLAGS="$CXXFLAGS -Wa,-mbig-obj"],,,)

ERROR_CXXFLAGS=
if test "x$enable_werror" = "xyes"; then
if test "x$CXXFLAG_WERROR" = "x"; then
Expand Down Expand Up @@ -1209,6 +1242,7 @@ echo " with test = $use_tests"
echo " with bench = $use_bench"
echo " with upnp = $use_upnp"
echo " debug enabled = $enable_debug"
echo " stacktraces enabled = $enable_stacktraces"
echo " werror = $enable_werror"
echo
echo " target os = $TARGET_OS"
Expand Down
21 changes: 21 additions & 0 deletions depends/packages/backtrace.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package=backtrace
$(package)_version=rust-snapshot-2018-05-22
$(package)_download_path=https://github.com/rust-lang-nursery/libbacktrace/archive
$(package)_file_name=$($(package)_version).tar.gz
$(package)_sha256_hash=8da6daa0a582c9bbd1f2933501168b4c43664700f604f43e922e85b99e5049bc

define $(package)_set_vars
$(package)_config_opts=--disable-shared --prefix=$(host_prefix)
endef

define $(package)_config_cmds
$($(package)_autoconf)
endef

define $(package)_build_cmds
$(MAKE)
endef

define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install
endef
2 changes: 1 addition & 1 deletion depends/packages/packages.mk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
packages:=boost openssl libevent zeromq gmp chia_bls
packages:=boost openssl libevent zeromq gmp chia_bls backtrace
native_packages := native_ccache

qt_native_packages = native_protobuf
Expand Down
7 changes: 6 additions & 1 deletion qa/rpc-tests/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,12 @@ def main(self):

if not self.options.noshutdown:
print("Stopping nodes")
stop_nodes(self.nodes)
try:
stop_nodes(self.nodes)
except BaseException as e:
success = False
print("Unexpected exception caught during shutdown: " + repr(e))
traceback.print_tb(sys.exc_info()[2])
else:
print("Note: dashds were not stopped and may still be running")

Expand Down
37 changes: 31 additions & 6 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,29 @@ AM_CXXFLAGS = $(HARDENED_CXXFLAGS) $(ERROR_CXXFLAGS)
AM_CPPFLAGS = $(HARDENED_CPPFLAGS)
EXTRA_LIBRARIES =

if ENABLE_STACKTRACES
if STACKTRACE_WRAPPED_CXX_ABI
# Wrap internal C++ ABI's so that we can attach stacktraces to exceptions
LDFLAGS_WRAP_EXCEPTIONS = -Wl,-wrap,__cxa_allocate_exception -Wl,-wrap,__cxa_free_exception
if TARGET_WINDOWS
LDFLAGS_WRAP_EXCEPTIONS += -Wl,-wrap,_assert -Wl,-wrap,_wassert
else
LDFLAGS_WRAP_EXCEPTIONS += -Wl,-wrap,__assert_fail
endif
endif

if RDYNAMIC_SUPPORTED
# This gives better stacktraces
AM_CXXFLAGS += -rdynamic
endif
endif

if TARGET_WINDOWS
BACKTRACE_LIB = -ldbghelp -lbacktrace
else
BACKTRACE_LIB = -lbacktrace
endif

if EMBEDDED_UNIVALUE
LIBUNIVALUE = univalue/libunivalue.la

Expand Down Expand Up @@ -184,6 +207,7 @@ BITCOIN_CORE_H = \
script/standard.h \
script/ismine.h \
spork.h \
stacktraces.h \
streams.h \
support/allocators/mt_pooled_secure.h \
support/allocators/pooled_secure.h \
Expand Down Expand Up @@ -464,6 +488,7 @@ libdash_util_a_SOURCES = \
compat/strnlen.cpp \
random.cpp \
rpc/protocol.cpp \
stacktraces.cpp \
support/cleanse.cpp \
sync.cpp \
threadinterrupt.cpp \
Expand Down Expand Up @@ -492,7 +517,7 @@ nodist_libdash_util_a_SOURCES = $(srcdir)/obj/build.h
dashd_SOURCES = dashd.cpp
dashd_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
dashd_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
dashd_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
dashd_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)

if TARGET_WINDOWS
dashd_SOURCES += dashd-res.rc
Expand All @@ -511,13 +536,13 @@ dashd_LDADD = \
$(LIBMEMENV) \
$(LIBSECP256K1)

dashd_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(BLS_LIBS)
dashd_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(BLS_LIBS)

# dash-cli binary #
dash_cli_SOURCES = dash-cli.cpp
dash_cli_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CFLAGS)
dash_cli_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
dash_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
dash_cli_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)

if TARGET_WINDOWS
dash_cli_SOURCES += dash-cli-res.rc
Expand All @@ -528,14 +553,14 @@ dash_cli_LDADD = \
$(LIBUNIVALUE) \
$(LIBBITCOIN_UTIL) \
$(LIBBITCOIN_CRYPTO)
dash_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) $(BLS_LIBS)
dash_cli_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) $(BLS_LIBS)
#

# dash-tx binary #
dash_tx_SOURCES = dash-tx.cpp
dash_tx_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
dash_tx_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
dash_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
dash_tx_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)

if TARGET_WINDOWS
dash_tx_SOURCES += dash-tx-res.rc
Expand All @@ -549,7 +574,7 @@ dash_tx_LDADD = \
$(LIBBITCOIN_CRYPTO) \
$(LIBSECP256K1)

dash_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) $(BLS_LIBS)
dash_tx_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(CRYPTO_LIBS) $(BLS_LIBS)
#

# dashconsensus library #
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.bench.include
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ bench_bench_dash_SOURCES += bench/coin_selection.cpp
bench_bench_dash_LDADD += $(LIBBITCOIN_WALLET) $(LIBBITCOIN_CRYPTO)
endif

bench_bench_dash_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(BLS_LIBS)
bench_bench_dash_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
bench_bench_dash_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(BLS_LIBS)
bench_bench_dash_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)

CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno $(GENERATED_TEST_FILES)

Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -643,9 +643,9 @@ if ENABLE_ZMQ
qt_dash_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
endif
qt_dash_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
$(BACKTRACE_LIB) $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(BLS_LIBS)
qt_dash_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
qt_dash_qt_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
qt_dash_qt_LIBTOOLFLAGS = --tag CXX

#locale/foo.ts -> locale/foo.qm
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.qttest.include
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ if ENABLE_ZMQ
qt_test_test_dash_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
endif
qt_test_test_dash_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
$(LIBMEMENV) $(BACKTRACE_LIB) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
$(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(BLS_LIBS)
qt_test_test_dash_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
qt_test_test_dash_qt_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
qt_test_test_dash_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)

CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,14 @@ endif
test_test_dash_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
test_test_dash_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_CFLAGS)
test_test_dash_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS)
$(BACKTRACE_LIB) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS)
test_test_dash_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
if ENABLE_WALLET
test_test_dash_LDADD += $(LIBBITCOIN_WALLET)
endif

test_test_dash_LDADD += $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(BLS_LIBS)
test_test_dash_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
test_test_dash_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static

if ENABLE_ZMQ
test_test_dash_LDADD += $(ZMQ_LIBS)
Expand Down
4 changes: 4 additions & 0 deletions src/bench/bench_dash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "bench.h"

#include "key.h"
#include "stacktraces.h"
#include "validation.h"
#include "util.h"

Expand All @@ -16,6 +17,9 @@ void CleanupBLSDkgTests();
int
main(int argc, char** argv)
{
RegisterPrettySignalHandlers();
RegisterPrettyTerminateHander();

ECC_Start();
ECCVerifyHandle verifyHandle;

Expand Down
17 changes: 7 additions & 10 deletions src/dash-cli.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "clientversion.h"
#include "rpc/client.h"
#include "rpc/protocol.h"
#include "stacktraces.h"
#include "util.h"
#include "utilstrencodings.h"

Expand Down Expand Up @@ -350,7 +351,7 @@ int CommandLineRPC(int argc, char *argv[])
nRet = EXIT_FAILURE;
}
catch (...) {
PrintExceptionContinue(NULL, "CommandLineRPC()");
PrintExceptionContinue(std::current_exception(), "CommandLineRPC()");
throw;
}

Expand All @@ -362,6 +363,9 @@ int CommandLineRPC(int argc, char *argv[])

int main(int argc, char* argv[])
{
RegisterPrettyTerminateHander();
RegisterPrettySignalHandlers();

SetupEnvironment();
if (!SetupNetworking()) {
fprintf(stderr, "Error: Initializing networking failed\n");
Expand All @@ -372,23 +376,16 @@ int main(int argc, char* argv[])
int ret = AppInitRPC(argc, argv);
if (ret != CONTINUE_EXECUTION)
return ret;
}
catch (const std::exception& e) {
PrintExceptionContinue(&e, "AppInitRPC()");
return EXIT_FAILURE;
} catch (...) {
PrintExceptionContinue(NULL, "AppInitRPC()");
PrintExceptionContinue(std::current_exception(), "AppInitRPC()");
return EXIT_FAILURE;
}

int ret = EXIT_FAILURE;
try {
ret = CommandLineRPC(argc, argv);
}
catch (const std::exception& e) {
PrintExceptionContinue(&e, "CommandLineRPC()");
} catch (...) {
PrintExceptionContinue(NULL, "CommandLineRPC()");
PrintExceptionContinue(std::current_exception(), "CommandLineRPC()");
}
return ret;
}
17 changes: 8 additions & 9 deletions src/dash-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <boost/algorithm/string.hpp>
#include <boost/assign/list_of.hpp>

#include "stacktraces.h"

static bool fCreateBlank;
static std::map<std::string,UniValue> registers;
static const int CONTINUE_EXECUTION=-1;
Expand Down Expand Up @@ -772,7 +774,7 @@ static int CommandLineRawTx(int argc, char* argv[])
nRet = EXIT_FAILURE;
}
catch (...) {
PrintExceptionContinue(NULL, "CommandLineRawTx()");
PrintExceptionContinue(std::current_exception(), "CommandLineRawTx()");
throw;
}

Expand All @@ -784,6 +786,9 @@ static int CommandLineRawTx(int argc, char* argv[])

int main(int argc, char* argv[])
{
RegisterPrettyTerminateHander();
RegisterPrettySignalHandlers();

SetupEnvironment();

try {
Expand All @@ -792,21 +797,15 @@ int main(int argc, char* argv[])
return ret;
}
catch (const std::exception& e) {
PrintExceptionContinue(&e, "AppInitRawTx()");
return EXIT_FAILURE;
} catch (...) {
PrintExceptionContinue(NULL, "AppInitRawTx()");
PrintExceptionContinue(std::current_exception(), "AppInitRawTx()");
return EXIT_FAILURE;
}

int ret = EXIT_FAILURE;
try {
ret = CommandLineRawTx(argc, argv);
}
catch (const std::exception& e) {
PrintExceptionContinue(&e, "CommandLineRawTx()");
} catch (...) {
PrintExceptionContinue(NULL, "CommandLineRawTx()");
PrintExceptionContinue(std::current_exception(), "CommandLineRawTx()");
}
return ret;
}
Loading