|
Boring .....
#include <stdio.h>
#include <stdlib.h>
int cc = 0;
static void entry ();
static void foo1 ();
static void foo2 ();
static void foo3 ();
static void foo4 ();
static void traceCallStack ();
#define FOOBAR (__name__)\
void __name __ () {\
if (++ cc> = 100)\
{if (cc% 16 == 0) traceCallStack ();}\
else switch (rand ()% 4) {\
case 0: foo1 (); foo2 (); break;\
case 1: foo2 (); foo3 (); break;\
case 2: foo3 (); foo4 (); break;\
case 3: if (! (rand ()% 4)) traceCallStack (); break;\
}}
FOOBAR (foo1);
FOOBAR (foo2);
FOOBAR (foo3);
FOOBAR (foo4);
struct name_rcd_st {
void * func;
const char * name;
int brk;}
name_rcd [] =
{
{entry, "entry", 1},
{foo1, "foo1"},
{foo2, "foo2"},
{foo3, "foo3"},
{foo4, "foo4"},
{traceCallStack, "traceCallStack"},
{NULL, NULL}
};
int name_rcd_compare (const void * lhs, const void * rhs)
{
return (int) ((struct name_rcd_st *) rhs)-> func-(int) ((struct name_rcd_st *) lhs)-> func;
}
void entry ()
{
foo1 ();
}
int main ()
{
qsort (name_rcd, sizeof (name_rcd) / sizeof (name_rcd [0])-1, sizeof (name_rcd [0]), name_rcd_compare);
entry ();
return 0;
}
/ *
----------------------- <-EBP
OLD EBP
-----------------------
RET ADDR
-----------------------
* /
#define CURR_FRAME (r) __asm mov r, ebp
#define NEXT_FRAME (c, r) r = ((void **) c) [0]
#define RET_ADDR (c, r) r = ((void **) c) [1]
void * getFrame (void * curr_frame, void ** next_frame_ret)
{
void * next_frame, * ret_addr;
if (NULL == curr_frame)
{
CURR_FRAME (curr_frame);
}
NEXT_FRAME (curr_frame, next_frame);
RET_ADDR (curr_frame, ret_addr);
* next_frame_ret = next_frame;
return ret_addr;
}
struct name_rcd_st * find_func (void * addr, int * off)
{
struct name_rcd_st * r = name_rcd;
for (; r-> func; ++ r)
{
if (addr> r-> func)
break;
}
if (! r-> func)
return NULL;
* off = (int) addr-(int) r-> func;
return r;
}
void traceCallStack ()
{
struct name_rcd_st * rcd;
void * curr_frame = NULL, * addr_func;
int brk = 0, off = 0;
printf ("\n ..... traceCallStack begin:\n");
while (! brk)
{
addr_func = getFrame (curr_frame,&curr_frame);
rcd = find_func (addr_func,&off);
if (! rcd) break;
brk = rcd-> brk;
printf ("% s +% d\n", rcd-> name, off);
}
printf ("........ traceCallStack end ....\n");
} |
|