Can anyone tell me what this is?

I’ve been chasing pxCurrentTCB corruption in my target in another thread but while running waiting for my application to fault or hit one of my asserts, this SIGTRAP breakpoint occured and the target kept on running??? I hit the ‘c’ continue just to see what it would do and my application kept on working and delivering automotive CAN data…

Somewhat confused…

Thread 2 hit Breakpoint 1, main () at /home/miller/src/vip-rcip/vip/src/main.cpp:891
891	    polaris::log::Logger &vdlog = *polaris::log::Logger::getLogger();
(gdb) c
Continuing.

Thread 2 received signal SIGTRAP, Trace/breakpoint trap.
0xdeadbeee in ?? ()
(gdb) info threads
  Id   Target Id         Frame 
* 2    Thread 57005      0xdeadbeee in ?? ()
(gdb) c
Continuing.

This happend after about 30 minutes into execution and loading up the CAN data.

So you are saying that the application receives SIGTRAP because of jumping to an invalid address and then continues to work. What does the SIGTRAP handler do? Does it force the code to return to a valid location or does it cause reset?

what platform?

0xdeadbeef is a custom signature frequently used to mark memory invalid for whatever operation it is used for. A toggled lsb in that location may indicate a corrupted handler mode stack on some mcus.

The platform is an STM32H573 ARM M33 processor

The only place where is set memory to 0xdeadbeef is a single marker variable that I used to help determine that my FreeRTOS pxCurrentTCB pointer is not being modified through a large errant memory corruption…

portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB_pre = (TCB_t *) 0xdeadbeef;

portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL;

portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB_post = (TCB_t *) 0xac987654;

If I align the SIGTRAP with the breakpoint ISR, the ST HAL points it to an empty handler that will just return.

/**
  * @brief This function handles Debug monitor.
  */
void DebugMon_Handler(void)
{
  /* USER CODE BEGIN DebugMonitor_IRQn 0 */

  /* USER CODE END DebugMonitor_IRQn 0 */
  /* USER CODE BEGIN DebugMonitor_IRQn 1 */

  /* USER CODE END DebugMonitor_IRQn 1 */
}

I’ve never set it up to do anything special so I expect the GDB target server is somehow plugging itself into the exception… Why I’m suddenly getting a breakpoint exception that is not registered (and handled by GDB) is the mystery… I’ve seen it twice now in several hours of waiting for my other faults to occur.

as I am sure you know, the variables are not necessarily ordered as you declared them. Have you checked with the map file that the order is preserved?

It might be a good idea to replace these empty handlers with infinite loops so that you can use debugger to analyze when the fault happens.

Yes I do know and yes I got it wrong… By initializing the _pre and _post pxCurrentTCB variables I moved them to the .data segment when the compiler knows that when a variable is initialized to 0 (or NULL) it was placed in the .bss.

I’ve changed the initialization of the pxCurrentTCB to 1 in place of NULL (actually surprised that FreeRTOS initialization did not get upset about it).

 .data.pxCurrentTCB_pre
                0x0000000020000480        0x4 ../debug/libFreeRTOS.a(tasks.c.obj)
                0x0000000020000480                pxCurrentTCB_pre
 .data.pxCurrentTCB
                0x0000000020000484        0x4 ../debug/libFreeRTOS.a(tasks.c.obj)
                0x0000000020000484                pxCurrentTCB
 .data.pxCurrentTCB_post
                0x0000000020000488        0x4 ../debug/libFreeRTOS.a(tasks.c.obj)
                0x0000000020000488                pxCurrentTCB_post

Thank you for this correction!

Little better way to force the pxCurrentTCB into the .data segment with my bookend variables.

portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB_pre = (TCB_t *) 0xdeadbeef;

portDONT_DISCARD __attribute__((section(".data"))) PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; //NULL;

portDONT_DISCARD PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB_post = (TCB_t *) 0xac987654;

Initializing it to a non-NULL value required other changes that were getting pretty sloppy as FreeRTOS expects it initialized to NUILL.

do you still see the 0xdeadbeee sig in the trap handler after the modification? When you dump the post variable, does it contain the expected value?

You can initialize the other 2 to NULL as that should be enough to catch the memory corruption you’re trying to catch.