mirror of
https://github.com/dashpay/dash.git
synced 2024-12-28 05:23:01 +01:00
48d92f116e
* Add libbacktrace to depends This is currently only useful to extract symbols. It fails to gather stacktraces when compiled with MinGW, so we can only use it to get symbol information from a stack trace which we gathered outside of libbacktrace. * Add -mbig-obj to CXXFLAGS for MinGW builds * Implement stacktraces for C++ exceptions This is a hack and should only be used for debugging. It works by wrapping the C++ ABI __wrap___cxa_allocate_exception. The wrapper records a backtrace and stores it in a global map. Later the stacktrace can be retrieved with GetExceptionStacktraceStr. This commit also adds handlers to pretty print uncaught exceptions and signals. * Use GetPrettyExceptionStr for all unhandled exceptions * Use --enable-stacktraces in CI for linux32/linux64 * Register exception translators to pretty print exceptions in unit tests * Catch and print python exceptions when stopping nodes Otherwise the code at the bottom is never executed when nodes crash, leading to no output of debug.log files on Travis. * Remove now unneeded/unused TestCrash methods
206 lines
6.5 KiB
C++
206 lines
6.5 KiB
C++
// Copyright (c) 2009-2010 Satoshi Nakamoto
|
|
// Copyright (c) 2009-2015 The Bitcoin Core developers
|
|
// Copyright (c) 2014-2019 The Dash Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#if defined(HAVE_CONFIG_H)
|
|
#include "config/dash-config.h"
|
|
#endif
|
|
|
|
#include "chainparams.h"
|
|
#include "clientversion.h"
|
|
#include "compat.h"
|
|
#include "rpc/server.h"
|
|
#include "init.h"
|
|
#include "noui.h"
|
|
#include "scheduler.h"
|
|
#include "util.h"
|
|
#include "httpserver.h"
|
|
#include "httprpc.h"
|
|
#include "utilstrencodings.h"
|
|
#include "stacktraces.h"
|
|
|
|
#include <boost/algorithm/string/predicate.hpp>
|
|
#include <boost/filesystem.hpp>
|
|
#include <boost/thread.hpp>
|
|
|
|
#include <stdio.h>
|
|
|
|
/* Introduction text for doxygen: */
|
|
|
|
/*! \mainpage Developer documentation
|
|
*
|
|
* \section intro_sec Introduction
|
|
*
|
|
* This is the developer documentation of the reference client for an experimental new digital currency called Dash (https://www.dash.org/),
|
|
* which enables instant payments to anyone, anywhere in the world. Dash uses peer-to-peer technology to operate
|
|
* with no central authority: managing transactions and issuing money are carried out collectively by the network.
|
|
*
|
|
* The software is a community-driven open source project, released under the MIT license.
|
|
*
|
|
* \section Navigation
|
|
* Use the buttons <code>Namespaces</code>, <code>Classes</code> or <code>Files</code> at the top of the page to start navigating the code.
|
|
*/
|
|
|
|
void WaitForShutdown(boost::thread_group* threadGroup)
|
|
{
|
|
bool fShutdown = ShutdownRequested();
|
|
// Tell the main threads to shutdown.
|
|
while (!fShutdown)
|
|
{
|
|
MilliSleep(200);
|
|
fShutdown = ShutdownRequested();
|
|
}
|
|
if (threadGroup)
|
|
{
|
|
Interrupt(*threadGroup);
|
|
threadGroup->join_all();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Start
|
|
//
|
|
bool AppInit(int argc, char* argv[])
|
|
{
|
|
boost::thread_group threadGroup;
|
|
CScheduler scheduler;
|
|
|
|
bool fRet = false;
|
|
|
|
//
|
|
// Parameters
|
|
//
|
|
// If Qt is used, parameters/dash.conf are parsed in qt/dash.cpp's main()
|
|
ParseParameters(argc, argv);
|
|
|
|
// Process help and version before taking care about datadir
|
|
if (IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help") || IsArgSet("-version"))
|
|
{
|
|
std::string strUsage = strprintf(_("%s Daemon"), _(PACKAGE_NAME)) + " " + _("version") + " " + FormatFullVersion() + "\n";
|
|
|
|
if (IsArgSet("-version"))
|
|
{
|
|
strUsage += FormatParagraph(LicenseInfo());
|
|
}
|
|
else
|
|
{
|
|
strUsage += "\n" + _("Usage:") + "\n" +
|
|
" dashd [options] " + strprintf(_("Start %s Daemon"), _(PACKAGE_NAME)) + "\n";
|
|
|
|
strUsage += "\n" + HelpMessage(HMM_BITCOIND);
|
|
}
|
|
|
|
fprintf(stdout, "%s", strUsage.c_str());
|
|
return true;
|
|
}
|
|
|
|
try
|
|
{
|
|
bool datadirFromCmdLine = IsArgSet("-datadir");
|
|
if (datadirFromCmdLine && !boost::filesystem::is_directory(GetDataDir(false)))
|
|
{
|
|
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", GetArg("-datadir", "").c_str());
|
|
return false;
|
|
}
|
|
try
|
|
{
|
|
ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME));
|
|
} catch (const std::exception& e) {
|
|
fprintf(stderr,"Error reading configuration file: %s\n", e.what());
|
|
return false;
|
|
}
|
|
if (!datadirFromCmdLine && !boost::filesystem::is_directory(GetDataDir(false)))
|
|
{
|
|
fprintf(stderr, "Error: Specified data directory \"%s\" from config file does not exist.\n", GetArg("-datadir", "").c_str());
|
|
return EXIT_FAILURE;
|
|
}
|
|
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
|
|
try {
|
|
SelectParams(ChainNameFromCommandLine());
|
|
} catch (const std::exception& e) {
|
|
fprintf(stderr, "Error: %s\n", e.what());
|
|
return false;
|
|
}
|
|
|
|
// Command-line RPC
|
|
bool fCommandLine = false;
|
|
for (int i = 1; i < argc; i++)
|
|
if (!IsSwitchChar(argv[i][0]) && !boost::algorithm::istarts_with(argv[i], "dash:"))
|
|
fCommandLine = true;
|
|
|
|
if (fCommandLine)
|
|
{
|
|
fprintf(stderr, "Error: There is no RPC client functionality in dashd anymore. Use the dash-cli utility instead.\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
// -server defaults to true for bitcoind but not for the GUI so do this here
|
|
SoftSetBoolArg("-server", true);
|
|
// Set this early so that parameter interactions go to console
|
|
InitLogging();
|
|
InitParameterInteraction();
|
|
if (!AppInitBasicSetup())
|
|
{
|
|
// InitError will have been called with detailed error, which ends up on console
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if (!AppInitParameterInteraction())
|
|
{
|
|
// InitError will have been called with detailed error, which ends up on console
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if (!AppInitSanityChecks())
|
|
{
|
|
// InitError will have been called with detailed error, which ends up on console
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
if (GetBoolArg("-daemon", false))
|
|
{
|
|
#if HAVE_DECL_DAEMON
|
|
fprintf(stdout, "Dash Core server starting\n");
|
|
|
|
// Daemonize
|
|
if (daemon(1, 0)) { // don't chdir (1), do close FDs (0)
|
|
fprintf(stderr, "Error: daemon() failed: %s\n", strerror(errno));
|
|
return false;
|
|
}
|
|
#else
|
|
fprintf(stderr, "Error: -daemon is not supported on this operating system\n");
|
|
return false;
|
|
#endif // HAVE_DECL_DAEMON
|
|
}
|
|
|
|
fRet = AppInitMain(threadGroup, scheduler);
|
|
} catch (...) {
|
|
PrintExceptionContinue(std::current_exception(), "AppInit()");
|
|
}
|
|
|
|
if (!fRet)
|
|
{
|
|
Interrupt(threadGroup);
|
|
// threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
|
|
// the startup-failure cases to make sure they don't result in a hang due to some
|
|
// thread-blocking-waiting-for-another-thread-during-startup case
|
|
} else {
|
|
WaitForShutdown(&threadGroup);
|
|
}
|
|
Shutdown();
|
|
|
|
return fRet;
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
RegisterPrettyTerminateHander();
|
|
RegisterPrettySignalHandlers();
|
|
|
|
SetupEnvironment();
|
|
|
|
// Connect dashd signal handlers
|
|
noui_connect();
|
|
|
|
return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
|
|
}
|