Linux内核中如何通过函数指针打印函数名称?
Hey there! Let's tackle how to trace those initcall function pointers and their execution order. I see you've got the loop over initcall_levels already—great start. Here are a few practical ways to get the function info you need:
1. Fix Your Existing printk Statement
First, I spotted a small issue in your commented-out printk: you're passing fn (a pointer to the function pointer) to %pF, but you should be passing *fn (the actual function pointer itself). Also, enabling the right kernel configs is critical for resolving raw addresses to human-readable function names.
Required Kernel Configs
Make sure these are enabled in your kernel config (use make menuconfig to check/edit):
CONFIG_KALLSYMS: Enables kernel symbol table supportCONFIG_KALLSYMS_ALL: Includes all symbols, not just minimal debugging ones
Updated Code Snippet
Modify your loop to print detailed execution info, including return codes:
for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) { // Print function details before execution printk(KERN_INFO "xhl -- Initcall level %d: Executing %pF (address: %p)\n", level, *fn, *fn); // Execute the initcall and capture its return value int ret = do_one_initcall(*fn); // Print the execution result printk(KERN_INFO "xhl -- %pF completed with return code %d\n", *fn, ret); }
After rebuilding and booting the kernel, check dmesg—you'll see actual function names (like usb_hub_init) instead of just raw addresses.
2. Use the initcall_debug Kernel Parameter (No Code Changes!)
If you don't want to modify kernel code at all, this is the quickest method. Just add initcall_debug to your kernel boot parameters (e.g., edit the GRUB boot entry and append it to the linux line).
Once the system boots, check dmesg—the kernel will automatically log every initcall with its function name, execution time, and return code, like this:
[ 0.123456] initcall foo_init+0x0/0x100 returned 0 after 123 usecs
3. Trace with Ftrace (Advanced, No Code Changes)
Ftrace is a powerful built-in kernel tracing tool that lets you track function calls without modifying code. Here's how to use it to trace do_one_initcall and its targets:
- Mount debugfs (if not already mounted):
mount -t debugfs none /sys/kernel/debug - Enable the function graph tracer to see call hierarchies:
echo function_graph > /sys/kernel/debug/tracing/current_tracer - Set
do_one_initcallas the function to focus on:echo do_one_initcall > /sys/kernel/debug/tracing/set_graph_function - Start tracing:
echo 1 > /sys/kernel/debug/tracing/tracing_on - After the system boots (or initcalls run), view the trace output:
cat /sys/kernel/debug/tracing/trace
This will show you the exact order of functions called via do_one_initcall, along with their execution times and call stacks.
内容的提问来源于stack exchange,提问作者teddyxiong53

