iPXE
Data Structures | Defines | Functions | Variables
fnrec.c File Reference

Function trace recorder for crash and hang debugging. More...

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ipxe/init.h>
#include <ipxe/uaccess.h>
#include <ipxe/io.h>

Go to the source code of this file.

Data Structures

struct  fnrec_entry
 A trace buffer entry. More...
struct  fnrec_buffer
 A trace buffer. More...

Defines

#define FNREC_MAGIC   ( 'f' << 24 | 'n' << 16 | 'r' << 8 | 'e' )
 Constant for identifying valid trace buffers.
#define FNREC_NUM_ENTRIES   4096
 Number of trace buffer entries.
#define FNREC_PHYS_ADDRESS   ( 17 * 1024 * 1024 )
 Trace buffer physical address.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
static int fnrec_is_valid (void)
 Test whether the trace buffer is valid.
static void fnrec_invalidate (void)
 Invalidate the trace buffer.
static void fnrec_reset (void)
 Reset the trace buffer and clear entries.
static struct fnrec_entryfnrec_append (void *called_fn, void *call_site)
 Append an entry to the trace buffer.
static void fnrec_dump (void)
 Print the contents of the trace buffer in chronological order.
static void fnrec_init (void)
 Function tracer initialisation function.
struct init_fn fnrec_init_fn __init_fn (INIT_NORMAL)
void __cyg_profile_func_enter (void *called_fn, void *call_site)
void __cyg_profile_func_exit (void *called_fn, void *call_site)

Variables

static struct fnrec_bufferfnrec_buffer
 The trace buffer.

Detailed Description

Function trace recorder for crash and hang debugging.

Definition in file fnrec.c.


Define Documentation

#define FNREC_MAGIC   ( 'f' << 24 | 'n' << 16 | 'r' << 8 | 'e' )

Constant for identifying valid trace buffers.

Definition at line 40 of file fnrec.c.

Referenced by fnrec_is_valid(), and fnrec_reset().

#define FNREC_NUM_ENTRIES   4096

Number of trace buffer entries.

Definition at line 43 of file fnrec.c.

Referenced by fnrec_append(), and fnrec_dump().

#define FNREC_PHYS_ADDRESS   ( 17 * 1024 * 1024 )

Trace buffer physical address.

Fixed at 17MB

Definition at line 49 of file fnrec.c.

Referenced by fnrec_init().


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
static int fnrec_is_valid ( void  ) [static]

Test whether the trace buffer is valid.

Return values:
is_validBuffer is valid

Definition at line 86 of file fnrec.c.

References FNREC_MAGIC, and fnrec_buffer::magic.

Referenced by __cyg_profile_func_enter(), __cyg_profile_func_exit(), and fnrec_init().

                                   {
        return ( fnrec_buffer && ( fnrec_buffer->magic == FNREC_MAGIC ) );
}
static void fnrec_invalidate ( void  ) [static]

Invalidate the trace buffer.

Definition at line 94 of file fnrec.c.

References fnrec_buffer::magic.

Referenced by fnrec_init().

                                      {
        fnrec_buffer->magic = 0;
}
static void fnrec_reset ( void  ) [static]

Reset the trace buffer and clear entries.

Definition at line 101 of file fnrec.c.

References FNREC_MAGIC, fnrec_buffer::magic, and memset().

Referenced by fnrec_init().

static struct fnrec_entry* fnrec_append ( void *  called_fn,
void *  call_site 
) [static, read]

Append an entry to the trace buffer.

Parameters:
called_fnCalled function
call_siteCall site
Return values:
entryTrace buffer entry

Definition at line 113 of file fnrec.c.

References fnrec_entry::call_site, fnrec_entry::called_fn, fnrec_entry::checksum, fnrec_buffer::data, entry, fnrec_entry::entry_count, fnrec_entry::exit_count, FNREC_NUM_ENTRIES, and fnrec_buffer::idx.

