pthread_stackinfo - thread stack information
#include <pthread.h>
pthread_stackinfo() returns the stack information for the thread tid in the pointer info.
The stackinfo_t fields contain the following values:pthread_stackinfo() returns 0 on success, and an error number if it failed.
During the initial startup (typically within setup.c), the control flag to fill the interrupt stack may be set to a non-zero value to enable monitoring. Enabling a flag causes that particular stack area to be filled with a known value ("S" for the threads stacks) when it is created subsequently by the kernel. After the kernel has started and the initial user thread is established a call can be made to pthread_stackinfo() to fill the interrupt stack information in info stucture. Additionally, the RTOS Viewer can be used to visualize either stack fills and is aware of the convention.
#include <sys.h>
/* the inital startup function. */
int main()
{
/*disable all interrupt in interrupt controller */
__disable_irq();
/* 1 - fill the task stack with 'S' during initialization for debugging. */
pthreadStackFill = 1;
/* 2 - fill the isr stack with 'I' during initialization for debugging. */
_isrStackFill = 1;
/* ... the rest of the initialization code ... */
}
After the kernel has been established, any arbitrary thread may then call pthread_stackinfo() to get thread stack information.
/* some arbitarty thread. */
THREAD threadx ()
{
stackinfo_t info;
/* call pthread_stackinfo to get current thread stack information. */
pthread_stackinfo (pthread_self(), &info);
/* print thread stack information. */
xprintf("threadx() stack:\n");
xprintf(" base: 0x%x\n", info.si_base);
xprintf(" current: 0x%x\n", info.si_current);
xprintf(" size: %d\n", info.si_size);
xprintf(" used: %d\n\n", info.si_used);
/* ... other code... */
}
The following result (or similar) will be printed:
threadx() stack: base: 0x2000120C current: 0x20001578 size: 1024 used: 296
The high water mark is not a guarenteed method of checking for stack usage or overflow. Lets look at an example. The user creates a thread with a stack size of 1000 bytes. The following code fragment shows the start of the thread.
THREAD thread(void)
{
char bigbuffer[20000];
int error = 0;
< initialization code >
if(mr_receive(bigbuffer, 1, 0, 0, 0) == 0)
error = RECEIVE_ERROR;
< rest of thread code >
}Note that bigbuffer overflows the stack, but the corruption will not be noticed as long as no messages are sent bigger that 1000 bytes. However, if the mr_receive() call ever fails, error will corrupt memory, but the high water mark is still valid since it will only check the 1000 bytes it knows about.
The pthread_stackinfo() call will report a problem if a large message comes in and overflows the stack.