John Park | 33858a3 | 2018-09-28 23:05:48 -0700 | [diff] [blame^] | 1 | #include "aos/die.h" |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 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 Silverman | 8d2e56e | 2013-09-23 17:55:03 -0700 | [diff] [blame] | 9 | #include <signal.h> |
Brian | 4a424a2 | 2014-04-02 11:52:45 -0700 | [diff] [blame] | 10 | #include <stdint.h> |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 11 | |
| 12 | #include <string> |
Brian Silverman | 6da0427 | 2014-05-18 18:47:48 -0700 | [diff] [blame] | 13 | #include <atomic> |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 14 | |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 15 | namespace aos { |
| 16 | |
| 17 | void Die(const char *format, ...) { |
| 18 | va_list args; |
| 19 | va_start(args, format); |
| 20 | VDie(format, args); |
Brian Silverman | 5b61e46 | 2013-03-16 16:47:23 -0700 | [diff] [blame] | 21 | // va_end(args) // not because VDie never returns |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 22 | } |
| 23 | |
| 24 | namespace { |
Brian Silverman | 8d2e56e | 2013-09-23 17:55:03 -0700 | [diff] [blame] | 25 | |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 26 | // Calculates the filename to dump the message into. |
| 27 | const 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 Silverman | 01be000 | 2014-05-10 15:44:38 -0700 | [diff] [blame] | 42 | " failed with %d\n", &filename, |
| 43 | static_cast<intmax_t>(getpid()), errno); |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 44 | return std::string(); |
| 45 | } |
| 46 | #endif |
| 47 | } |
Brian Silverman | 8d2e56e | 2013-09-23 17:55:03 -0700 | [diff] [blame] | 48 | |
Brian Silverman | 6da0427 | 2014-05-18 18:47:48 -0700 | [diff] [blame] | 49 | ::std::atomic_bool test_mode(false); |
Brian Silverman | 8d2e56e | 2013-09-23 17:55:03 -0700 | [diff] [blame] | 50 | |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 51 | } // namespace |
brians | 6ed722d | 2013-02-12 03:19:55 +0000 | [diff] [blame] | 52 | |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 53 | void VDie(const char *format, va_list args_in) { |
Brian Silverman | 5b61e46 | 2013-03-16 16:47:23 -0700 | [diff] [blame] | 54 | // 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; |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 57 | |
| 58 | fputs("aos fatal: ERROR!! details following\n", stderr); |
Brian Silverman | 5b61e46 | 2013-03-16 16:47:23 -0700 | [diff] [blame] | 59 | va_copy(args1, args_in); |
| 60 | vfprintf(stderr, format, args1); |
Brian Silverman | 6da0427 | 2014-05-18 18:47:48 -0700 | [diff] [blame] | 61 | if (!test_mode.load()) { |
Brian Silverman | 8d2e56e | 2013-09-23 17:55:03 -0700 | [diff] [blame] | 62 | fputs("aos fatal: ERROR!! see stderr for details\n", stdout); |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 63 | |
Brian Silverman | 8d2e56e | 2013-09-23 17:55:03 -0700 | [diff] [blame] | 64 | 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 Silverman | 01be000 | 2014-05-10 15:44:38 -0700 | [diff] [blame] | 72 | fprintf(stderr, "aos fatal: fopen('%s', \"w\") failed with %d\n", |
| 73 | filename.c_str(), errno); |
Brian Silverman | 8d2e56e | 2013-09-23 17:55:03 -0700 | [diff] [blame] | 74 | } |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 75 | } |
| 76 | } |
| 77 | |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 78 | abort(); |
| 79 | } |
| 80 | |
Brian Silverman | 8d2e56e | 2013-09-23 17:55:03 -0700 | [diff] [blame] | 81 | void SetDieTestMode(bool new_test_mode) { |
Brian Silverman | 6da0427 | 2014-05-18 18:47:48 -0700 | [diff] [blame] | 82 | test_mode.store(new_test_mode); |
Brian Silverman | 8d2e56e | 2013-09-23 17:55:03 -0700 | [diff] [blame] | 83 | } |
| 84 | |
brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame] | 85 | } // namespace aos |