Referenced by __cyg_profile_func_enter(), and __cyg_profile_func_exit().

                                                                              {
        struct fnrec_entry *entry;

        /* Re-use existing entry, if possible */
        entry = &fnrec_buffer->data[ fnrec_buffer->idx ];
        if ( ( entry->called_fn == called_fn ) &&
             ( entry->call_site == call_site ) &&
             ( entry->entry_count >= entry->exit_count ) ) {
                return entry;
        }

        /* Otherwise, create a new entry */
        fnrec_buffer->idx = ( ( fnrec_buffer->idx + 1 ) % FNREC_NUM_ENTRIES );
        entry = &fnrec_buffer->data[ fnrec_buffer->idx ];
        entry->called_fn = called_fn;
        entry->call_site = call_site;
        entry->entry_count = 0;
        entry->exit_count = 0;
        entry->checksum = ( ( ( unsigned long ) called_fn ) ^
                            ( ( unsigned long ) call_site ) );
        return entry;
}
static void fnrec_dump ( void  ) [static]

Print the contents of the trace buffer in chronological order.

Definition at line 139 of file fnrec.c.

References fnrec_entry::call_site, fnrec_entry::called_fn, fnrec_entry::checksum, checksum, fnrec_buffer::data, entry, fnrec_entry::entry_count, fnrec_entry::exit_count, FNREC_NUM_ENTRIES, fnrec_buffer::idx, printf(), and virt_to_phys().

Referenced by fnrec_init().

                                {
        struct fnrec_entry *entry;
        unsigned int i;
        unsigned int idx;
        unsigned long checksum;

        printf ( "fnrec buffer dump:\n" );
        for ( i = 1 ; i <= FNREC_NUM_ENTRIES ; i++ ) {
                idx = ( ( fnrec_buffer->idx + i ) % FNREC_NUM_ENTRIES );
                entry = &fnrec_buffer->data[idx];
                if ( ( entry->entry_count == 0 ) && ( entry->exit_count == 0 ) )
                        continue;
                checksum = ( ( ( ( unsigned long ) entry->called_fn ) ^
                               ( ( unsigned long ) entry->call_site ) ) +
                             entry->entry_count + entry->exit_count );
                printf ( "%p %p %d %d", entry->called_fn, entry->call_site,
                         entry->entry_count, entry->exit_count );
                if ( entry->checksum != checksum ) {
                        printf ( " (checksum wrong at phys %08lx)",
                                 virt_to_phys ( entry ) );
                }
                printf ( "\n");
        }
}
static void fnrec_init ( void  ) [static]

Function tracer initialisation function.

Definition at line 167 of file fnrec.c.

References fnrec_dump(), fnrec_invalidate(), fnrec_is_valid(), FNREC_PHYS_ADDRESS, fnrec_reset(), phys_to_virt(), and printf().

                                {

        fnrec_buffer = phys_to_virt ( FNREC_PHYS_ADDRESS );
        if ( fnrec_is_valid() ) {
                fnrec_invalidate();
                fnrec_dump();
        } else {
                printf ( "fnrec buffer not found\n" );
        }
        fnrec_reset();
}
struct init_fn fnrec_init_fn __init_fn ( INIT_NORMAL  ) [read]
void __cyg_profile_func_enter ( void *  called_fn,
void *  call_site 
)

Definition at line 187 of file fnrec.c.

References fnrec_entry::checksum, entry, fnrec_entry::entry_count, fnrec_append(), fnrec_is_valid(), and mb().

                                                                   {
        struct fnrec_entry *entry;

        if ( fnrec_is_valid() ) {
                entry = fnrec_append ( called_fn, call_site );
                entry->entry_count++;
                entry->checksum++;
                mb();
        }
}
void __cyg_profile_func_exit ( void *  called_fn,
void *  call_site 
)

Definition at line 198 of file fnrec.c.

References fnrec_entry::checksum, entry, fnrec_entry::exit_count, fnrec_append(), fnrec_is_valid(), and mb().

                                                                  {
        struct fnrec_entry *entry;

        if ( fnrec_is_valid() ) {
                entry = fnrec_append ( called_fn, call_site );
                entry->exit_count++;
                entry->checksum++;
                mb();
        }
}

Variable Documentation

struct fnrec_buffer* fnrec_buffer [static]

The trace buffer.

Definition at line 79 of file fnrec.c.