5

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

stdcerr
  • 9,675
  • 15
  • 50
  • 95

2 Answers2

1

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.

vxWizard
  • 501
  • 2
  • 3
  • Unfortunately, I'm on powerPC and diab compiler – stdcerr Jun 29 '17 at 01:06
  • While much more heavy handed and requiring an iterative process you can write some inlined assembly to move the link registers content into a C variable that you can print. The main downside to this approach besides having the use the poorly document inline assembly syntax diab supports is that you can only find the current function's caller. To get the next call you have to modify the calling function to get the link registers contents. I've used this in ARM and PPC cards, but it's a technique of last resort. – vxWizard Jun 29 '17 at 14:12
  • Are you able to do "tt" on task? tt on vxWorks shell. Also try setting the below options for task and see if it helps "taskOptionsSet , 2, 0". – Vikash Jain Aug 05 '17 at 12:39
1

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 */
jHops
  • 183
  • 1
  • 2
  • 11