Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf_hooks.PerformanceObserver.observe kills node.js 16.0.0 when registering same entryTypes twice #38412

Closed
analytik opened this issue Apr 26, 2021 · 4 comments
Labels
confirmed-bug Issues with confirmed bugs. perf_hooks Issues and PRs related to the implementation of the Performance Timing API.

Comments

@analytik
Copy link

  • Version: v16.0.0
  • Platform: debian x64 in WSL, also Windows 10
  • Subsystem: Envionment (?)

What steps will reproduce the bug?

The easiest way is to clone siimon/prom-client (13.1.0 or current master branch) and run unit tests.

The minimum use case I could find is this code - I don't know or use perf_tools myself, but I can confirm this snippet works in Node.js 14.x

let perf_hooks = require('perf_hooks');
// works
const obs = new perf_hooks.PerformanceObserver(list => { console.log('in observer'); });
// works
obs.observe({ entryTypes: ['gc'], buffered: false });
// works
perf_hooks.performance.measure('gc');

// works
const obs2 = new perf_hooks.PerformanceObserver(list => { console.log('in observer 2'); });
// kills node.js
obs2.observe({ entryTypes: ['gc'], buffered: false });

How often does it reproduce? Is there a required condition?

Every time.

What is the expected behavior?

All prom-client unit tests pass like in node.js 14 or 15.

What do you see instead?

Under Debian:

