diff --git a/.github/workflows/test-sync.yml b/.github/workflows/test-sync.yml index 00824ed..f36fd49 100644 --- a/.github/workflows/test-sync.yml +++ b/.github/workflows/test-sync.yml @@ -339,13 +339,15 @@ jobs: & "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\Msbuild\\Current\\Bin\\amd64\\msbuild" -v:m /m /p:Configuration=Debug p2pool.vcxproj - name: Run p2pool + shell: cmd run: | + call "C:\\Program Files\\Microsoft Visual Studio\\2022\\Enterprise\\VC\\Auxiliary\\Build\\vcvarsall.bat" amd64 cd build/Debug mkdir data - Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 1" - Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 2" - Start-Process python -ArgumentList "../../tests/src/stratum_dummy.py 3" - ./p2pool.exe --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --mini --out-peers 200 --data-api data --local-api --loglevel 6 + start python ../../tests/src/stratum_dummy.py 1 + start python ../../tests/src/stratum_dummy.py 2 + start python ../../tests/src/stratum_dummy.py 3 + p2pool.exe --host xmrnode.facspro.net --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --wallet 44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg --mini --out-peers 200 --data-api data --local-api --loglevel 6 - name: Check p2pool.log run: | diff --git a/cmake/flags.cmake b/cmake/flags.cmake index 4ddc9de..1aac963 100644 --- a/cmake/flags.cmake +++ b/cmake/flags.cmake @@ -67,7 +67,7 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU) endif() endif() elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(GENERAL_FLAGS "/MP") + set(GENERAL_FLAGS "/MP /EHa") set(WARNING_FLAGS "/Wall /WX /sdl") set(SECURITY_FLAGS "/GS /guard:cf") set(OPTIMIZATION_FLAGS "/O2 /Oi /Ob2 /Ot /DNDEBUG /GL") diff --git a/src/common.h b/src/common.h index c5468ad..7ab2c6f 100644 --- a/src/common.h +++ b/src/common.h @@ -19,7 +19,7 @@ #ifdef _MSC_VER -#pragma warning(disable : 4005 4061 4324 4365 4464 4619 4625 4626 4668 4710 4711 4804 4820 5039 5045 5220 5246 5264) +#pragma warning(disable : 4005 4061 4324 4365 4464 4619 4625 4626 4668 4710 4711 4714 4804 4820 5039 5045 5220 5246 5264) #define FORCEINLINE __forceinline #define NOINLINE __declspec(noinline) #define LIKELY(expression) expression diff --git a/src/log.cpp b/src/log.cpp index f20b9b0..2d2593d 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -44,8 +44,66 @@ bool CONSOLE_COLORS = true; #ifdef _WIN32 static const HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); static const HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); -static const HANDLE hStdErr = GetStdHandle(STD_ERROR_HANDLE); -#endif + +#if defined(_MSC_VER) && !defined(NDEBUG) + +#include + +#pragma comment(lib, "Dbghelp.lib") + +LONG WINAPI UnhandledExceptionFilter(_In_ _EXCEPTION_POINTERS* exception_pointers) +{ + constexpr size_t MAX_FRAMES = 32; + + void* stack_trace[MAX_FRAMES] = {}; + DWORD hash; + CaptureStackBackTrace(1, MAX_FRAMES, stack_trace, &hash); + + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)] = {}; + PSYMBOL_INFO pSymbol = reinterpret_cast(buffer); + + pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); + pSymbol->MaxNameLen = MAX_SYM_NAME; + + IMAGEHLP_LINE64 line{}; + line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + + const HANDLE h = GetCurrentProcess(); + + const uint32_t code = (exception_pointers && exception_pointers->ExceptionRecord) ? exception_pointers->ExceptionRecord->ExceptionCode : 0; + + fprintf(stderr, "\n\nUnhandled exception %X at:\n", code); + fflush(stderr); + + for (size_t j = 0; j < MAX_FRAMES; ++j) { + const DWORD64 address = reinterpret_cast(stack_trace[j]); + DWORD t = 0; + if (SymFromAddr(h, address, nullptr, pSymbol) && SymGetLineFromAddr64(h, address, &t, &line)) { + fprintf(stderr, "%s (%s, line %lu)\n", line.FileName, pSymbol->Name, line.LineNumber); + fflush(stderr); + } + } + + fprintf(stderr, "\n\n"); + fflush(stderr); + + // Normal logging might be broken at this point, but try to log it anyway + LOGERR(0, "Unhandled exception " << log::Hex(code) << " at:"); + + for (size_t j = 0; j < MAX_FRAMES; ++j) { + const DWORD64 address = reinterpret_cast(stack_trace[j]); + DWORD t = 0; + if (SymFromAddr(h, address, nullptr, pSymbol) && SymGetLineFromAddr64(h, address, &t, &line)) { + LOGERR(0, line.FileName << " (" << static_cast(pSymbol->Name) << ", line " << static_cast(line.LineNumber) << ')'); + } + } + + Sleep(1000); + + return EXCEPTION_CONTINUE_SEARCH; +} +#endif // _MSC_VER && !NDEBUG +#endif // _WIN32 class Worker { @@ -62,6 +120,11 @@ public: , m_started{ false } , m_stopped(false) { +#if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG) + SetUnhandledExceptionFilter(UnhandledExceptionFilter); + SymInitialize(GetCurrentProcess(), NULL, TRUE); +#endif + set_main_thread(); std::setlocale(LC_ALL, "en_001"); @@ -140,6 +203,10 @@ public: #endif m_logFile.close(); + +#if defined(_WIN32) && defined(_MSC_VER) && !defined(NDEBUG) + SymCleanup(GetCurrentProcess()); +#endif } FORCEINLINE void write(const char* buf, uint32_t size) @@ -245,12 +312,7 @@ private: strip_colors(p, size); } -#ifdef _WIN32 - DWORD k; - WriteConsole((severity == 1) ? hStdOut : hStdErr, p, size, &k, nullptr); -#else fwrite(p, 1, size, (severity == 1) ? stdout : stderr); -#endif if (m_logFile.is_open()) { if (c) { @@ -289,6 +351,9 @@ private: m_logFile.open(log_file_name, std::ios::app | std::ios::binary); } } + + fflush(stdout); + fflush(stderr); } while (1); } diff --git a/src/memory_leak_debug.cpp b/src/memory_leak_debug.cpp index 05a8f89..0aef9d7 100644 --- a/src/memory_leak_debug.cpp +++ b/src/memory_leak_debug.cpp @@ -18,7 +18,7 @@ #include "common.h" // Simple memory leak detector for Windows users, works best in RelWithDebInfo configuration. -#if defined(_WIN32) && defined(DEV_TRACK_MEMORY) +#if defined(_WIN32) && defined(DEV_TRACK_MEMORY) && defined(_MSC_VER) && !defined(NDEBUG) #include "uv_util.h" #include @@ -270,8 +270,6 @@ void memory_tracking_start() // Trigger std::ostream initialization to avoid reporting it as leaks std::cout << "Memory leak detection = " << 1 << std::endl; - SymInitialize(GetCurrentProcess(), NULL, TRUE); - using namespace p2pool; uv_replace_allocator(malloc_hook, realloc_hook, calloc_hook, free_hook); @@ -307,8 +305,6 @@ bool memory_tracking_stop() printf("No memory leaks detected\n\n"); } - SymCleanup(h); - return (total_leaks == 0); } diff --git a/src/p2p_server.cpp b/src/p2p_server.cpp index c5bbe6b..446dd2d 100644 --- a/src/p2p_server.cpp +++ b/src/p2p_server.cpp @@ -34,8 +34,8 @@ LOG_CATEGORY(P2PServer) static constexpr char saved_peer_list_file_name[] = "p2pool_peers.txt"; -static const char* seed_nodes[] = { "seeds.p2pool.io", "main.p2poolpeers.net", ""}; -static const char* seed_nodes_mini[] = { "seeds-mini.p2pool.io", "mini.p2poolpeers.net", "" }; +static const char* seed_nodes[] = { "seeds.p2pool.io", "main.p2poolpeers.net", "main.gupax.io", "" }; +static const char* seed_nodes_mini[] = { "seeds-mini.p2pool.io", "mini.p2poolpeers.net", "mini.gupax.io", "" }; static constexpr int DEFAULT_BACKLOG = 16; static constexpr uint64_t DEFAULT_BAN_TIME = 600; diff --git a/src/util.cpp b/src/util.cpp index c76fa68..bf5210d 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -508,22 +508,29 @@ bool get_dns_txt_records_base(const std::string& host, CallbackpNext) { - for (size_t j = 0; j < p->Data.TXT.dwStringCount; ++j) { - const char* s = p->Data.TXT.pStringArray[j]; - const size_t n = strlen(s); - if (n > 0) { - callback(s, n); + for (PDNS_RECORD p = pQueryResults; p; p = p->pNext) { + for (size_t j = 0; j < p->Data.TXT.dwStringCount; ++j) { + const char* s = p->Data.TXT.pStringArray[j]; + if (s) { + const size_t n = strlen(s); + if (n > 0) { + callback(s, n); + } + } } } - } - DnsRecordListFree(pQueryResults, DnsFreeRecordList); + DnsRecordListFree(pQueryResults, DnsFreeRecordList); + } + catch (...) { + return false; + } return true; #elif defined(HAVE_RES_QUERY)