Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
src: split out async stack corruption detection from inline fn
This is fairly expensive code that unnecessarily bloats the
contents of the inline function.
  • Loading branch information
addaleax committed Dec 26, 2021
commit 853853fc7c5aeae20654b758d3a874ce981ea11f
18 changes: 4 additions & 14 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,25 +168,15 @@ inline void AsyncHooks::push_async_context(double async_id,
inline bool AsyncHooks::pop_async_context(double async_id) {
// In case of an exception then this may have already been reset, if the
// stack was multiple MakeCallback()'s deep.
if (fields_[kStackLength] == 0) return false;
if (UNLIKELY(fields_[kStackLength] == 0)) return false;

// Ask for the async_id to be restored as a check that the stack
// hasn't been corrupted.
// Since async_hooks is experimental, do only perform the check
// when async_hooks is enabled.
if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) {
fprintf(stderr,
"Error: async hook stack has become corrupted ("
"actual: %.f, expected: %.f)\n",
async_id_fields_.GetValue(kExecutionAsyncId),
async_id);
DumpBacktrace(stderr);
fflush(stderr);
if (!env()->abort_on_uncaught_exception())
exit(1);
fprintf(stderr, "\n");
fflush(stderr);
ABORT_NO_BACKTRACE();
if (UNLIKELY(fields_[kCheck] > 0 &&
async_id_fields_[kExecutionAsyncId] != async_id)) {
FailWithCorruptedAsyncStack(async_id);
}

uint32_t offset = fields_[kStackLength] - 1;
Expand Down
15 changes: 15 additions & 0 deletions src/env.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,21 @@ void AsyncHooks::grow_async_ids_stack() {
async_ids_stack_.GetJSArray()).Check();
}

void AsyncHooks::FailWithCorruptedAsyncStack(double expected_async_id) {
fprintf(stderr,
"Error: async hook stack has become corrupted ("
"actual: %.f, expected: %.f)\n",
async_id_fields_.GetValue(kExecutionAsyncId),
expected_async_id);
DumpBacktrace(stderr);
fflush(stderr);
if (!env()->abort_on_uncaught_exception())
exit(1);
fprintf(stderr, "\n");
fflush(stderr);
ABORT_NO_BACKTRACE();
}

void Environment::Exit(int exit_code) {
if (options()->trace_exit) {
HandleScope handle_scope(isolate());
Expand Down
2 changes: 2 additions & 0 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,8 @@ class AsyncHooks : public MemoryRetainer {
friend class Environment; // So we can call the constructor.
explicit AsyncHooks(v8::Isolate* isolate, const SerializeInfo* info);

[[noreturn]] void FailWithCorruptedAsyncStack(double expected_async_id);

// Stores the ids of the current execution context stack.
AliasedFloat64Array async_ids_stack_;
// Attached to a Uint32Array that tracks the number of active hooks for
Expand Down