|
13 | 13 | #define DEFAULT_LOG_FILE "/var/log/osconfig_nrp.log" |
14 | 14 | #define MSG_STACK_HDR "[ERROR] Stack trace:" EOL_TERMINATOR |
15 | 15 |
|
16 | | -#define OSCONFIG_MAX_FRAMES 32 |
| 16 | +#define OSCONFIG_MAX_FRAMES 10 |
17 | 17 |
|
18 | 18 | static const char* g_logFileName = DEFAULT_LOG_FILE; |
19 | 19 |
|
@@ -84,3 +84,94 @@ void InstallCrashHandler(const char* logFileName) |
84 | 84 | sigaction(SIGFPE, &sa, NULL); |
85 | 85 | sigaction(SIGILL, &sa, NULL); |
86 | 86 | } |
| 87 | + |
| 88 | +static char* LoadEndOfFile(const char* logFileName, OsConfigLogHandle log) |
| 89 | +{ |
| 90 | + const int maxSize = 2048; |
| 91 | + int size = 0; |
| 92 | + long offset = 0; |
| 93 | + FILE* file = NULL; |
| 94 | + char* string = NULL; |
| 95 | + |
| 96 | + if (false == FileExists(logFileName)) |
| 97 | + { |
| 98 | + return string; |
| 99 | + } |
| 100 | + |
| 101 | + if (NULL != (file = fopen(logFileName, "r"))) |
| 102 | + { |
| 103 | + if (LockFile(file, log)) |
| 104 | + { |
| 105 | + fseek(file, 0, SEEK_END); |
| 106 | + size = (int)ftell(file); |
| 107 | + |
| 108 | + if (size > maxSize) |
| 109 | + { |
| 110 | + size = maxSize; |
| 111 | + } |
| 112 | + |
| 113 | + offset = (long)(ftell(file) - size); |
| 114 | + fseek(file, offset, SEEK_SET); |
| 115 | + |
| 116 | + if (NULL != (string = (char*)malloc(size + 1))) |
| 117 | + { |
| 118 | + memset(string, 0, size + 1); |
| 119 | + fread(string, sizeof(char), size, file); |
| 120 | + } |
| 121 | + else |
| 122 | + { |
| 123 | + OsConfigLogError(log, "LoadEndOfFile: unable to allocate memory"); |
| 124 | + } |
| 125 | + |
| 126 | + UnlockFile(file, log); |
| 127 | + } |
| 128 | + |
| 129 | + fclose(file); |
| 130 | + } |
| 131 | + |
| 132 | + OsConfigLogDebug(log, "LoadEndOfFile: '%s' ends in '%s'", logFileName, string); |
| 133 | + |
| 134 | + return string; |
| 135 | +} |
| 136 | + |
| 137 | +static char* GetCrashString(const char* content, const char* marker) |
| 138 | +{ |
| 139 | + char* found = NULL; |
| 140 | + |
| 141 | + if ((NULL == content) || (NULL == marker)) |
| 142 | + { |
| 143 | + return found; |
| 144 | + } |
| 145 | + |
| 146 | + return (found = strstr(content, marker)); |
| 147 | +} |
| 148 | + |
| 149 | +void ParseLogForPreviousCrashIfAny(const char* logFileName, OsConfigLogHandle log) |
| 150 | +{ |
| 151 | + const char* crashDueToMarker = "[ERROR] Crash due to"; |
| 152 | + const char* stackTraceMarker = "[ERROR] Stack trace:\n"; |
| 153 | + char* endOfFile = NULL; |
| 154 | + char* crashStart = NULL; |
| 155 | + char* stackStart = NULL; |
| 156 | + char* endOfLine = NULL; |
| 157 | + |
| 158 | + if (NULL != (endOfFile = LoadEndOfFile(logFileName, log))) |
| 159 | + { |
| 160 | + if (NULL != (crashStart = GetCrashString(endOfFile, crashDueToMarker))) |
| 161 | + { |
| 162 | + // Search for stack trace before mutating crashStart |
| 163 | + stackStart = GetCrashString(endOfFile, stackTraceMarker); |
| 164 | + |
| 165 | + // Null-terminate the crash header line |
| 166 | + if (NULL != (endOfLine = strchr(crashStart, '\n'))) |
| 167 | + { |
| 168 | + endOfLine[0] = 0; |
| 169 | + } |
| 170 | + |
| 171 | + OsConfigLogInfo(log, "### Crash start: '%s'", crashStart); |
| 172 | + OsConfigLogInfo(log, "### Stack start: '%s'", stackStart); |
| 173 | + } |
| 174 | + } |
| 175 | + |
| 176 | + FREE_MEMORY(endOfFile); |
| 177 | +} |
0 commit comments