Systemtapは、モジュールをロードするとカーネルモジュールの機能を検出します。

Systemtapは、モジュールをロードするとカーネルモジュールの機能を検出します。

モジュールをロードするときにカーネルモジュール関数でSystemtapプローブを使用する方法。ロード中の特定のモジュールから呼び出される関数を印刷しようとしています。hello.koロードされていないカーネルモジュールがあるとしましょう。今hello_init()このモジュールの機能を追跡したいと思います。次のSystemtapスクリプトを試しましたが、うまくいきません。

注文する:

stap test10.stp -c "modprobe hello"-->何も印刷されません。

システムタブスクリプト:

#!/usr/bin/env stap

global traces

probe module("hello").function("hello_init") {
    printf("hello")
    print_stack(backtrace())
}

カーネルモジュール:

#include <linux/module.h>       
#include <linux/kernel.h>       
#include <linux/init.h>         
MODULE_LICENSE("GPL");

static int __init hello_init(void)
{
printk(KERN_INFO "Hello world\n");
return 0;
}

static void __exit hello_exit(void)
{
printk(KERN_INFO "Done\n");
}

module_init(hello_init);
module_exit(hello_exit);

答え1

私が知る限り、生成されたカーネルモジュールにのみstaprun送信し、カーネルモジュールにプローブシンボルが見つからないため、カーネルモジュールにkprobeアドレスを設定しません。迅速な「テスト」のために代わりにアドレスを送信することができ、両方の機能が同じ署名を持つために機能します。kallsyms_on_each_symbolint send_relocation_kernel()staprun.ckallsyms_on_each_symbolmodule_kallsyms_on_each_symbolkallsyms_on_each_symbolint send_relocation_kernel()

変える

else if (linesize - pos == sizeof "kallsyms_on_each_symbol"
        && !strcmp(line + pos, "kallsyms_on_each_symbol" "\n"))
  {
     rc = send_a_relocation ("kernel", "kallsyms_on_each_symbol", address);

そして

else if (linesize - pos == sizeof "module_kallsyms_on_each_symbol"
        && !strcmp(line + pos, "module_kallsyms_on_each_symbol" "\n"))
  {
     rc = send_a_relocation ("kernel", "kallsyms_on_each_symbol", address);

この変更により、関数の検出器がinit()何かを印刷する必要があります。

関連情報