Skip to content

Commit

Permalink
src: split out async stack corruption detection from inline fn
Browse files Browse the repository at this point in the history
This is fairly expensive code that unnecessarily bloats the
contents of the inline function.

PR-URL: #41331
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
  • Loading branch information
addaleax authored and targos committed Jan 14, 2022
1 parent 250e197 commit 337ebfc
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 14 deletions.
18 changes: 4 additions & 14 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,25 +166,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 @@ -1196,6 +1196,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

0 comments on commit 337ebfc

Please sign in to comment.