// g++ -Wall -g -o t ./CheckPrintCall.cxx; ./t; echo '---------'; nm -ACln ./t | grep -E 'main|CheckPrintCall|func' // objdump -d -g ./t # Show disassembly code (-d) and debug info (-g). // ## Show disassembly code (-d) and display the corresponding source filenames // ## and line numbers (-l) (executable should be compiled with '-g' flag!) and // ## demangle symbol names (-C) and display source code (-S). // objdump -CSld ./t | less // kill -usr1 `pgrep '^t$'` #include <iostream> #include <signal.h> #include <stdlib.h> #define CHECK_PRINT_CALL(level) \ { \ void* frame = __builtin_frame_address(level); \ if (!frame) \ { \ cout << "*** BOTTOM OF FRAMES ***" << endl; \ return; \ } \ cout << "LEVEL " << level << " | FRAME " << frame << " | " << \ "RETURN " << __builtin_return_address(level) << endl; \ } __attribute__ ((__noinline__)) void CheckPrintCall() { using std::cout; using std::endl; cout << "*** TOP OF FRAMES ***" << endl; // Don't prepend zero before each number or it will be treated as octal number. CHECK_PRINT_CALL( 0); CHECK_PRINT_CALL( 1); CHECK_PRINT_CALL( 2); CHECK_PRINT_CALL( 3); CHECK_PRINT_CALL( 4); CHECK_PRINT_CALL( 5); CHECK_PRINT_CALL( 6); CHECK_PRINT_CALL( 7); CHECK_PRINT_CALL( 8); CHECK_PRINT_CALL( 9); CHECK_PRINT_CALL(10); CHECK_PRINT_CALL(11); CHECK_PRINT_CALL(12); CHECK_PRINT_CALL(13); CHECK_PRINT_CALL(14); CHECK_PRINT_CALL(15); CHECK_PRINT_CALL(16); CHECK_PRINT_CALL(17); CHECK_PRINT_CALL(18); CHECK_PRINT_CALL(19); CHECK_PRINT_CALL(20); CHECK_PRINT_CALL(21); CHECK_PRINT_CALL(22); CHECK_PRINT_CALL(23); CHECK_PRINT_CALL(24); CHECK_PRINT_CALL(25); CHECK_PRINT_CALL(26); CHECK_PRINT_CALL(27); CHECK_PRINT_CALL(28); CHECK_PRINT_CALL(29); CHECK_PRINT_CALL(30); CHECK_PRINT_CALL(31); // cout << " . ." << endl; // cout << " . ." << endl; // cout << " . ." << endl; cout << "(there could be more frames not printed out)" << endl; } void func5() { CheckPrintCall(); } void func4() { func5(); } void func3() { func4(); } void func2() { func3(); } void func1() { func2(); } void sighand(int signum) { std::cout << "b ++++++++++++" << std::endl; CheckPrintCall(); std::cout << "e ++++++++++++" << std::endl; } int main(int argc, char** argv) { // asm("movl %eax,%ebx"); func1(); signal(SIGUSR1, sighand); getchar(); return 0; }