#include <iostream>
#include <list>

using namespace std;

struct stack_frame {
    const char *funName;
    const char *fileName;
    int line;
    stack_frame(const char* func, const char* file, int ln)
    : funName(func), fileName(file), line(ln) {}
};

thread_local list<stack_frame> *frames = 0;

struct entry_exit {
    bool delFrames;
    entry_exit(const char* func, const char* file, int ln) {
        if (!frames) {
            frames = new list<stack_frame>();
            delFrames = true;
        } else {
            delFrames = false;
        }
        frames->push_back(stack_frame(func, file, ln));
    }
    ~entry_exit() {
        frames->pop_back();
        if (delFrames) {
            delete frames;
            frames = 0;
        }
    }
};

void show_stack() {
    for (list<stack_frame>::const_iterator i = frames->begin() ; i != frames->end() ; ++i) {
        cerr << i->funName << " - " << i->fileName << " (" << i->line << ")" << endl;
    }
}

#define FUNCTION_ENTRY entry_exit _entry_exit_(__func__, __FILE__, __LINE__);

void foo() {
    FUNCTION_ENTRY;
    show_stack();
}
void bar() {
    FUNCTION_ENTRY;
    foo();
}
void baz() {
    FUNCTION_ENTRY;
    bar();
}

int main() {
	baz();
	return 0;
}