summaryrefslogtreecommitdiff
path: root/microkernel/mach/gnumach/profiling.mdwn
blob: a15fab5e31817ff1e7a0ebd957df75e1d02640af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[[!meta copyright="Copyright © 2016 Free Software Foundation, Inc."]]

[[!meta license="""[[!toggle id="license" text="GFDL 1.2+"]][[!toggleable
id="license" text="Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License, Version 1.2 or
any later version published by the Free Software Foundation; with no Invariant
Sections, no Front-Cover Texts, and no Back-Cover Texts.  A copy of the license
is included in the section entitled [[GNU Free Documentation
License|/fdl]]."]]"""]]

Here is some guide to profile the GNU Mach kernel uses for a userland process.

[[!toc levels=2]]

First, it needs to be enabled: since this will leak kernel addresses to userland, it is not enabled by default. Pass `--enable-kernelsample` to the `./configure` invocation, and rebuild the kernel.

Then you need to get the start and end of the text portion of the kernel:

    nm gnumach | grep " _start$"
    nm gnumach | grep " etext$"

And you need to patch glibc to use these start and end instead of the userland starts and ends: in `glibc/csu/gmon-start.c`, in the `__monstartup` call, replace `TEXT_START` and `&etext` with the start and end addresses obtained above. Rebuild libc (`make lib` is enough). Install `csu/gcrt[01].o` in `/usr/lib/i386-gnu/`.

Now, you can rebuild your application with `-pg`, run it (for translators, use `settrans -a`, work with it, and use `settrans -fga` to terminate it nicely), you will get a `gmon.out` file. Normally you would just run `gprof application` to get the profiling, but here we need to get symbols from the kernel:

    nm -n gnumach > /tmp/list

and then we can run `gprof -S /tmp/list application`, and the kernel profiling will show up.

You will probably notice that `spl0` will show up a lot, more precisely the `sti` instruction. This is because all the kernel code running with interrupts disabled can't be profiled, and will be accounted for on that instruction (which triggers the profiling interrupts which should have happened while the interrupts were disabled).