Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I retrieve a stack trace of the currently running function's stack?

For troubleshooting reason, I would like to be able to retreive and print the caller stack of the currently running function. I have tried the following:

/*******************************************************************************
 * *
 * * xxxTracePrint - stack trace print function
 * *
 * * RETURNS: OK or ERROR
 * */

static void xxxTracePrint
    (
         INSTR *caller,
             int func,
                 int nargs,
                     int *args
                         )
{
    char buf [250];
    int ix;
    int len = 0;

    len += sprintf (&buf [len], "%#10x: %#10x (", (int)caller, func);
    for (ix = 0; ix < nargs; ix++) {
        if (ix != 0)
            len += sprintf (&buf [len], ", ");
        len += sprintf (&buf [len], "%#x", args [ix]);
    }

    len += sprintf (&buf [len], ")\n");

    printf (buf);
}

/*******************************************************************************
 * *
 * * xxxTrace - stack trace
 * *
 * * RETURNS: OK or ERROR
 * */

int xxxTrace(int tcb)
{
    REG_SET regs;

    if (tcb == 0)
        return (ERROR);

    taskRegsGet (tcb, &regs);
    trcStack (&regs, (FUNCPTR) xxxTracePrint, tcb);

    return (OK);
}

void DbgTest(void)
{
    xxxTrace(taskIdSelf());
}

but I get:

JPAX-DP> DbgTest
trcStack aborted: error in top frame
value = 0 = 0x0

Is this even possible? How can I do this? I saw, for taskRegsGet(), they say:

This routine only works well if the task is known to be in a stable, non-executing state. Self-examination, for instance, is not advisable, as results are unpredictable.

But what other method should I apply?

The compiler is diab and cpu arch powerpc

like image 350
stdcerr Avatar asked Oct 29 '22 05:10

stdcerr


2 Answers

You mentioned that taskRegsGet() mentions that it is not advisable to call from a currently running task. However I have seen someone using taskDelay(1) with the comment 'force context save'. I cannot take credit for it, nor do I know how reliable it is, or what side-effects it may have, but it might help to get correct information about the current task:

taskDelay (1);     /* Force context save */
taskRegsGet (0, &regs);   /* 0 task-id for myself */
trcStack (&regs, NULL, 0); /* NULL function pointer for default print fcn, 0 task-id for myself */
like image 163
jHops Avatar answered Nov 14 '22 01:11

jHops


If your compiler is GCC and the calling conventions of your architecture permit it (x86 being the first that comes to mind), I'd recommend using __builtin_return_address( unsigned int level ). More info can be found here: https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html.

like image 34
vxWizard Avatar answered Nov 14 '22 02:11

vxWizard