Skip to content

Commit

Permalink
runtime: make sure halt() is not called before abort() message is pri…
Browse files Browse the repository at this point in the history
…nted

Concurrent abort() call will call osv::halt() immediately which may
result in a halting NMI being delivered to the CPU which is in the
middle of printing the abort message. This can lead to silent aborts
with no message on the screen. To make debugging easier, let the first
aborter call osv::halt(), others will just spin and wait for the
leader to halt all CPUs.

Signed-off-by: Tomasz Grabiec <[email protected]>
Signed-off-by: Pekka Enberg <[email protected]>
  • Loading branch information
tgrabiec authored and Pekka Enberg committed Aug 9, 2014
1 parent 0d2aaf6 commit 28c67d8
Showing 1 changed file with 28 additions and 24 deletions.
52 changes: 28 additions & 24 deletions runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -103,39 +103,43 @@ static void print_backtrace(void)
}
}

static bool already_aborted = false;
static std::atomic<bool> aborting { false };

void abort()
{
abort("Aborted\n");
}

void abort(const char *fmt, ...)
{
if (!already_aborted) {
arch::irq_disable();
already_aborted = true;

static char msg[1024];
va_list ap;

va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);

debug_early(msg);
// backtrace requires threads to be available, and also
// ELF s_program to be initialized. Since s_program happens
// later, this check is enough to ensure a minimal fallback
// functionality even early on.
if (elf::get_program() != nullptr) {
print_backtrace();
} else {
debug_early("Halting.\n");
}
bool expected = false;
if (!aborting.compare_exchange_strong(expected, true)) {
do {} while (true);
}

arch::irq_disable();

static char msg[1024];
va_list ap;

va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);

debug_early(msg);
// backtrace requires threads to be available, and also
// ELF s_program to be initialized. Since s_program happens
// later, this check is enough to ensure a minimal fallback
// functionality even early on.
if (elf::get_program() != nullptr) {
print_backtrace();
} else {
debug_early("Halting.\n");
}
#ifndef AARCH64_PORT_STUB
panic::pvpanic::panicked();
panic::pvpanic::panicked();
#endif /* !AARCH64_PORT_STUB */
}

osv::halt();
}

Expand Down

0 comments on commit 28c67d8

Please sign in to comment.