Browse Source

feat(debug/macos/windows): imp macos/windows backtrace, fix mem issue

GitOrigin-RevId: 9bed738bb5
release-1.2
Megvii Engine Team 4 years ago
parent
commit
783a612643
3 changed files with 82 additions and 17 deletions
  1. +1
    -1
      imperative/CMakeLists.txt
  2. +80
    -15
      src/core/impl/utils/debug.cpp
  3. +1
    -1
      src/core/include/megbrain/utils/debug.h

+ 1
- 1
imperative/CMakeLists.txt View File

@@ -56,7 +56,7 @@ if (APPLE)
elseif (MSVC OR WIN32)
# Windows does not support implicitly importing data members from DLL.
target_link_libraries(${MODULE_NAME} PRIVATE megbrain megdnn)
message(STATUS, "CMAKE_MSVC_RUNTIME_LIBRARY: ${CMAKE_MSVC_RUNTIME_LIBRARY}")
message(STATUS "CMAKE_MSVC_RUNTIME_LIBRARY: ${CMAKE_MSVC_RUNTIME_LIBRARY}")
set_target_properties(${MODULE_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY "${CMAKE_MSVC_RUNTIME_LIBRARY}")
else()
if (MGE_WITH_PYTHON_MODULE)


+ 80
- 15
src/core/impl/utils/debug.cpp View File

@@ -51,6 +51,15 @@ using namespace debug;
#endif
#endif

#if defined(WIN32)
#include <process.h>
#include <windows.h>
#include <iostream>
#include <sstream>
#include "dbghelp.h"
#pragma comment(lib, "dbghelp.lib")
#endif

#ifdef __ANDROID__
namespace {

@@ -98,6 +107,7 @@ struct MemmapEntry {
: low(low_), high(high_), file(file_) {}
};

#if !defined (WIN32) && ! defined (__APPLE__)
void get_mem_map(
int pid,
thin_function<void(uintptr_t, uintptr_t, const char*, const char*)>
@@ -125,6 +135,7 @@ void get_mem_map(
}
fclose(fin);
}
#endif

#ifndef WIN32
// FIXME: imp SigHandlerInit backtrace for windows
@@ -146,12 +157,9 @@ class SigHandlerInit {
mgb_log_error("%s: caught deadly signal %d(%s)", msg0, signum,
strsignal(signum));
}
// FIXME: imp backtrace for macos
#ifndef __APPLE__
std::string bp;
debug::backtrace(2).fmt_to_str(bp);
mgb_log_error("%s", bp.c_str());
#endif
exit(EXIT_FAILURE);
}

@@ -228,16 +236,69 @@ void (*ForkAfterCudaError::throw_)() = throw_fork_cuda_exc;
std::atomic_size_t ScopedForkWarningSupress::sm_depth{0};

BacktraceResult mgb::debug::backtrace(int nr_exclude) {
#ifndef WIN32
static bool thread_local recursive_call = false;
constexpr size_t MAX_DEPTH = 12;
void* stack_mem[MAX_DEPTH];
if (recursive_call) {
fprintf(stderr, "recursive call to backtrace()!\n");
return {};
}
recursive_call = true;
BacktraceResult result;

constexpr size_t MAX_DEPTH = 6;
void* stack_mem[MAX_DEPTH];
#if defined(WIN32)
WORD i = 0;
SYMBOL_INFO* pSymbol;
HANDLE p = GetCurrentProcess();
SymInitialize(p, NULL, TRUE);
if (!p) {
recursive_call = false;
return {};
}
pSymbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + 256 * sizeof(char), 1);
WORD depth = CaptureStackBackTrace(0, MAX_DEPTH, stack_mem, NULL);
if (depth > nr_exclude)
i = nr_exclude;
for (; i < depth; ++i) {
std::ostringstream frame_info;
DWORD64 address = (DWORD64)(stack_mem[i]);
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = 128;

DWORD displacementLine = 0;
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

if (SymFromAddr(p, address, 0, pSymbol) &&
SymGetLineFromAddr64(p, address, &displacementLine, &line)) {
frame_info << i << " " << line.FileName << ":" << line.LineNumber
<< " " << pSymbol->Name << std::endl;
} else {
frame_info << i << " "
<< "null" << std::endl;
}
auto frame = std::string{frame_info.str().c_str()};
result.stack.emplace_back(frame, i);
}
free(pSymbol);

recursive_call = false;
return result;
#elif defined(__APPLE__)
int i = 0;
int depth = ::backtrace(stack_mem, MAX_DEPTH);
char** strs = backtrace_symbols(stack_mem, depth);
if (depth > nr_exclude)
i = nr_exclude;
for (; i < depth; ++i) {
auto frame = std::string{strs[i]};
result.stack.emplace_back(frame, i);
}
free(strs);

recursive_call = false;
return result;
#else
int depth = ::backtrace(stack_mem, MAX_DEPTH);
auto stack = stack_mem;
if (depth > nr_exclude) {
@@ -257,7 +318,6 @@ BacktraceResult mgb::debug::backtrace(int nr_exclude) {
});
}
}
BacktraceResult result;

for (int i = 0; i < depth; ++i) {
const char* fname = nullptr;
@@ -273,33 +333,37 @@ BacktraceResult mgb::debug::backtrace(int nr_exclude) {
fname = j.file.c_str();
break;
}
result.stack.emplace_back(fname, addr);
auto frame = std::string{fname};
result.stack.emplace_back(frame, addr);
}

recursive_call = false;
return result;
#else
// FIXME: imp Backtrace for windows
BacktraceResult result;
return result;
#endif
}

void BacktraceResult::fmt_to_str(std::string& dst) {
#if defined(WIN32) || defined(__APPLE__)
dst.append("bt:\n");
for (auto&& i : stack) {
dst.append(i.first);
dst.append("\n");
}
#else
char addr[128];
bool first = true;
const char* prev_fname = nullptr;
dst.append("bt:");
for (auto&& i : stack) {
sprintf(addr, "%zx", i.second);
if (i.first != prev_fname || first) {
if (i.first.c_str() != prev_fname || first) {
if (!first)
dst.append("}");
if (i.first)
if (i.first.c_str())
dst.append(i.first);
else
dst.append("unknown");
prev_fname = i.first;
prev_fname = i.first.c_str();
first = false;
dst.append("{");
dst.append(addr);
@@ -309,6 +373,7 @@ void BacktraceResult::fmt_to_str(std::string& dst) {
}
}
dst.append("}");
#endif
}

void debug::set_fork_cuda_warning_flag(int flag) {


+ 1
- 1
src/core/include/megbrain/utils/debug.h View File

@@ -32,7 +32,7 @@ namespace debug {
};

struct BacktraceResult {
std::vector<std::pair<const char*, size_t>> stack;
std::vector<std::pair<std::string, size_t>> stack;

/*!
* \brief format and write to dst


Loading…
Cancel
Save