Chapter 3. Collecting and processing samples

Table of Contents

1. Receiving interrupts
2. Core data structures
3. Logging a sample
4. Logging stack traces
5. Synchronising the CPU buffers to the event buffer
6. Identifying binary images
7. Finding a sample's binary image and offset

1. Receiving interrupts

Naturally, how the overflow interrupts are received is specific to the hardware architecture, unless we are in "timer" mode, where the logging routine is called directly from the standard kernel timer interrupt handler.

On the i386 architecture, the local APIC is programmed such that when a counter overflows (that is, it receives an event that causes an integer overflow of the register value to zero), an NMI is generated. This calls into the general handler do_nmi(); because OProfile has registered itself as capable of handling NMI interrupts, this will call into the OProfile driver code in arch/i386/oprofile. Here, the saved PC value (the CPU saves the register set at the time of interrupt on the stack available for inspection) is extracted, and the counters are examined to find out which one generated the interrupt. Also determined is whether the system was inside kernel or user space at the time of the interrupt. These three pieces of information are then forwarded onto the OProfile core via oprofile_add_sample(). Finally, the counter values are reset to the chosen count value, to ensure another interrupt happens after another N events have occurred. Other architectures behave in a similar manner.