| #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(); | 
 | } |