Smarttrap
Contents |
Smarttrap Utility
About
During software development it is possible for a software developer to download an application with a coding error severe enough to cause an application to crash. Common causes of a system crash are: task stack overflow, indexing an array out of bounds and bad pointer assignments. When a system crash occurs a device will usually recover by a reboot of the system. The purpose of the SmartTrap utility is to provide more information about the system when the crash occurred to assist with debugging the problem.
To enable the SmartTrap feature your application must include smarttrap.h and call the EnableSmartTraps() function. SmartTraps is used in conjunction with the MTTTY serial terminal program. The SmartTraps information will be displayed on the debug serial port, which is UART0 by default.
SmartTraps is commonly used for:
- Debugging an application crash
- Finding functions that are taking a significant amount of time to perform
Warning: The SmartTrap utility cannot be run at the same time as the network debugger. A simple way to automatically handle this situation is to use the _DEBUG definition used by the compiler as shown below.
In the #include section of the application:
// Disable SmartTraps when in debug mode #ifdef _DEBUG #include <NetworkDebug.h> #else #include <smarttrap.h> #endif
In UserMain():
#ifndef _DEBUG EnableSmartTraps(); #endif
Example Application
This example program will demonstrate the SmartTraps utility. The code will call 4 different functions in order to illustrate the display of the call stack for each task. The functions are declared as "volatile" because in this simple example the compiler optimization would optimize out functions 1, 2, and 3.
#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <startnet.h>
#include <autoupdate.h>
#include <dhcpclient.h>
#include <smarttrap.h>
extern "C" {
void UserMain(void * pd);
}
const char * AppName = "Smarttrap Example";
volatile int func4(int i) {
int rv = *(int *) i; // Read from the address of 'i', 0 in this case
return rv;
}
volatile int func3(int i) // func3 calls func4
{
iprintf("Executing func3\r\n");
int rv = func4(i);
return rv;
}
volatile int func2(int i) // func2 calls func3
{
iprintf("Executing func2\r\n");
int rv = func3(i);
return rv;
}
volatile int func1(int i) // func1 calls func2
{
iprintf("Executing func1\r\n");
int rv = func2(i);
return rv;
}
void UserMain(void * pd) {
InitializeStack();
if (EthernetIP == 0)
GetDHCPAddress();
OSChangePrio(MAIN_PRIO);
EnableAutoUpdate();
#ifndef _DEBUG
EnableSmartTraps();
#endif
iprintf("Hit any key to crash\r\n");
getchar();
iprintf("Application started\n");
while (1) {
iprintf("Before crash\r\n");
int i = 0;
int q = func1(i);
iprintf("func1 = %d\r\n", q);
OSTimeDly(TICKS_PER_SECOND);
}
}
Running The Example
The example in the previous section was compiled and downloaded into a NetBurner device, and MTTTY is connected to UART0. The MTTTY screen shot below was generated once a key was pressed and the trap occurred.
The SmartTraps information has four sections. It is beyond the scope of this document to go into detail on each of the processor registers; please see the Freescale Users Manual for your particular processor for more information. They are located in the \nburn\docs directory of your development tools installation.
Trap Information This section displays the processor status and error registers. The most significant is the “Faulted PC”, with is the Program Counter register indicating the area where the fault occurred. In this example the program counter value at the time a trap was detected is 0x02000152.
Register Information This section displays the processor’s Address and Data registers.
RTOS Information Identifies the RTOS Task Control Block and the current running task. The priority number is in hexadecimal. Traps caused by stack overflows may corrupt this section of the report.
Task Information This is a very useful section of the report. It identifies each task, as well as its current state, wait time, and call stack. If you look at the Main task, you can see 6 entries with 0x02000152 (the faulted pc) at the left, and 0 at the right. The value of 0 is the start of the call stack. Each hexadecimal address between those two numbers represents each function that was called.
Each address can be related to the corresponding line number in the source code by using the WinAddr2Line utility. By selecting the .elf file location and each address in the call stack you can determine the calling sequence starting from 0 on the right and moving to the left.
The last line signifies the end of the SmartTrap output. Since the boot monitor is configured to “boot to application”, the device reboots after the trap occurs.
