blob: d1d3d408a49364707949dff3cb8b5c8eb1846b7b [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/die.h"
brians343bc112013-02-10 01:53:46 +00002
brians343bc112013-02-10 01:53:46 +00003#include <sys/types.h>
4#include <unistd.h>
brians343bc112013-02-10 01:53:46 +00005
Brian Silverman6da04272014-05-18 18:47:48 -07006#include <atomic>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07007#include <cerrno>
8#include <csignal>
9#include <cstdint>
10#include <cstdio>
11#include <cstdlib>
12#include <cstring>
13#include <string>
brians343bc112013-02-10 01:53:46 +000014
brians343bc112013-02-10 01:53:46 +000015namespace 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 {
Tyler Chatowbf0609c2021-07-31 16:13:27 -070041 fprintf(stderr,
42 "aos fatal: asprintf(%p, \"thingie with %%jd\", %jd)"
43 " failed with %d\n",
44 &filename, static_cast<intmax_t>(getpid()), errno);
brians343bc112013-02-10 01:53:46 +000045 return std::string();
46 }
47#endif
48}
Brian Silverman8d2e56e2013-09-23 17:55:03 -070049
Brian Silverman6da04272014-05-18 18:47:48 -070050::std::atomic_bool test_mode(false);
Brian Silverman8d2e56e2013-09-23 17:55:03 -070051
brians343bc112013-02-10 01:53:46 +000052} // namespace
brians6ed722d2013-02-12 03:19:55 +000053
brians343bc112013-02-10 01:53:46 +000054void VDie(const char *format, va_list args_in) {
Brian Silverman5b61e462013-03-16 16:47:23 -070055 // We don't bother va_ending either of these because we're going nowhere and
56 // vxworks has some weird bugs that sometimes show up...
57 va_list args1, args2;
brians343bc112013-02-10 01:53:46 +000058
59 fputs("aos fatal: ERROR!! details following\n", stderr);
Brian Silverman5b61e462013-03-16 16:47:23 -070060 va_copy(args1, args_in);
61 vfprintf(stderr, format, args1);
Brian Silverman6da04272014-05-18 18:47:48 -070062 if (!test_mode.load()) {
Brian Silverman8d2e56e2013-09-23 17:55:03 -070063 fputs("aos fatal: ERROR!! see stderr for details\n", stdout);
brians343bc112013-02-10 01:53:46 +000064
Brian Silverman8d2e56e2013-09-23 17:55:03 -070065 const std::string filename = GetFilename();
66 if (!filename.empty()) {
67 FILE *error_file = fopen(filename.c_str(), "w");
68 if (error_file != NULL) {
69 va_copy(args2, args_in);
70 vfprintf(error_file, format, args2);
71 fclose(error_file);
72 } else {
Brian Silverman01be0002014-05-10 15:44:38 -070073 fprintf(stderr, "aos fatal: fopen('%s', \"w\") failed with %d\n",
74 filename.c_str(), errno);
Brian Silverman8d2e56e2013-09-23 17:55:03 -070075 }
brians343bc112013-02-10 01:53:46 +000076 }
77 }
78
brians343bc112013-02-10 01:53:46 +000079 abort();
80}
81
Tyler Chatowbf0609c2021-07-31 16:13:27 -070082void SetDieTestMode(bool new_test_mode) { test_mode.store(new_test_mode); }
Brian Silverman8d2e56e2013-09-23 17:55:03 -070083
brians343bc112013-02-10 01:53:46 +000084} // namespace aos