blob: e1b3b07d1b41a15261c9a9c7ef82be50db43e963 [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>
Brian4a424a22014-04-02 11:52:45 -070010#include <stdint.h>
brians343bc112013-02-10 01:53:46 +000011
12#include <string>
13
brians343bc112013-02-10 01:53:46 +000014namespace aos {
15
16void Die(const char *format, ...) {
17 va_list args;
18 va_start(args, format);
19 VDie(format, args);
Brian Silverman5b61e462013-03-16 16:47:23 -070020 // va_end(args) // not because VDie never returns
brians343bc112013-02-10 01:53:46 +000021}
22
23namespace {
Brian Silverman8d2e56e2013-09-23 17:55:03 -070024
brians343bc112013-02-10 01:53:46 +000025// Calculates the filename to dump the message into.
26const std::string GetFilename() {
27#ifdef __VXWORKS__
28 const char *name = taskName(0); // get the name of this task
29 if (name == NULL) name = "<unknown>";
30 const std::string first_part = "/aos_fatal_error.";
31 return first_part + std::string(name);
32#else
33 char *filename;
34 if (asprintf(&filename, "/tmp/aos_fatal_error.%jd",
35 static_cast<intmax_t>(getpid())) > 0) {
36 std::string r(filename);
37 free(filename);
38 return r;
39 } else {
40 fprintf(stderr, "aos fatal: asprintf(%p, \"thingie with %%jd\", %jd)"
Brian Silverman01be0002014-05-10 15:44:38 -070041 " failed with %d\n", &filename,
42 static_cast<intmax_t>(getpid()), errno);
brians343bc112013-02-10 01:53:46 +000043 return std::string();
44 }
45#endif
46}
Brian Silverman8d2e56e2013-09-23 17:55:03 -070047
48bool test_mode = false;
49
brians343bc112013-02-10 01:53:46 +000050} // namespace
brians6ed722d2013-02-12 03:19:55 +000051
brians343bc112013-02-10 01:53:46 +000052void VDie(const char *format, va_list args_in) {
Brian Silverman5b61e462013-03-16 16:47:23 -070053 // We don't bother va_ending either of these because we're going nowhere and
54 // vxworks has some weird bugs that sometimes show up...
55 va_list args1, args2;
brians343bc112013-02-10 01:53:46 +000056
57 fputs("aos fatal: ERROR!! details following\n", stderr);
Brian Silverman5b61e462013-03-16 16:47:23 -070058 va_copy(args1, args_in);
59 vfprintf(stderr, format, args1);
Brian Silverman8d2e56e2013-09-23 17:55:03 -070060 if (!test_mode) {
61 fputs("aos fatal: ERROR!! see stderr for details\n", stdout);
brians343bc112013-02-10 01:53:46 +000062
Brian Silverman8d2e56e2013-09-23 17:55:03 -070063 const std::string filename = GetFilename();
64 if (!filename.empty()) {
65 FILE *error_file = fopen(filename.c_str(), "w");
66 if (error_file != NULL) {
67 va_copy(args2, args_in);
68 vfprintf(error_file, format, args2);
69 fclose(error_file);
70 } else {
Brian Silverman01be0002014-05-10 15:44:38 -070071 fprintf(stderr, "aos fatal: fopen('%s', \"w\") failed with %d\n",
72 filename.c_str(), errno);
Brian Silverman8d2e56e2013-09-23 17:55:03 -070073 }
brians343bc112013-02-10 01:53:46 +000074 }
75 }
76
brians343bc112013-02-10 01:53:46 +000077 abort();
78}
79
Brian Silverman8d2e56e2013-09-23 17:55:03 -070080void SetDieTestMode(bool new_test_mode) {
81 test_mode = new_test_mode;
82}
83
brians343bc112013-02-10 01:53:46 +000084} // namespace aos