blob: 467b81d5592f437d69c0f6abad3893752f1a4f55 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#include "aos/common/die.h"
2
3#include <stdlib.h>
4#include <stdio.h>
5#include <errno.h>
6#include <sys/types.h>
7#include <unistd.h>
8#include <string.h>
9#ifdef __VXWORKS__
10#include <taskLib.h>
11// Have to re-declare it with __attribute__((noreturn)).
12extern "C" void abort() __attribute__((noreturn));
brians8fcd8752013-03-16 21:30:54 +000013#include <usrLib.h>
14#include <dbgLib.h>
brians343bc112013-02-10 01:53:46 +000015#endif
16
17#include <string>
18
19#include "aos/aos_stdint.h"
20
21namespace aos {
22
23void Die(const char *format, ...) {
24 va_list args;
25 va_start(args, format);
26 VDie(format, args);
Brian Silverman5b61e462013-03-16 16:47:23 -070027 // va_end(args) // not because VDie never returns
brians343bc112013-02-10 01:53:46 +000028}
29
30namespace {
31// Calculates the filename to dump the message into.
32const std::string GetFilename() {
33#ifdef __VXWORKS__
34 const char *name = taskName(0); // get the name of this task
35 if (name == NULL) name = "<unknown>";
36 const std::string first_part = "/aos_fatal_error.";
37 return first_part + std::string(name);
38#else
39 char *filename;
40 if (asprintf(&filename, "/tmp/aos_fatal_error.%jd",
41 static_cast<intmax_t>(getpid())) > 0) {
42 std::string r(filename);
43 free(filename);
44 return r;
45 } else {
46 fprintf(stderr, "aos fatal: asprintf(%p, \"thingie with %%jd\", %jd)"
47 " failed with %d (%s)\n", &filename,
48 static_cast<intmax_t>(getpid()), errno, strerror(errno));
49 return std::string();
50 }
51#endif
52}
53} // namespace
brians6ed722d2013-02-12 03:19:55 +000054
brians343bc112013-02-10 01:53:46 +000055void VDie(const char *format, va_list args_in) {
Brian Silverman5b61e462013-03-16 16:47:23 -070056 // We don't bother va_ending either of these because we're going nowhere and
57 // vxworks has some weird bugs that sometimes show up...
58 va_list args1, args2;
brians343bc112013-02-10 01:53:46 +000059
60 fputs("aos fatal: ERROR!! details following\n", stderr);
Brian Silverman5b61e462013-03-16 16:47:23 -070061 va_copy(args1, args_in);
62 vfprintf(stderr, format, args1);
brians343bc112013-02-10 01:53:46 +000063 fputs("aos fatal: ERROR!! see stderr for details\n", stdout);
64
65 const std::string filename = GetFilename();
66 if (!filename.empty()) {
67 FILE *error_file = fopen(filename.c_str(), "w");
68 if (error_file != NULL) {
Brian Silverman5b61e462013-03-16 16:47:23 -070069 va_copy(args2, args_in);
70 vfprintf(error_file, format, args2);
brians343bc112013-02-10 01:53:46 +000071 fclose(error_file);
72 } else {
73 fprintf(stderr, "aos fatal: fopen('%s', \"w\") failed with %d (%s)\n",
74 filename.c_str(), errno, strerror(errno));
75 }
76 }
77
brians8fcd8752013-03-16 21:30:54 +000078#ifdef __VXWORKS__
79 printf("I am 0x%x suspending for debugging purposes.\n", taskIdSelf());
80 printf("\t`tt 0x%x` will give you a stack trace.\n", taskIdSelf());
81 fputs("\t`lkAddr` will reverse lookup a symbol for you.\n", stdout);
82 fputs("\t`dbgHelp` and `help` have some useful commands in them.\n", stdout);
83 taskSuspend(0);
84 printf("You weren't supposed to resume 0x%x!!. Going to really die now.\n",
85 taskIdSelf());
86#endif
brians343bc112013-02-10 01:53:46 +000087 abort();
88}
89
90} // namespace aos