NAME

pthread_stackinfo - thread stack information

SYNOPSIS

#include <pthread.h>

int pthreadStackFill;
int pthread_stackinfo( pthread_t tid, stackinfo_t *info);
typedef struct {
void * si_current; /* current stack pointer */
void * si_base; /* stack base */
size_t si_size; /* stack size */
size_t si_used; /* high water mark. */
} stackinfo_t;

DESCRIPTION

pthread_stackinfo() returns the stack information for the thread tid in the pointer info.

The stackinfo_t fields contain the following values:
    si_current is the current value of the stack pointer.
    si_base is the address returned from the kalloc() call used to allocate the stack.
    si_size is the size of the stack. Usually the size argument to the kalloc() call.
    si_used is only valid if the global variable pthreadStackFill was non-zero when the stack was allocated. If pthreadStackFill was non-zero, then si_used gives the high water mark for stack usage.

RETURN VALUES

pthread_stackinfo() returns 0 on success, and an error number if it failed.

ERRORS

ESRCH
tid is not a valid thread.
ENOSPC
The stack has overflowed.

EXAMPLE

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

SEE ALSO

checkIstack()

NOTES

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.

Home page (Kernel)


< Copyright Rowebots Research Inc. and Multiprocessor Toolsmiths Inc. 1987-2018 >