Process 如何访问进程';linux内核中的内核堆栈?

Process 如何访问进程';linux内核中的内核堆栈?,process,linux-kernel,stack,kernel-module,Process,Linux Kernel,Stack,Kernel Module,我试图监视进程在执行过程中调用哪些函数。我的目标是了解一个进程在每个函数中花费了多少时间。函数被推到堆栈上,并在函数调用返回时弹出。我想知道在内核代码中,这种推送和弹出实际上发生在哪里 我在task\u struct中找到了一个void*stack字段。我不确定这是否是我正在寻找的领域。如果是,那么如何知道它是如何更新的 我必须写一个模块,将利用这段代码。请帮我解决这个问题 函数被推到堆栈上,并在函数调用返回时弹出。我想知道在内核代码中,这种推送和弹出实际上发生在哪里 它不会发生在内核代码中,而

我试图监视进程在执行过程中调用哪些函数。我的目标是了解一个进程在每个函数中花费了多少时间。函数被推到堆栈上,并在函数调用返回时弹出。我想知道在内核代码中,这种推送和弹出实际上发生在哪里

我在
task\u struct
中找到了一个
void*stack
字段。我不确定这是否是我正在寻找的领域。如果是,那么如何知道它是如何更新的

我必须写一个模块,将利用这段代码。请帮我解决这个问题

函数被推到堆栈上,并在函数调用返回时弹出。我想知道在内核代码中,这种推送和弹出实际上发生在哪里

它不会发生在内核代码中,而是由处理器完成的。也就是说,当x86汇编CPU找到
call
指令时,它将
IP
推到堆栈上,而
ret
指令将弹出该值

您可以使用
call my_tracing_routine
修补内核中的每个
call
ret
指令,并在那里记录指令指针,然后将控制传递给原始被调用方/调用方。有这样的工具:,在内核接口中,如kprobes、ftrace。。。这种方法称为跟踪

但如果修补所有指令,即使用SystemTap probe
kernel.function(“*”
),则会破坏性能,并可能导致系统死机。所以,您不能测量每个函数调用,但您可以测量每个第n个函数调用,并希望得到相同的结果,但您需要大样本(即运行程序几分钟)——这称为评测

Linux附带分析器
perf

# perf record -- dd if=/dev/zero of=/dev/null
...
^C

# perf report
9.75%  dd  [kernel.kallsyms]  [k] __clear_user
6.69%  dd  [kernel.kallsyms]  [k] __audit_syscall_exit
5.61%  dd  [kernel.kallsyms]  [k] fsnotify
4.73%  dd  [kernel.kallsyms]  [k] system_call_after_swapgs
4.37%  dd  [kernel.kallsyms]  [k] system_call
...
您也可以使用
-g
来收集呼叫链。默认情况下,
perf
使用CPU性能计数器,因此在N个CPU周期后,会引发中断,perf处理程序(已嵌入内核)会保存
IP

如果您希望收集堆栈,可以使用SystemTap:

# stap --all-modules -e '
    probe timer.profile { 
        if(execname() == "dd") { 
            println("----"); 
            print_backtrace(); } 
        }' -c 'dd if=/dev/zero of=/dev/null' 
...
    ----
0xffffffff813e714d : _raw_spin_unlock_irq+0x32/0x3c [kernel]
0xffffffff81047bb9 : spin_unlock_irq+0x9/0xb [kernel]
0xffffffff8104ac68 : get_signal_to_deliver+0x4f0/0x528 [kernel]
0xffffffff8100216f : do_signal+0x48/0x4b1 [kernel]
0xffffffff81002608 : do_notify_resume+0x30/0x63 [kernel]
0xffffffff813edd6a : int_signal+0x12/0x17 [kernel]

在本例中,SystemTap使用连接到性能事件
cpu时钟的
timer.profile
探测器。为此,它生成、构建和加载内核模块。您可以通过函数检查
stap-k-p3

,您是指系统调用吗?或者只是您的代码从userland调用的userland中的任何函数?因为我现在无法评论,您是否尝试过为流程配置manning/proc/和strace?通过函数调用,我指的是作为流程执行一部分执行的所有可能函数。例如,对于用户级别的文件读取操作,将调用系统调用read(),然后是内核函数,如do_page_fault()、do_generic_file_read()等。感谢您的全面回复!你能详细介绍一下SystemTap输出吗?要获得上述表单的输出(堆栈跟踪),内核代码perf或SystemTap实用程序在哪里进行更改/更新?