blob: ad5f2a881a7cdd9f422fb45bbf95cc1cca48aacb [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#include "aos/die.h"
brians343bc112013-02-10 01:53:46 +00002
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>
Brian Silverman6da04272014-05-18 18:47:48 -070013#include <atomic>
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 {
41 fprintf(stderr, "aos fatal: asprintf(%p, \"thingie with %%jd\", %jd)"
Brian Silverman01be0002014-05-10 15:44:38 -070042 " failed with %d\n", &filename,
43 static_cast<intmax_t>(getpid()), errno);
brians343bc112013-02-10 01:53:46 +000044 return std::string();
45 }
46#endif
47}
Brian Silverman8d2e56e2013-09-23 17:55:03 -070048
Brian Silverman6da04272014-05-18 18:47:48 -070049::std::atomic_bool test_mode(false);
Brian Silverman8d2e56e2013-09-23 17:55:03 -070050
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 Silverman6da04272014-05-18 18:47:48 -070061 if (!test_mode.load()) {
Brian Silverman8d2e56e2013-09-23 17:55:03 -070062 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 {
Brian Silverman01be0002014-05-10 15:44:38 -070072 fprintf(stderr, "aos fatal: fopen('%s', \"w\") failed with %d\n",
73 filename.c_str(), errno);
Brian Silverman8d2e56e2013-09-23 17:55:03 -070074 }
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) {
Brian Silverman6da04272014-05-18 18:47:48 -070082 test_mode.store(new_test_mode);
Brian Silverman8d2e56e2013-09-23 17:55:03 -070083}
84
brians343bc112013-02-10 01:53:46 +000085} // namespace aos