CrashDump

You can add this source code to your project and it should dump some useful information to the serial port when your program dies:

DumpStack.cpp

/* Copyright 2013 Adam Green (http://mbed.org/users/AdamGreen/)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
/* Implementation of routines to help in debugging. */
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <error.h>
#include <cmsis.h>


/* Determines the number of elements in an array */
#define ARRAY_SIZE(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))


/* Dumps the contents of memory to stdout

   Parameters:
    pvBuffer is a pointer to the memory to be dumped
    BufferSizeInBytes is the length of the memory buffer to be dumped
    ElementSize is the size of each element to be dumped.  Valid values are 1, 2, and 4
    
   Returns:
    Nothing
*/
void DebugDumpMemory(const void* pvBuffer, size_t BufferSizeInBytes, size_t ElementSize)
{
    size_t                  i = 0;
    size_t                  Count = BufferSizeInBytes / ElementSize;
    size_t                  ColumnsPerRow = 0;
    size_t                  ByteIndex = 0;
    const unsigned char*    pBuffer = (const unsigned char*)pvBuffer;
    
    char   ASCIIBuffer[9];
    
    /* Check for alignment */
    if ((size_t)pvBuffer & (ElementSize - 1))
    {
        printf("RIP: DebugDumpMemory() pvBuffer(%08X) isn't properly aligned to ElementSize(%d)\n",
              (size_t)pvBuffer, ElementSize);
        for(;;)
        {
        }
    }
    
    /* Number of elements to dump per line depends on the element size */
    switch(ElementSize)
    {
    case 1:
        ColumnsPerRow = 8;
        break;
    case 2:
        ColumnsPerRow = 16;
        break;
    case 4:
        ColumnsPerRow = 16;
        break;
    default:
        printf("RIP: DebugDumpMemory() ElementSize of %u is invalid\n", ElementSize);
        for(;;)
        {
        }
    }
    
    
    /* Loop through and dump the elements */
    for (i = 0 ; i < Count ; i++)
    {
        if ((ByteIndex % ColumnsPerRow) == 0)
        {
            printf("%08X: ", (unsigned int)pBuffer);
            memset(ASCIIBuffer, ' ', ARRAY_SIZE(ASCIIBuffer)-1);
            ASCIIBuffer[ARRAY_SIZE(ASCIIBuffer)-1] = '\0';
        }

        switch(ElementSize)
        {
        case 1:
            {
                unsigned char   b;

                b = 0xff & (*(const char*)pBuffer);
                printf("0x%02X ", b);
                ASCIIBuffer[ByteIndex % ColumnsPerRow] = (b >= ' ' && b < 0x80) ? b : '.';
            }
            break;
        case 2:
            printf("0x%04X ", 0xffff & (*(const short*)(const void*)pBuffer));
            break;
        case 4:
            printf("0x%08X ", *(const int*)(const void*)pBuffer);
            break;
        }

        ByteIndex += ElementSize;
        pBuffer   += ElementSize;
        if ((ByteIndex % ColumnsPerRow) == 0)
        {
            printf(" %s\n", (1 == ElementSize) ? ASCIIBuffer : "");
        }
    }
    if ((ByteIndex % ColumnsPerRow ) != 0)
    {
        if (1 == ElementSize)
        {
            for ( ; (ByteIndex % ColumnsPerRow) != 0 ; ByteIndex++)
            {
                printf("     ");
            }
            printf(" %s\n", ASCIIBuffer);
        }
        else
        {
            printf("\n");
        }
    }
}


/* Dumps the contents of the stack to stdout */
void DebugDumpStack(void)
{
    uint32_t TopOfStack = *(volatile uint32_t*)0;
    uint32_t BottomOfStack = __current_sp();
    uint32_t StackLength = TopOfStack - BottomOfStack;
    
    DebugDumpMemory((void*)BottomOfStack, StackLength, 4);
}

volatile int __dummyFlag = 1;

extern "C" void mbed_die(void)
{
    printf("mbed_die @ %08X\n", &mbed_die);
    DebugDumpStack();
    while (__dummyFlag);
}

extern "C" void HardFault_Handler(void)
{
    printf("HardFault_Handler @ %08X\n", &HardFault_Handler);
    DebugDumpStack();
    while (__dummyFlag);
}


What I need for debugging the crash:

  1. All of the text sent to the serial port by this code when the crash occurs.
  2. The .bin file that was running on your mbed when the crash occurred.


1 comment on CrashDump:

25 Nov 2014

Socket constructor error: no wifly instance available! mbed_die @ 0001C181

2002FF90: 0x00000001 0x0001B32B 0x1FFF050C 0x000183FB

2002FFA0: 0x00018404 0x00FFFFFF 0x00000200 0x00000010

2002FFB0: 0x00027824 0x00016FAD 0x00027824 0x000192DB

2002FFC0: 0x00000200 0x00000000 0x00000000 0x000276BF

2002FFD0: 0x00000000 0x000015FB 0x1FFF12BC 0x00000000

2002FFE0: 0x00000000 0x00000587 0x1FFF1450 0x20030000

2002FFF0: 0x20030000 0x00000000 0x00000000 0x0000059B

That's what I get from the serial port,what does it mean?

Please log in to post comments.