src: add PrintLibuvHandleInformation debug helper
This function is not only helpful for debugging crashes, but can also be used as an ad-hoc debugging statement. PR-URL: https://github.com/nodejs/node/pull/25905 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
2ed556c11f
commit
46d9573c68
@ -282,20 +282,36 @@ void DumpBacktrace(FILE* fp) {
|
||||
void CheckedUvLoopClose(uv_loop_t* loop) {
|
||||
if (uv_loop_close(loop) == 0) return;
|
||||
|
||||
auto sym_ctx = NativeSymbolDebuggingContext::New();
|
||||
PrintLibuvHandleInformation(loop, stderr);
|
||||
|
||||
fprintf(stderr, "uv loop at [%p] has active handles\n", loop);
|
||||
fflush(stderr);
|
||||
// Finally, abort.
|
||||
CHECK(0 && "uv_loop_close() while having open handles");
|
||||
}
|
||||
|
||||
void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream) {
|
||||
struct Info {
|
||||
std::unique_ptr<NativeSymbolDebuggingContext> ctx;
|
||||
FILE* stream;
|
||||
};
|
||||
|
||||
Info info { NativeSymbolDebuggingContext::New(), stream };
|
||||
|
||||
fprintf(stream, "uv loop at [%p] has %d active handles\n",
|
||||
loop, loop->active_handles);
|
||||
|
||||
uv_walk(loop, [](uv_handle_t* handle, void* arg) {
|
||||
auto sym_ctx = static_cast<NativeSymbolDebuggingContext*>(arg);
|
||||
Info* info = static_cast<Info*>(arg);
|
||||
NativeSymbolDebuggingContext* sym_ctx = info->ctx.get();
|
||||
FILE* stream = info->stream;
|
||||
|
||||
fprintf(stderr, "[%p] %s\n", handle, uv_handle_type_name(handle->type));
|
||||
fprintf(stream, "[%p] %s\n", handle, uv_handle_type_name(handle->type));
|
||||
|
||||
void* close_cb = reinterpret_cast<void*>(handle->close_cb);
|
||||
fprintf(stderr, "\tClose callback: %p %s\n",
|
||||
fprintf(stream, "\tClose callback: %p %s\n",
|
||||
close_cb, sym_ctx->LookupSymbol(close_cb).Display().c_str());
|
||||
|
||||
fprintf(stderr, "\tData: %p %s\n",
|
||||
fprintf(stream, "\tData: %p %s\n",
|
||||
handle->data, sym_ctx->LookupSymbol(handle->data).Display().c_str());
|
||||
|
||||
// We are also interested in the first field of what `handle->data`
|
||||
@ -309,14 +325,10 @@ void CheckedUvLoopClose(uv_loop_t* loop) {
|
||||
first_field = *reinterpret_cast<void**>(handle->data);
|
||||
|
||||
if (first_field != nullptr) {
|
||||
fprintf(stderr, "\t(First field): %p %s\n",
|
||||
fprintf(stream, "\t(First field): %p %s\n",
|
||||
first_field, sym_ctx->LookupSymbol(first_field).Display().c_str());
|
||||
}
|
||||
}, sym_ctx.get());
|
||||
|
||||
fflush(stderr);
|
||||
// Finally, abort.
|
||||
CHECK(0 && "uv_loop_close() while having open handles");
|
||||
}, &info);
|
||||
}
|
||||
|
||||
std::vector<std::string> NativeSymbolDebuggingContext::GetLoadedLibraries() {
|
||||
|
@ -119,6 +119,7 @@ class NativeSymbolDebuggingContext {
|
||||
// about giving information on currently existing handles, if there are any,
|
||||
// but still aborts the process.
|
||||
void CheckedUvLoopClose(uv_loop_t* loop);
|
||||
void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream);
|
||||
|
||||
} // namespace node
|
||||
|
||||
|
@ -89,7 +89,7 @@ if (process.argv[2] === 'child') {
|
||||
|
||||
switch (state) {
|
||||
case 'initial':
|
||||
assert(/^uv loop at \[.+\] has active handles$/.test(line), line);
|
||||
assert(/^uv loop at \[.+\] has \d+ active handles$/.test(line), line);
|
||||
state = 'handle-start';
|
||||
break;
|
||||
case 'handle-start':
|
||||
|
Loading…
x
Reference in New Issue
Block a user