diff options
| author | ruki <[email protected]> | 2022-02-08 10:49:28 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-02-08 10:49:28 +0800 |
| commit | 6b74a4dcd274cf96f3b224975ca8a4580ebc0f65 (patch) | |
| tree | c38cbda0839b5a278e9d7431449a0d4576bb54f0 | |
| parent | c80d0c5638f83d7de838a09554daa48800c71fe3 (diff) | |
| parent | a4a168088d6032427769b0c9f1405e2eebcd5c66 (diff) | |
Merge pull request #2032 from xmake-io/catch
catch ctrl-c to get backtrace of stuck
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | core/src/xmake/engine.c | 75 | ||||
| -rw-r--r-- | xmake/core/base/coroutine.lua | 6 | ||||
| -rw-r--r-- | xmake/core/base/os.lua | 22 | ||||
| -rw-r--r-- | xmake/plugins/show/lists/envs.lua | 2 |
5 files changed, 91 insertions, 16 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index c82fd5000..2cd9552bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * [#2021](https://github.com/xmake-io/xmake/issues/2021): Support Swift for linux and windows * [#2024](https://github.com/xmake-io/xmake/issues/2024): Add asn1c support * [#2031](https://github.com/xmake-io/xmake/issues/2031): Support linker scripts and version scripts for add_files +* [#2033](https://github.com/xmake-io/xmake/issues/2033): Catch ctrl-c to get current backtrace for debugging stuck ### Bugs fixed @@ -1214,6 +1215,7 @@ * [#2021](https://github.com/xmake-io/xmake/issues/2021): 支持 Linux/Windows 下构建 Swift 程序 * [#2024](https://github.com/xmake-io/xmake/issues/2024): 添加 asn1c 支持 * [#2031](https://github.com/xmake-io/xmake/issues/2031): 为 add_files 增加 linker scripts 和 version scripts 支持 +* [#2033](https://github.com/xmake-io/xmake/issues/2033): 捕获 ctrl-c 去打印当前运行栈,用于调试分析卡死问题 ### Bugs 修复 diff --git a/core/src/xmake/engine.c b/core/src/xmake/engine.c index e87fce465..efc89977c 100644 --- a/core/src/xmake/engine.c +++ b/core/src/xmake/engine.c @@ -36,12 +36,15 @@ #elif defined(TB_CONFIG_OS_MACOSX) || defined(TB_CONFIG_OS_IOS) # include <unistd.h> # include <mach-o/dyld.h> +# include <signal.h> #elif defined(TB_CONFIG_OS_LINUX) || defined(TB_CONFIG_OS_BSD) || defined(TB_CONFIG_OS_ANDROID) # include <unistd.h> +# include <signal.h> #endif #ifdef TB_CONFIG_OS_BSD -# include <sys/types.h> -# include <sys/sysctl.h> +# include <sys/types.h> +# include <sys/sysctl.h> +# include <signal.h> #endif /* ////////////////////////////////////////////////////////////////////////////////////// @@ -448,6 +451,9 @@ static luaL_Reg const g_tty_functions[] = , { tb_null, tb_null } }; +// the lua global instance for signal handler +static lua_State* g_lua = tb_null; + /* ////////////////////////////////////////////////////////////////////////////////////// * private implementation */ @@ -492,16 +498,14 @@ static tb_bool_t xm_engine_save_arguments(xm_engine_t* engine, tb_int_t argc, tb // _ARGV = table_new lua_setglobal(engine->lua, "_ARGV"); - - // ok return tb_true; } + static tb_size_t xm_engine_get_program_file(xm_engine_t* engine, tb_char_t* path, tb_size_t maxn) { // check tb_assert_and_check_return_val(engine && path && maxn, tb_false); - // done tb_bool_t ok = tb_false; do { @@ -563,16 +567,14 @@ static tb_size_t xm_engine_get_program_file(xm_engine_t* engine, tb_char_t* path lua_pushstring(engine->lua, path); lua_setglobal(engine->lua, "_PROGRAM_FILE"); } - - // ok? return ok; } + static tb_bool_t xm_engine_get_program_directory(xm_engine_t* engine, tb_char_t* path, tb_size_t maxn, tb_char_t const* programfile) { // check tb_assert_and_check_return_val(engine && path && maxn, tb_false); - // done tb_bool_t ok = tb_false; do { @@ -652,12 +654,12 @@ static tb_bool_t xm_engine_get_program_directory(xm_engine_t* engine, tb_char_t* // ok? return ok; } + static tb_bool_t xm_engine_get_project_directory(xm_engine_t* engine, tb_char_t* path, tb_size_t maxn) { // check tb_assert_and_check_return_val(engine && path && maxn, tb_false); - // done tb_bool_t ok = tb_false; do { @@ -688,6 +690,41 @@ static tb_bool_t xm_engine_get_project_directory(xm_engine_t* engine, tb_char_t* // ok? return ok; } + +#if defined(TB_CONFIG_OS_WINDOWS) || defined(SIGINT) +static tb_void_t xm_engine_dump_traceback(lua_State* lua) +{ + // @note it's not safe, but it doesn't matter, we're just trying to get the stack backtrace for debugging + lua_getglobal(lua, "debug"); + lua_getfield(lua, -1, "traceback"); + lua_replace(lua, -2); + lua_pushvalue(lua, 1); + lua_call(lua, 1, 1); + tb_trace_i("%s", lua_tostring(lua, -1)); +} +#endif + +#if defined(TB_CONFIG_OS_WINDOWS) +static BOOL WINAPI xm_engine_signal_handler(DWORD signo) +{ + if (signo == CTRL_C_EVENT && g_lua) + { + xm_engine_dump_traceback(g_lua); + tb_abort(); + } + return TRUE; +} +#elif defined(SIGINT) +static tb_void_t xm_engine_signal_handler(tb_int_t signo) +{ + if (signo == SIGINT && g_lua) + { + xm_engine_dump_traceback(g_lua); + tb_abort(); + } +} +#endif + static tb_void_t xm_engine_init_host(xm_engine_t* engine) { // check @@ -733,6 +770,7 @@ static tb_void_t xm_engine_init_host(xm_engine_t* engine) lua_pushstring(engine->lua, subhost? subhost : "unknown"); lua_setglobal(engine->lua, "_SUBHOST"); } + static tb_void_t xm_engine_init_arch(xm_engine_t* engine) { // check @@ -803,6 +841,7 @@ static tb_void_t xm_engine_init_arch(xm_engine_t* engine) lua_pushstring(engine->lua, subarch); lua_setglobal(engine->lua, "_SUBARCH"); } + static tb_void_t xm_engine_init_features(xm_engine_t* engine) { // check @@ -832,6 +871,21 @@ static tb_void_t xm_engine_init_features(xm_engine_t* engine) lua_setglobal(engine->lua, "_FEATURES"); } +static tb_void_t xm_engine_init_signal(xm_engine_t* engine) +{ + // we enable it to catch the current lua stack in ctrl-c signal handler if XMAKE_PROFILE=stuck + tb_char_t data[64] = {0}; + if (!tb_environment_first("XMAKE_PROFILE", data, sizeof(data)) || tb_strcmp(data, "stuck")) + return ; + + g_lua = engine->lua; +#if defined(TB_CONFIG_OS_WINDOWS) + SetConsoleCtrlHandler(xm_engine_signal_handler, TRUE); +#elif defined(SIGINT) + signal(SIGINT, xm_engine_signal_handler); +#endif +} + /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ @@ -915,6 +969,9 @@ xm_engine_ref_t xm_engine_init(tb_char_t const* name, xm_engine_lni_initalizer_c // init features xm_engine_init_features(engine); + // init signal + xm_engine_init_signal(engine); + // get version tb_version_t const* version = xm_version(); tb_assert_and_check_break(version); diff --git a/xmake/core/base/coroutine.lua b/xmake/core/base/coroutine.lua index 2f1c347a8..43a5d6d8a 100644 --- a/xmake/core/base/coroutine.lua +++ b/xmake/core/base/coroutine.lua @@ -31,8 +31,6 @@ coroutine._resume = coroutine._resume or coroutine.resume -- resume coroutine function coroutine.resume(co, ...) - - -- resume it local ok, results = coroutine._resume(co, ...) if not ok then @@ -47,12 +45,8 @@ function coroutine.resume(co, ...) errors = results:sub(pos + 1) end end - - -- failed return false, errors end - - -- ok return true, results end diff --git a/xmake/core/base/os.lua b/xmake/core/base/os.lua index 18b59f61c..19f22e88f 100644 --- a/xmake/core/base/os.lua +++ b/xmake/core/base/os.lua @@ -268,6 +268,23 @@ function os._deduplicate_pathenv(value) return value end +-- trace process for profile(stuck,trace)? +function os._is_tracing_process() + local is_tracing = os._IS_TRACING_PROCESS + if is_tracing == nil then + local profile = os.getenv("XMAKE_PROFILE") + if profile then + profile = profile:trim() + if profile == "trace" or profile == "stuck" then + is_tracing = true + end + end + is_tracing = is_tracing or false + os._IS_TRACING_PROCESS = is_tracing + end + return is_tracing +end + -- match files or directories -- -- @param pattern the search pattern @@ -749,6 +766,11 @@ function os.execv(program, argv, opt) local proc = process.openv(filename, argv or {}, openopt) if proc ~= nil then + -- trace process + if os._is_tracing_process() then + utils.cprint("%s: ${color.dump.string}%s %s${clear}", proc, filename, argv and os.args(argv) or "") + end + -- wait process local waitok, status = proc:wait(-1) if waitok > 0 then diff --git a/xmake/plugins/show/lists/envs.lua b/xmake/plugins/show/lists/envs.lua index 4092901fa..8e66db1e8 100644 --- a/xmake/plugins/show/lists/envs.lua +++ b/xmake/plugins/show/lists/envs.lua @@ -36,7 +36,7 @@ function main() XMAKE_RAMDIR = {"Set the ramdisk directory.", os.getenv("XMAKE_RAMDIR")}, XMAKE_RCFILES = {"Set the runtime configuration files.", path.joinenv(project.rcfiles())}, XMAKE_TMPDIR = {"Set the temporary directory.", os.tmpdir()}, - XMAKE_PROFILE = {"Start profiler, e.g. perf, trace.", os.getenv("XMAKE_PROFILE")}, + XMAKE_PROFILE = {"Start profiler, e.g. perf, trace, stuck.", os.getenv("XMAKE_PROFILE")}, XMAKE_PKG_CACHEDIR = {"Set the cache directory of packages.", os.getenv("XMAKE_PKG_CACHEDIR")}, XMAKE_PKG_INSTALLDIR = {"Set the install directory of packages.", os.getenv("XMAKE_PACKAGEDIR")}} local width = 24 |
