问题标签 [kprobe]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
linux - kprobe 是否可用于除 /sys/kernel/debug/kprobes/blacklist 中的功能以外的所有功能?
我正在使用 kprobe 命令来跟踪一些内核函数。我使用的命令是:
kprobe "p:balance_pgdat"
但出现以下错误:
错误:函数 balance_pgdat 不在
我检查了 balance_pgdat 不在 available_filter_functions 中。但是,根据我的理解,无法跟踪的功能都保存在 /sys/kernel/debug/kprobes/blacklist 中,为什么还有其他功能不适用于 kprobe ?
感谢任何人的帮助!
linux - register_kprobe() 在包含结构时返回 EINVAL 而没有额外的内存
我编写了一个内核模块(一个字符设备),每当我写入模块时,它都会注册新的 KProbes。
我有一个包含struct kprobe
. 当我打电话时register_kprobe()
,它会返回-EINVAL
。但是当我向(可能还有其他一些数据类型)添加一个虚拟字符数组时,KProbe 注册成功。
探针注册
不工作:
在职的:
为什么它需要这个额外的内存位存在于结构中?
linux - register_kprobe 为涉及 rip 的指令返回 EINVAL (-22) 错误
我正在尝试在内核模块的功能中使用 kprobes 以不同的指令插入探针。
但是 register_kprobe 从下面的汇编代码返回 0xffffffffa33c1085 指令地址和 0xffffffffa33c109b 的 EINVAL(-22) 错误(它传递给所有其他指令地址)。
给出错误的说明:
观察到这两条指令都使用了 rip 寄存器。尝试使用其他模块的功能,发现与使用 rip 寄存器的指令相同的错误。
为什么 register_kprobe 失败?它有任何涉及 rip 的限制吗?任何帮助表示赞赏。
系统在 x86_64 上安装了内核 3.10.0-514。
kprobe函数:
探测功能:
汇编代码:
谢谢
linux - kprobe 处理程序未针对特定功能触发
我正在尝试使用 kprobes 拦截模块中的以下函数。为此函数传递了“register_kprobe”,但在调用函数时未触发 Kprobe 处理程序。
奇怪的是,如果我在探测函数中打印函数地址,它就会开始工作(调用 kprobe 处理程序)。它也适用于内核中的其他功能。
为什么 kprobe 处理程序没有被触发,打印功能地址有什么不同?
系统在 x86_64 上安装了 3.10 内核。
不工作的代码:
工作代码:
调用 func(它被注册为回调以写入 debugfs 文件):
kprobe函数:
谢谢。
linux - 为什么 kprobes 禁用抢占,什么时候可以安全地重新启用它?
根据文档,kprobes 禁用抢占:
探测处理程序在禁用抢占的情况下运行。根据架构和优化状态,处理程序也可以在禁用中断的情况下运行(例如,在 x86/x86-64 上,kretprobe 处理程序和优化的 kprobe 处理程序在没有中断禁用的情况下运行)。
从提交 9a09f261a中,我们可以清楚地看到优化的 kprobe 用于在启用抢占的情况下运行。
为什么会这样?我将 kprobes 理解为在内核中的特定地址注入一些代码的一种方式,并且理解任何代码都应该没问题。
- 是什么让 kprobes 如此特别以至于必须禁用抢占?
- 在什么情况下可以重新启用抢占?
bpf - 在 BPF 程序中总是得到 0 会话 ID
我正在尝试编写一个 BPF 程序来检查调用tty_write
内核函数的任何进程的会话 ID。我试图通过从当前task_struct
结构中检索一个字段来做到这一点。我的代码如下:
请注意,我正在将我的 BPF 程序编译clang
成一个 ELF 文件并使用gobpf 的ELF 包加载它。不幸的是, 的值sessionid
始终为 0。这是为什么呢?我认为我没有错误地访问会话 ID,因为我在 4.11 内核上使用bcc之前已经这样做了(由于 bcc 如何重写 BPF 程序,当我想自己编译程序时,我不能简单地使用相同的代码)。用于访问的等效工作密件抄送代码sessionid
如下。请注意,这仅适用于 4.11 内核,以下代码不适用于 4.13 内核。然而,上面的代码在这两个内核上都不起作用。
4.11内核:
uname -a
:Linux ubuntu16 4.11.0-14-generic #20~16.04.1-Ubuntu SMP Wed Aug 9 09:06:22 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
4.13内核:
uname -a
: Linux ubuntu1710 4.13.0-32-generic #35-Ubuntu SMP Thu Jan 25 09:13:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
linux-kernel - kprobe 模块在执行“echo 0 > /proc/sys/kernel/ftrace_enabled”后无法工作
只需对 ftrace 进行一些研究。
TCP echo 程序在两台主机之间运行。
当我关闭大开关(echo 0 > /proc/sys/kernel/ftrace_enabled
)时,我自己的 kprobe 模块也无法工作。在内核日志文件中看不到 printk 消息。另外,pkt修改操作失败,可以成功接收到pkt。这真的让我很困惑。
我的测试 kprobe 模块在这里:
linux-kernel - ebpf:拦截函数调用
我正在阅读有关kprobes
BPF 程序类型的信息,并且想知道是否有可能不仅拦截函数调用以进行跟踪或收集一些低级信息(寄存器、堆栈等),还可以替换调用并执行而不是实际功能?
是否kprobe
提供此功能或我正在寻找错误的工具?
linux - kprobe 不适用于某些功能
我正在尝试使用 kprobe 来跟踪handle_pte_fault
linux 内核中的函数调用。我可以探测handle_mm_fault
,但是当我尝试探测时handle_pte_dault
,kprobe 的处理程序handle_pte_fault
不会打印任何内容。
使用这个我发现我无法探测一个内联的函数,也可能是静态的。所以,我改变了handle_pte_fault
函数的定义如下并重新编译了内核。
从:
至:
我还添加了以下内容以确保handle_pte_fault
符号存在
我仍然无法跟踪/探测 handle_pte_fault 功能。任何帮助或解释。这是否意味着 kprobe 仅适用于某些随机函数?
我正在使用内核 v4.13。
下面是我正在使用的 kprobe 的内核模块代码:
c - 在 Linux 中跟踪硬 irq
我对 Linux 内核的经验非常少。我最近才开始玩弄它。
为了我的研究目的,我一直在尝试追踪数据包到达的最早时间。我可以在设备驱动程序级别通过修改设备驱动程序并在设备驱动程序的中断处理函数中记录时间戳来做到这一点。很抱歉这篇文章可能会有点长。
例如,我修改了这个函数(https://elixir.bootlin.com/linux/v4.7/source/drivers/net/ethernet/intel/i40e/i40e_main.c#L3232)来跟踪调用的时间戳这个功能的。
进一步深入并遵循此调用的堆栈跟踪,我们将找到如下堆栈跟踪:
- i40e_msix_clean_rings() - i40e 驱动程序的 i40e_main.c 在上面提供的链接中
- __handle_irq_event_percpu() -内核/irq/handle.c
- handle_irq_event_percpu() -内核/irq/handle.c
- handle_irq_event() -内核/irq/handle.c
- handle_edge_irq() - kernel/irq/chip.c
- handle_irq() -arch/x86/kernel/irq_64.c
- do_IRQ() -arch/x86/kernel / irq.c
- common_interrupt() -不太确定,但实现应该类似于 arch/x86/kernel/head_32.s 中的 early_idt_handler_common()
我试图在函数 do_IRQ() 函数(上面的堆栈跟踪中的粗体字)中跟踪我的数据包到达的时间戳。作为参考,do_IRQ 函数如下所示:
为了让我的意图更清楚一点,我已经表明我在这个函数中的更改包含在“**”中。
例如,在我的测试机器上,我的 NIC 绑定到 IRQ 编号19。int_number变量代表该编号。因此,这让我可以跟踪特定 IRQ 编号的 IRQ。
这听起来可能与单队列 NIC 适配器无关,但它适用于多队列适配器,因为我可以将我的数据包定向到带有流控制器的固定队列,并且每个队列都绑定到特定的 IRQ 号。因此,这将帮助我轻松追踪我的数据包。
我的方法:
- 在此函数中添加手动实现;我认为这不是正确的方法。
- 使用 kprobes。但它是否让我根据变量或参数内部的内容过滤我的踪迹?
- 使用 jprobe。我想,通过这种方法,我们将能够玩弄这些论点。我能够处理这个事件。我只是按照jprobe的例子。(https://stuff.mit.edu/afs/sipb/contrib/linux/samples/kprobes/jprobe_example.c)等等。
- 在通过上述方法时,我也遇到了其他工具。比如性能、性能工具、eBPF。但是,我不确定哪种方法最适合我。
只是为了澄清我的最终任务:我正在尝试捕获我的数据包最早到达的时间戳,例如:
我将不胜感激任何形式的投入。
谢谢 !