blob: 65a913d5ff1ed328fdd33347b9132d1fb54efee2 [file] [log] [blame]
#include <parlib/arch/arch.h>
#include <parlib/stdio.h>
#include <parlib/assert.h>
#include <parlib/ros_debug.h>
#include <stdarg.h>
#include <stdlib.h>
static void __attribute__((constructor)) parlib_stdio_ctor(void)
{
if (__in_fake_parlib())
return;
/* This isn't ideal, since it might affect some stdout streams where our
* parent tried to do something else. Note that isatty() always returns
* TRUE, due to how we fake tcgetattr(), and that doesn't affect
* whatever our shells are doing to set us up. */
setlinebuf(stdout);
}
static void __attribute__((noreturn)) fatal_backtrace(void)
{
/* This will cause the kernel to print out a backtrace to the console.
* Short of reading /proc/self/maps or other stuff, userspace would have
* a hard time backtracing itself. */
breakpoint();
abort();
}
void _panic(const char *file, int line, const char *fmt, ...)
{
char buf[128];
int ret = 0;
va_list ap;
va_start(ap, fmt);
ret += snprintf(buf + ret, sizeof(buf) - ret,
"[user] panic: PID %d, vcore %d, %s:%d: ",
getpid(), vcore_id(), file, line);
/* ignore errors (ret < 0) by setting ret to be at least 0 */
ret = MAX(ret, 0);
ret += vsnprintf(buf + ret, sizeof(buf) - ret, fmt, ap);
ret = MAX(ret, 0);
ret += snprintf(buf + ret, sizeof(buf) - ret, "\n");
ret = MAX(ret, 0);
write(2, buf, ret);
fatal_backtrace();
}
void _assert_failed(const char *file, int line, const char *msg)
{
fprintf(stderr, "[user] %s:%d, vcore %d, Assertion failed: %s\n", file,
line, vcore_id(), msg);
fatal_backtrace();
}