I'm just hazarding a guess here.
gprof
has a signal interrupt every 10ms, at which time it samples the program counter (PC).
The total self time of a routine is the number of samples landing in that routine.
Since it also counts calls to the routine, it can get the average self time per call.
Normally, when your program is blocked, like for I/O, sleep, or multitasking suspension, the PC is meaningless, so the interrupts are suspended.
That's why gprof
cannot see I/O at all.
However, if you have your own timer interrupt, that may only mask the profiler interrupt, not suspend it, causing it to be answered after your timer interrupt is dismissed, which might put the PC preferentially in your interrupt handler.
But that's just a guess.
Unless this is purely an academic question, there are better profilers than gprof
.