blob: 7cd276dce0b2b8df5222ef79ede2844885ecf7fe [file] [log] [blame] [edit]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BACKTRACE_REQUEST_BACKTRACE_REQUEST_H_
#define BACKTRACE_REQUEST_BACKTRACE_REQUEST_H_
#include <stdint.h>
// Special value we put in the first register to let the exception handler know
// that we are just requesting a backtrace and we should resume the thread.
#define BACKTRACE_REQUEST_MAGIC ((uint64_t)0xee726573756d65ee)
// Prints a backtrace, resuming the thread without killing the process.
__attribute__((always_inline)) static inline void backtrace_request(void) {
// Two instructions: one that sets a software breakpoint ("int3" on x64,
// "brk" on arm64) and one that writes the "magic" value in the first
// register ("a" on x64, "x0" on arm64).
//
// We set a software breakpoint to trigger the exception handling in
// crashsvc, which will print the debug info, including the backtrace.
//
// We write the "magic" value in the first register so that the exception
// handler can check for it and resume the thread if present.
#ifdef __x86_64__
__asm__("int3" : : "a"(BACKTRACE_REQUEST_MAGIC));
#endif
#ifdef __aarch64__
// This is what gdb uses.
__asm__(
"mov x0, %0\n"
"\tbrk 0"
:
: "r"(BACKTRACE_REQUEST_MAGIC)
: "x0");
#endif
}
#endif // BACKTRACE_REQUEST_BACKTRACE_REQUEST_H_