Identify Runtime Exceptions and Execution Residues
Gain the skills to detect and understand runtime exceptions, trace execution history, and identify handled exceptions.
Runtime exceptions are the exceptions that arise during the runtime, as opposed to the compile time exceptions. An execution residue is symbolic information left in the stack region. For instance, functions that were called in the past, but were not active at the time of core dump generation, will not show up in the stack traces. We can find their traces in the execution residues.
In this lesson, we’ll learn how to identify runtime exceptions, examine execution residues or history, construct stack traces, and identify handled exceptions.
Application source code
We have created a multi-threaded application to determine if a runtime exception is causing the fault.
// Build:// g++ main.cpp -pthread -static -o App8#include <string>#include <unistd.h>#define def_call(name, x, y) void name##_##x() { name##_##y(); }#define def_final(name, x) void name##_##x() {}#define def_init(name, y, size) \void name() { \int arr[size]; \name##_##y(); \*arr = 0; \}def_final(work, 9)def_call(work, 8, 9)def_call(work, 7, 8)def_call(work, 6, 7)def_call(work, 5, 6)def_call(work, 4, 5)def_call(work, 3, 4)def_call(work, 2, 3)def_call(work, 1, 2)def_init(work, 1, 256)class Exception {int code;std::string description;public:Exception(int _code, std::string _desc) : code(_code), description(_desc) {}};void procB(){throw new Exception(5, "Access Denied");}void procNB(){work();}void procA(){procB();}void procNA(){procNB();}void procH(){try {procA();} catch (...) {sleep(-1);}}void procNH(){sleep(10);procA();}void procNE(){try {procNA();} catch (...) {}sleep(-1);}#define THREAD_DECLARE(num, func) \void bar_##num() \{ \func; \} \\void foo_##num() \{ \bar_##num(); \} \\void *thread_##num(void *arg) \{ \foo_##num(); \return 0; \}THREAD_DECLARE(one, procNH())THREAD_DECLARE(two, procNE())THREAD_DECLARE(three, procH())THREAD_DECLARE(four, procNE())THREAD_DECLARE(five, procNE())#define THREAD_CREATE(num) \{ \pthread_t threadID_##num; \pthread_create(&threadID_##num, NULL, thread_##num, NULL); \}int main(int argc, const char *argv[]){THREAD_CREATE(one)THREAD_CREATE(two)THREAD_CREATE(three)THREAD_CREATE(four)THREAD_CREATE(five)sleep(-1);return 0;}
The work
functions
In addition to other structures, this program generates the following work
functions that we’ll see later on in this lesson: