summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2019-12-06 00:59:19 +0100
committerRich Trott <rtrott@gmail.com>2019-12-07 21:30:39 -0800
commitd1f4936fab0a57282581da65d82411db96eb4108 (patch)
tree47a6595529f7fef36242074f011c32288fb2275b
parenta2cfb7dd8664c73385758c98966823fb80144d2c (diff)
downloadandroid-node-v8-d1f4936fab0a57282581da65d82411db96eb4108.tar.gz
android-node-v8-d1f4936fab0a57282581da65d82411db96eb4108.tar.bz2
android-node-v8-d1f4936fab0a57282581da65d82411db96eb4108.zip
src: improve checked uv loop close output
Addon developers may run into this when not closing libuv handles inside Workers. Previously, output may have included unhelpful statements such as `uv loop at ... has 0 active handles`, which may sound like everything’s supposed to be fine actually. So, instead of printing the active handle count, print the total handle count and mark active handles individually. Also, fix the test for this to work properly and make sure that parsing finishes properly. PR-URL: https://github.com/nodejs/node/pull/30814 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
-rw-r--r--src/debug_utils.cc13
-rw-r--r--test/abort/test-addon-uv-handle-leak.js25
2 files changed, 24 insertions, 14 deletions
diff --git a/src/debug_utils.cc b/src/debug_utils.cc
index 4e52feb69d..6168d9a968 100644
--- a/src/debug_utils.cc
+++ b/src/debug_utils.cc
@@ -292,19 +292,21 @@ void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream) {
struct Info {
std::unique_ptr<NativeSymbolDebuggingContext> ctx;
FILE* stream;
+ size_t num_handles;
};
- Info info { NativeSymbolDebuggingContext::New(), stream };
+ Info info { NativeSymbolDebuggingContext::New(), stream, 0 };
- fprintf(stream, "uv loop at [%p] has %d active handles\n",
- loop, loop->active_handles);
+ fprintf(stream, "uv loop at [%p] has open handles:\n", loop);
uv_walk(loop, [](uv_handle_t* handle, void* arg) {
Info* info = static_cast<Info*>(arg);
NativeSymbolDebuggingContext* sym_ctx = info->ctx.get();
FILE* stream = info->stream;
+ info->num_handles++;
- fprintf(stream, "[%p] %s\n", handle, uv_handle_type_name(handle->type));
+ fprintf(stream, "[%p] %s%s\n", handle, uv_handle_type_name(handle->type),
+ uv_is_active(handle) ? " (active)" : "");
void* close_cb = reinterpret_cast<void*>(handle->close_cb);
fprintf(stream, "\tClose callback: %p %s\n",
@@ -328,6 +330,9 @@ void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream) {
first_field, sym_ctx->LookupSymbol(first_field).Display().c_str());
}
}, &info);
+
+ fprintf(stream, "uv loop at [%p] has %zu open handles in total\n",
+ loop, info.num_handles);
}
std::vector<std::string> NativeSymbolDebuggingContext::GetLoadedLibraries() {
diff --git a/test/abort/test-addon-uv-handle-leak.js b/test/abort/test-addon-uv-handle-leak.js
index 47751954ab..c9614e1173 100644
--- a/test/abort/test-addon-uv-handle-leak.js
+++ b/test/abort/test-addon-uv-handle-leak.js
@@ -47,8 +47,8 @@ if (process.argv[2] === 'child') {
// Parse output that is formatted like this:
- // uv loop at [0x559b65ed5770] has active handles
- // [0x7f2de0018430] timer
+ // uv loop at [0x559b65ed5770] has open handles:
+ // [0x7f2de0018430] timer (active)
// Close callback: 0x7f2df31de220 CloseCallback(uv_handle_s*) [...]
// Data: 0x7f2df33df140 example_instance [...]
// (First field): 0x7f2df33dedc0 vtable for ExampleOwnerClass [...]
@@ -58,6 +58,7 @@ if (process.argv[2] === 'child') {
// [0x7f2de000b910] timer
// Close callback: 0x7f2df31de220 CloseCallback(uv_handle_s*) [...]
// Data: 0x42
+ // uv loop at [0x559b65ed5770] has 3 open handles in total
function isGlibc() {
try {
@@ -89,15 +90,15 @@ if (process.argv[2] === 'child') {
switch (state) {
case 'initial':
- assert(/^uv loop at \[.+\] has \d+ active handles$/.test(line), line);
+ assert(/^uv loop at \[.+\] has open handles:$/.test(line), line);
state = 'handle-start';
break;
case 'handle-start':
- if (/Assertion .+ failed/.test(line)) {
- state = 'done';
+ if (/^uv loop at \[.+\] has \d+ open handles in total$/.test(line)) {
+ state = 'assertion-failure';
break;
}
- assert(/^\[.+\] timer$/.test(line), line);
+ assert(/^\[.+\] timer( \(active\))?$/.test(line), line);
state = 'close-callback';
break;
case 'close-callback':
@@ -109,15 +110,19 @@ if (process.argv[2] === 'child') {
state = 'maybe-first-field';
break;
case 'maybe-first-field':
- if (/^\(First field\)$/.test(line)) {
+ if (!/^\(First field\)/.test(line)) {
lines.unshift(line);
- state = 'handle-start';
- break;
}
- state = 'maybe-first-field';
+ state = 'handle-start';
+ break;
+ case 'assertion-failure':
+ assert(/Assertion .+ failed/.test(line), line);
+ state = 'done';
break;
case 'done':
break;
}
}
+
+ assert.strictEqual(state, 'done');
}