Welcome to Node.js v16.0.0.
Type ".help" for more information.
> let perf_hooks = require('perf_hooks');
undefined
> // works
undefined
> const obs = new perf_hooks.PerformanceObserver(list => {
...     console.log('in observer');
... });
undefined
> // works
undefined
> obs.observe({ entryTypes: ['gc'], buffered: false });
undefined
> // works
undefined
> perf_hooks.performance.measure('gc');
PerformanceMeasure {
  name: 'gc',
  entryType: 'measure',
  startTime: 0,
  duration: 83245.0522999987,
  detail: undefined
}
> const obs2 = new perf_hooks.PerformanceObserver(list => {
...     console.log('in obin observer
server 2');
... });
undefined
>
> obs2.observe({ entryTypes: ['gc'], buffered: false });
node[1367]: ../src/env-inl.h:1052:void node::Environment::AddCleanupHook(node::Environment::CleanupCallback, void*): Assertion `(insertion_info.second) == (true)' failed.
 1: 0xb12b00 node::Abort() [node]
 2: 0xb12b7e  [node]
 3: 0xb7a58c  [node]
 4: 0xd5f70b  [node]
 5: 0xd60bac  [node]
 6: 0xd61226 v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [node]
 7: 0x160c579  [node]
Aborted

Under Windows:

λ node
Welcome to Node.js v16.0.0.
Type ".help" for more information.
> let perf_hooks = require('perf_hooks');
undefined
> // works
undefined
> const obs = new perf_hooks.PerformanceObserver(list => { console.log('in observer'); });
undefined
> // works
undefined
> obs.observe({ entryTypes: ['gc'], buffered: false });
undefined
> // works
undefined
> perf_hooks.performance.measure('gc');
PerformanceMeasure {
  name: 'gc',
  entryType: 'measure',
  startTime: 0,
  duration: 12642.107500001788,
  detail: undefined
}
>
> // works
undefined
> const obs2 = new perf_hooks.PerformanceObserver(list => { console.log('in observer 2'); });
undefined
> in observer
obs2.observe({ entryTypes: ['gc'], buffered: falsese });
cmd - node[4256]: c:\ws\src\env-inl.h:1052: Assertion `(insertion_info.second) == (true)' failed.
 1: 00007FF798E886BF v8::internal::Isolate::ArchiveSpacePerThread+4719
 2: 00007FF798E1B246 v8::internal::wasm::WasmCode::safepoint_table_offset+67414
 3: 00007FF798E1B5C1 v8::internal::wasm::WasmCode::safepoint_table_offset+68305
 4: 00007FF798DAFFB1 v8::CFunction::ReturnInfo+27953
 5: 00007FF799743969 v8::internal::Builtins::builtin_handle+318073
 6: 00007FF799742F01 v8::internal::Builtins::builtin_handle+315409
 7: 00007FF7997431F1 v8::internal::Builtins::builtin_handle+316161
 8: 00007FF799743033 v8::internal::Builtins::builtin_handle+315715
 9: 00007FF7998198B1 v8::internal::SetupIsolateDelegate::SetupHeap+455217
10: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
11: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
12: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
13: 00007FF7997B1C0F v8::internal::SetupIsolateDelegate::SetupHeap+30095
14: 00007FF7997B180B v8::internal::SetupIsolateDelegate::SetupHeap+29067
15: 00007FF79966A022 v8::internal::Execution::CallWasm+1698
16: 00007FF79966985F v8::internal::Execution::Call+191
17: 00007FF799794CC6 v8::Script::Run+694
18: 00007FF798E268B6 node::OnFatalError+43190
19: 00007FF798E29E46 node::OnFatalError+56902
20: 00007FF799743969 v8::internal::Builtins::builtin_handle+318073
21: 00007FF799742F01 v8::internal::Builtins::builtin_handle+315409
22: 00007FF7997431F1 v8::internal::Builtins::builtin_handle+316161
23: 00007FF799743033 v8::internal::Builtins::builtin_handle+315715
24: 00007FF7998198B1 v8::internal::SetupIsolateDelegate::SetupHeap+455217
25: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
26: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
27: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
28: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
29: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
30: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
31: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
32: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
33: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
34: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
35: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
36: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
37: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
38: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
39: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
40: 00007FF7997E1EA7 v8::internal::SetupIsolateDelegate::SetupHeap+227367
41: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
42: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
43: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
44: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
45: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
46: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
47: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
48: 00007FF7997B39B9 v8::internal::SetupIsolateDelegate::SetupHeap+37689
49: 00007FF7997B1C0F v8::internal::SetupIsolateDelegate::SetupHeap+30095
50: 00007FF7997B180B v8::internal::SetupIsolateDelegate::SetupHeap+29067
51: 00007FF79966A022 v8::internal::Execution::CallWasm+1698
52: 00007FF79966985F v8::internal::Execution::Call+191
53: 00007FF799770EF1 v8::Function::Call+609
54: 00007FF798EB7B8A node::CallbackScope::~CallbackScope+1674
55: 00007FF798EAF714 v8::internal::compiler::Operator::EffectOutputCount+228
56: 00007FF798D39A53 RSA_meth_get_flags+20675
57: 00007FF798D3A5CD RSA_meth_get_flags+23613
58: 00007FF798D34EF9 RSA_meth_get_flags+1385
59: 00007FF798ECD698 uv_udp_set_ttl+5176
60: 00007FF798EE796C uv_loop_init+908
61: 00007FF798EE7C8A uv_run+202
62: 00007FF798EB6F64 node::SpinEventLoop+308
63: 00007FF798DD3F53 v8::internal::UnoptimizedCompilationInfo::feedback_vector_spec+52995
64: 00007FF798E4E387 node::Start+215
65: 00007FF798C7822C RC4_options+346412
66: 00007FF799D3931C v8::internal::compiler::RepresentationChanger::Uint32OverflowOperatorFor+151692
67: 00007FFE484C7034 BaseThreadInitThunk+20
68: 00007FFE48602651 RtlUserThreadStart+33
@targos
Copy link
Member

targos commented Apr 26, 2021

/cc @jasnell

@targos targos added the perf_hooks Issues and PRs related to the implementation of the Performance Timing API. label Apr 26, 2021
@jasnell
Copy link
Member

jasnell commented Apr 26, 2021

PR incoming

jasnell added a commit to jasnell/node that referenced this issue Apr 26, 2021
Signed-off-by: James M Snell <jasnell@gmail.com>
Fixes: nodejs#38412
@jasnell
Copy link
Member

jasnell commented Apr 26, 2021

Fix in #38414 ...

Btw, the PerformanceObserver implementation in 16.0 was updated to match the current version of the spec.

obs.observe({ entryTypes: ['gc'], buffered: false });

Would now be

obs.observe({ type: 'gc' });

And the buffered option is now a non-op

@Linkgoron Linkgoron added the confirmed-bug Issues with confirmed bugs. label Apr 26, 2021
targos pushed a commit that referenced this issue Apr 29, 2021
Signed-off-by: James M Snell <jasnell@gmail.com>
Fixes: #38412

PR-URL: #38414
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Zijian Liu <lxxyxzj@gmail.com>
@sirreal
Copy link

sirreal commented May 14, 2021

Hi @jasnell, do you mind clarifying whether entryTypes is likely to be deprecated or removed?

The v16 documentation still mentions entryTypes. I understand that these are synonymous and either should be valid, where a single type may be provided or a list of entryTypes:

obs.observe({ type: 'gc' });          // Observe a single type
obs.observe({ entryTypes: ['gc'] });  // Observe one or more types

The former is Node >= 16, while the latter is supported by earlier versions. For a library that wants to support multiple versions, it's simpler to use entryTypes.

I looked ad MDN and this spec, both of them mention either types or entryTypes (not both!) are valid observe options.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. perf_hooks Issues and PRs related to the implementation of the Performance Timing API.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants