blob: 0ea7007511e134257836aa18edc06978ca33d5cc [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>
Brian Silverman8d2e56e2013-09-23 17:55:03 -07009#include <signal.h>
brians343bc112013-02-10 01:53:46 +000010
11#include <string>
12
13#include "aos/aos_stdint.h"
14
15namespace aos {
16
17void Die(const char *format, ...) {
18 va_list args;
19 va_start(args, format);
20 VDie(format, args);
Brian Silverman5b61e462013-03-16 16:47:23 -070021 // va_end(args) // not because VDie never returns
brians343bc112013-02-10 01:53:46 +000022}
23
24namespace {
Brian Silverman8d2e56e2013-09-23 17:55:03 -070025
brians343bc112013-02-10 01:53:46 +000026// Calculates the filename to dump the message into.
27const std::string GetFilename() {
28#ifdef __VXWORKS__
29 const char *name = taskName(0); // get the name of this task
30 if (name == NULL) name = "<unknown>";
31 const std::string first_part = "/aos_fatal_error.";
32 return first_part + std::string(name);
33#else
34 char *filename;
35 if (asprintf(&filename, "/tmp/aos_fatal_error.%jd",
36 static_cast<intmax_t>(getpid())) > 0) {
37 std::string r(filename);
38 free(filename);
39 return r;
40 } else {
41 fprintf(stderr, "aos fatal: asprintf(%p, \"thingie with %%jd\", %jd)"
42 " failed with %d (%s)\n", &filename,
43 static_cast<intmax_t>(getpid()), errno, strerror(errno));
44 return std::string();
45 }
46#endif
47}
Brian Silverman8d2e56e2013-09-23 17:55:03 -070048
49bool test_mode = false;
50
brians343bc112013-02-10 01:53:46 +000051} // namespace
brians6ed722d2013-02-12 03:19:55 +000052
brians343bc112013-02-10 01:53:46 +000053void VDie(const char *format, va_list args_in) {
Brian Silverman5b61e462013-03-16 16:47:23 -070054 // We don't bother va_ending either of these because we're going nowhere and
55 // vxworks has some weird bugs that sometimes show up...
56 va_list args1, args2;
brians343bc112013-02-10 01:53:46 +000057
58 fputs("aos fatal: ERROR!! details following\n", stderr);
Brian Silverman5b61e462013-03-16 16:47:23 -070059 va_copy(args1, args_in);
60 vfprintf(stderr, format, args1);
Brian Silverman8d2e56e2013-09-23 17:55:03 -070061 if (!test_mode) {
62 fputs("aos fatal: ERROR!! see stderr for details\n", stdout);
brians343bc112013-02-10 01:53:46 +000063
Brian Silverman8d2e56e2013-09-23 17:55:03 -070064 const std::string filename = GetFilename();
65 if (!filename.empty()) {
66 FILE *error_file = fopen(filename.c_str(), "w");
67 if (error_file != NULL) {
68 va_copy(args2, args_in);
69 vfprintf(error_file, format, args2);
70 fclose(error_file);
71 } else {
72 fprintf(stderr, "aos fatal: fopen('%s', \"w\") failed with %d (%s)\n",
73 filename.c_str(), errno, strerror(errno));
74 }
brians343bc112013-02-10 01:53:46 +000075 }
76 }
77
brians343bc112013-02-10 01:53:46 +000078 abort();
79}
80
Brian Silverman8d2e56e2013-09-23 17:55:03 -070081void SetDieTestMode(bool new_test_mode) {
82 test_mode = new_test_mode;
83}
84
brians343bc112013-02-10 01:53:46 +000085} // namespace aos