How to parse raw stack data in hex (STM32F4)?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 7:25 AM
Hello,
I'd like to ask is there any information about parsing raw stack data?
I always save data from PSP stack when a HardFault happens. Here is an example:
20020200: 00000000 0A461285 00000F7F 00000000 00000000 0812CA7D 0812CA9A 20020210
20020220: <hex> <hex> <hex> <hex> <hex> <hex> <hex> <hex>
etc
As far as I understand it may be helpful to recover the end of the list of functions in the order they were called before a HF happened. Is there any resources about recording information on stack for STM32F4?
- Labels:
-
STM32F4 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 7:55 AM
What you are looking for is stack unwinding. This can be done with a little help of the gcc compiler. See https://github.com/red-rocket-computing/backtrace
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 8:40 AM
Generally speaking you'd need a lot of debug data from the compiler/linker to make a much headway. The stack frame, register usage is not as orthogonal as say DOS x86 code.
ODD addresses in the 0x08000000 range are typically LR pushes to return targets, ie 0x0812CA7D is where in came from. This is usually the easiest way to pull out points of interest if you can't determine why the Hard Fault arrived where it did. Generally far easier to check-point the code with sanity checks and flow telemetry if this is a recurrent fault on the debugger.
For field analysis you're often better to use a pencil and a .MAP file, and a dump of the immediate stack, and instructions, along with the registers.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 8:52 AM
> Is there any resources about recording information on stack for STM32F4?
In your case, PC is 0812CA9A , i.e. the faulting instruction will be at that address or a few addresses before that address (in case of imprecise fault).
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 9:09 AM
Ok and is there any way to recognize ASM instruction codes in a stack frame?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 9:35 AM
Stack is in RAM, but code (instructions) are in Flash, usually. Stack contains data like local variables, saved register values, and exception/return addresses which point to code.
Read PM0214 Programming manual cited by Jan below or a good book on that topic (Joseph Yiu). Try stepping though sample code and watch what happend and how the stack is used.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 9:35 AM
There aren't any instructions on the stack. The stack mostly contains data, with sporadic return addresses, if pushed, and perhaps pointers.
You can pull the faulting PC from the fault stack, and dump the 16-bit works around that.
Stack dump variant looking like this currently
void hard_fault_handler_c(unsigned int * hardfault_args, unsigned int r4, unsigned int r5, unsigned int r6)
{
printf("\n[Hard Fault]\n"); // After Joseph Yiu
printf("r0 = %08X, r1 = %08X, r2 = %08X, r3 = %08X\n",
hardfault_args[0], hardfault_args[1], hardfault_args[2], hardfault_args[3]);
printf("r4 = %08X, r5 = %08X, r6 = %08X, sp = %08X\n",
r4, r5, r6, (unsigned int)&hardfault_args[8]);
printf("r12= %08X, lr = %08X, pc = %08X, psr= %08X\n",
hardfault_args[4], hardfault_args[5], hardfault_args[6], hardfault_args[7]);
if (__CORTEX_M >= 3)
printf("bfar=%08X, cfsr=%08X, hfsr=%08X, dfsr=%08X, afsr=%08X\n",
*((volatile unsigned int *)(0xE000ED38)),
*((volatile unsigned int *)(0xE000ED28)),
*((volatile unsigned int *)(0xE000ED2C)),
*((volatile unsigned int *)(0xE000ED30)),
*((volatile unsigned int *)(0xE000ED3C)) );
extern void *__initial_sp;
{ // Stack Dump
int i = 0;
uint32_t *p = (uint32_t *)&hardfault_args[8];
uint32_t *q = (uint32_t *)&__initial_sp;
while((p < q) && (i < 32))
{
if ((i++ & 7) == 0) putchar('\n');
printf(" %08X", *p++);
}
putchar('\n');
}
{ // Instruction Dump
int i = 8;
uint16_t *p = (uint16_t *)((hardfault_args[6] & ~1) - (i*2)); // PC, 8 opcodes earlier
while(i--)
printf(" %04X", *p++);
printf("[%04X]", *p++);
i = 3;
while(i--)
printf("%04X ", *p++);
putchar('\n');
}
while(1)
{
}
} // sourcer32@gmail.com
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 9:37 AM
Thank you so much for your help
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 9:37 AM
Thank you!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-12-08 9:38 AM
Thank you
