简体   繁体   English

Linux内核函数调用流程

[英]Linux kernel function call flow

Is there a way to get to know what kernel functions are called during a certain event.有没有办法了解在某个事件期间调用了哪些内核函数。

For example, if I press any key on keyboard, I want to know what all kernel functions and device driver functions are getting called - before the character appears on the screen (the character corresponding to the key that I typed on keyboard).例如,如果我按下键盘上的任意键,我想知道所有内核函数和设备驱动程序函数都被调用了 - 在字符出现在屏幕上之前(与我在键盘上键入的键对应的字符)。

I want to dump the complete flow somewhere and examine it later.我想将完整的流程转储到某个地方,稍后再检查。 I'm talking about kernel-space functions - NOT user-space functions.我说的是内核空间函数——而不是用户空间函数。

I want to know what all kernel functions and device driver functions are getting called我想知道所有内核函数和设备驱动程序函数都被调用了什么

Obviously, the fullness of the trace depends on where it is started.显然,轨迹的完整程度取决于它的起点。 And that's up to you.这取决于你。

You can traсе what you want through the handy trace-cmd .您可以通过方便的trace-cmd您想要的内容。 Eg you can obtain the function graph.例如,您可以获得函数图。 Firstly you need to determine some entry point depending on your needs.首先,您需要根据需要确定一些入口点。
If it is about keyboard pressing, you need to find its driver and some function related to it.如果是关于键盘按下,你需要找到它的驱动程序和一些与它相关的功能。

Example:例子:
Classic AT and PS/2 keyboard driver atkbd has interrupt function atkbd_interrupt .经典的 AT 和 PS/2 键盘驱动程序atkbd具有中断函数atkbd_interrupt Let's check if there is such a trace point:让我们检查一下是否有这样的跟踪点:

trace-cmd list -f | grep atkbd_int

Then start the recording:然后开始录制:

trace-cmd record -p function_graph -g atkbd_interrupt &

Press some keys and stop recording: fg then Ctrl+C .按一些键并停止录制: fg然后Ctrl+C Now you can obtain the function graph:现在你可以得到函数图:

trace-cmd report | vim -

It would be something like:它会是这样的:

CPU 1 is empty
CPU 2 is empty
CPU 3 is empty
cpus=4
          <idle>-0     [000] 1095787.266859: funcgraph_entry:                   |  atkbd_interrupt() {
          <idle>-0     [000] 1095787.266863: funcgraph_entry:                   |    input_event() {
          <idle>-0     [000] 1095787.266864: funcgraph_entry:        0.215 us   |      _raw_spin_lock_irqsave();
          <idle>-0     [000] 1095787.266866: funcgraph_entry:        0.386 us   |      input_handle_event();
          <idle>-0     [000] 1095787.266867: funcgraph_entry:        0.163 us   |      _raw_spin_unlock_irqrestore();
          <idle>-0     [000] 1095787.266868: funcgraph_exit:         3.882 us   |    }
          <idle>-0     [000] 1095787.266869: funcgraph_entry:                   |    input_event() {
          <idle>-0     [000] 1095787.266869: funcgraph_entry:        0.123 us   |      _raw_spin_lock_irqsave();
          <idle>-0     [000] 1095787.266870: funcgraph_entry:                   |      input_handle_event() {
          <idle>-0     [000] 1095787.266871: funcgraph_entry:                   |        add_input_randomness() {
          <idle>-0     [000] 1095787.266871: funcgraph_entry:                   |          add_timer_randomness() {
          <idle>-0     [000] 1095787.266872: funcgraph_entry:                   |            mix_pool_bytes() {
          <idle>-0     [000] 1095787.266872: funcgraph_entry:        0.327 us   |              _raw_spin_lock_irqsave();
          <idle>-0     [000] 1095787.266873: funcgraph_entry:        0.877 us   |              _mix_pool_bytes();
          <idle>-0     [000] 1095787.266875: funcgraph_entry:        0.163 us   |              _raw_spin_unlock_irqrestore();
          <idle>-0     [000] 1095787.266876: funcgraph_exit:         3.628 us   |            }
          <idle>-0     [000] 1095787.266876: funcgraph_entry:                   |            credit_entropy_bits() {
          <idle>-0     [000] 1095787.266877: funcgraph_entry:                   |              __wake_up() {
          <idle>-0     [000] 1095787.266877: funcgraph_entry:        0.229 us   |                _raw_spin_lock_irqsave();
          <idle>-0     [000] 1095787.266878: funcgraph_entry:        0.120 us   |                __wake_up_common();
          <idle>-0     [000] 1095787.266879: funcgraph_entry:        0.135 us   |                _raw_spin_unlock_irqrestore();
          <idle>-0     [000] 1095787.266880: funcgraph_exit:         2.719 us   |              }
          <idle>-0     [000] 1095787.266880: funcgraph_entry:        0.108 us   |              kill_fasync();
          <idle>-0     [000] 1095787.266881: funcgraph_exit:         4.833 us   |            }
          <idle>-0     [000] 1095787.266882: funcgraph_exit:       + 10.249 us  |          }
          <idle>-0     [000] 1095787.266882: funcgraph_exit:       + 11.186 us  |        }
          <idle>-0     [000] 1095787.266883: funcgraph_entry:        0.237 us   |        atkbd_event();
          <idle>-0     [000] 1095787.266884: funcgraph_exit:       + 13.347 us  |      }
          <idle>-0     [000] 1095787.266884: funcgraph_entry:        0.138 us   |      _raw_spin_unlock_irqrestore();
          ........                                                         

It's just a little piece of trace for example.例如,这只是一小段痕迹。 I did it in my qemu VM.我在我的 qemu VM 中做到了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM