iPXE
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...

Macros

#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_buffer * fnrec_buffer
 The trace buffer.

Detailed Description

Function trace recorder for crash and hang debugging.

Definition in file fnrec.c.

Macro Definition Documentation

◆ FNREC_MAGIC

#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().

◆ FNREC_NUM_ENTRIES

#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().

◆ FNREC_PHYS_ADDRESS

#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()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ fnrec_is_valid()

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.

86 {
87 return ( fnrec_buffer && ( fnrec_buffer->magic == FNREC_MAGIC ) );
88}
#define FNREC_MAGIC
Constant for identifying valid trace buffers.
Definition fnrec.c:40
A trace buffer.
Definition fnrec.c:66
uint32_t magic
Constant for identifying valid trace buffers.
Definition fnrec.c:68

References FNREC_MAGIC, and fnrec_buffer::magic.

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

◆ fnrec_invalidate()

void fnrec_invalidate ( void )
static

Invalidate the trace buffer.

Definition at line 94 of file fnrec.c.

94 {
96}

References fnrec_buffer::magic.

Referenced by fnrec_init().

◆ fnrec_reset()

void fnrec_reset ( void )
static

Reset the trace buffer and clear entries.

Definition at line 101 of file fnrec.c.

101 {
102 memset ( fnrec_buffer, 0, sizeof ( *fnrec_buffer ) );
104}
void * memset(void *dest, int character, size_t len) __nonnull

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

Referenced by fnrec_init().

◆ fnrec_append()

struct fnrec_entry * fnrec_append ( void * called_fn,
void * call_site )
static

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.

113 {
114 struct fnrec_entry *entry;
115
116 /* Re-use existing entry, if possible */
117 entry = &fnrec_buffer->data[ fnrec_buffer->idx ];
118 if ( ( entry->called_fn == called_fn ) &&
119 ( entry->call_site == call_site ) &&
120 ( entry->entry_count >= entry->exit_count ) ) {
121 return entry;
122 }
123
124 /* Otherwise, create a new entry */
126 entry = &fnrec_buffer->data[ fnrec_buffer->idx ];
127 entry->called_fn = called_fn;
128 entry->call_site = call_site;
129 entry->entry_count = 0;
130 entry->exit_count = 0;
131 entry->checksum = ( ( ( unsigned long ) called_fn ) ^
132 ( ( unsigned long ) call_site ) );
133 return entry;
134}
#define FNREC_NUM_ENTRIES
Number of trace buffer entries.
Definition fnrec.c:43
unsigned int idx
Next trace buffer entry to fill.
Definition fnrec.c:71
struct fnrec_entry data[FNREC_NUM_ENTRIES]
Trace buffer.
Definition fnrec.c:74
A trace buffer entry.
Definition fnrec.c:52
void * called_fn
Called function address.
Definition fnrec.c:54
void * call_site
Call site.
Definition fnrec.c:56
uint16_t entry_count
Entry count.
Definition fnrec.c:58
unsigned long checksum
Checksum.
Definition fnrec.c:62
uint16_t exit_count
Exit count.
Definition fnrec.c:60

References fnrec_entry::call_site, fnrec_entry::called_fn, fnrec_entry::checksum, fnrec_buffer::data, 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().

◆ fnrec_dump()

void fnrec_dump ( void )
static

Print the contents of the trace buffer in chronological order.

Definition at line 139 of file fnrec.c.

139 {
140 struct fnrec_entry *entry;
141 unsigned int i;
142 unsigned int idx;
143 unsigned long checksum;
144
145 printf ( "fnrec buffer dump:\n" );
146 for ( i = 1 ; i <= FNREC_NUM_ENTRIES ; i++ ) {
147 idx = ( ( fnrec_buffer->idx + i ) % FNREC_NUM_ENTRIES );
148 entry = &fnrec_buffer->data[idx];
149 if ( ( entry->entry_count == 0 ) && ( entry->exit_count == 0 ) )
150 continue;
151 checksum = ( ( ( ( unsigned long ) entry->called_fn ) ^
152 ( ( unsigned long ) entry->call_site ) ) +
153 entry->entry_count + entry->exit_count );
154 printf ( "%p %p %d %d", entry->called_fn, entry->call_site,
155 entry->entry_count, entry->exit_count );
156 if ( entry->checksum != checksum ) {
157 printf ( " (checksum wrong at phys %08lx)",
158 virt_to_phys ( entry ) );
159 }
160 printf ( "\n");
161 }
162}
uint8_t checksum
Checksum.
Definition pnpbios.c:12
int printf(const char *fmt,...)
Write a formatted string to the console.
Definition vsprintf.c:465

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

Referenced by fnrec_init().

◆ fnrec_init()

void fnrec_init ( void )
static

Function tracer initialisation function.

Definition at line 167 of file fnrec.c.

167 {
168
169 fnrec_buffer = phys_to_virt ( FNREC_PHYS_ADDRESS );
170 if ( fnrec_is_valid() ) {
172 fnrec_dump();
173 } else {
174 printf ( "fnrec buffer not found\n" );
175 }
176 fnrec_reset();
177}
#define FNREC_PHYS_ADDRESS
Trace buffer physical address.
Definition fnrec.c:49
static int fnrec_is_valid(void)
Test whether the trace buffer is valid.
Definition fnrec.c:86
static void fnrec_dump(void)
Print the contents of the trace buffer in chronological order.
Definition fnrec.c:139
static void fnrec_invalidate(void)
Invalidate the trace buffer.
Definition fnrec.c:94
static void fnrec_reset(void)
Reset the trace buffer and clear entries.
Definition fnrec.c:101

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

Referenced by __init_fn().

◆ __init_fn()

struct init_fn fnrec_init_fn __init_fn ( INIT_NORMAL )

References __init_fn, fnrec_init(), and INIT_NORMAL.

◆ __cyg_profile_func_enter()

void __cyg_profile_func_enter ( void * called_fn,
void * call_site )

Definition at line 188 of file fnrec.c.

188 {
189 struct fnrec_entry *entry;
190
191 if ( fnrec_is_valid() ) {
192 entry = fnrec_append ( called_fn, call_site );
193 entry->entry_count++;
194 entry->checksum++;
195 mb();
196 }
197}
static struct fnrec_entry * fnrec_append(void *called_fn, void *call_site)
Append an entry to the trace buffer.
Definition fnrec.c:113
void mb(void)
Memory barrier.

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

◆ __cyg_profile_func_exit()

void __cyg_profile_func_exit ( void * called_fn,
void * call_site )

Definition at line 199 of file fnrec.c.

199 {
200 struct fnrec_entry *entry;
201
202 if ( fnrec_is_valid() ) {
203 entry = fnrec_append ( called_fn, call_site );
204 entry->exit_count++;
205 entry->checksum++;
206 mb();
207 }
208}

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

Variable Documentation

◆ fnrec_buffer

struct fnrec_buffer* fnrec_buffer
static

The trace buffer.

Definition at line 79 of file fnrec.c.