【原创】Linux kprobe 实现原理 图文详解 (一) kprobe实现原理

linux kprobe使用 kprobe 阅读详情

目录

一、kprobe 基本介绍

二、kprobe 实现原理

三、BRK指令

四、具体代码


(代码:linux 6.3.1,架构:arm64)

One look is worth a thousand words.  —— Tess Flanders

相关链接:

【原创】Linux kprobe 实现原理 图文详解 (二) kretprobe实现原理

【原创】Linux kprobe 实现原理 图文详解 (三) kprobe跳转优化

【原创】Linux kprobe 实现原理 图文详解 (四) 指令替换、cpu stopper

一、kprobe 基本介绍

        Kprobe 是 Linux内核 提供的一种动态调试机制,用于debug、动态跟踪、性能分析。Kprobe技术可以对内核函数进行探测,使得被探测指令执行的前后,可以执行用户注册的钩子函数(pre_handler、post_handler)。

        Kprobe可以在大部分内核代码段插入探测点,除了一些分支类指令(如:br、exception、eret等)、以及Kprobe模块本身代码也无法被探测。

二、kprobe 实现原理

        上图为内核image反汇编后某一个函数的前2条指令,假设采用kprobe对第一条指令“stp x29, x30, [sp, #-32]!”进行打桩探测。打桩后,kprobe触发的完整流程图如下:

        1)register_kprobe内核接口,会将代码中 “被探测指令” 替换成 “断点指令BRK” (arm64架构),同时会分配 “指令槽”,用于存放 “被探测指令”、BRK指令;

        2)  当程序执行到被探测指令(本例中为0xffff80000001ae70)时,由于代码段中对应指令已经被替换成BRK断点指令,于是会触发同步异常,陷入异常处理;

        3)在 el1 sync 异常处理中,会根据 ESR寄存器 中的异常信息走brk_handler处理流程,一步步最终会调用到:register_kprobe注册时提供的 pre_handler 钩子函数;当其执行完后,会将任务寄存器上下文中的 PC 修改为 “指令槽地址”,然后eret从异常返回;

        4)当从异常返回后,程序会跳转到指令槽,并执行其中保存的 “被探测指令 stp, x29, 30, [sp, #-32]!”(上图中的步骤4),执行完后 PC+4,接着执行下一条 BRK指令,再次触发同步异常陷入内核 el1 sync 同步异常处理流程;

        5)在异常处理中,同样会根据esr信息,最终调用到 register_kprobe注册时提供的 post_handler 钩子函数;当该钩子函数执行完毕后,会将 regs->PC 重新设置为 “被探测指令 + 4” (即:被探测指令的下一条指令),然后异常返回后,程序就会回到原先的指令指令流程中去了。

三、BRK指令

        arm64架构下指令异常指令是BRK,看完上述kprobe完成流程后,有些小伙伴心中可能会有些疑惑:BRK断点指令触发的2次同步异常,会调用到不同的钩子函数,内核是如何进行区分的?

        要回答上述问题,就要来看一下ARM64手册中 “brk指令” 的编码方式:

        可以看到:BRK指令 5~20 bit(imm16字段)代表该BRK指令的用途,触发异常时,这16 bits 会被记录到 ESR寄存器 中。

        这样在同步异常处理时,就可以根据 ESR寄存器中的 “ESR_ELx_BRK64_ISS_COMMENT_MASK” 字段,区分判断出本次BRK异常的触发原因,进而调用不同的处理函数,最终分别执行到 kprobe被探测指令对应的 pre_handler、post_handler。

        上图中,“BRK64_OPCODE_KPROBES”、“BRK64_OPCODE_KPROBES_SS” 分别就是:“替换被探测指令的BRK指令” 、以及 “指令槽中的BRK指令”。

ESR_EL1(Exception Syndrome Register)

        当执行BRK指令触发异常陷入内核后,ESR寄存器中的EC字段为0b111100(即:0x3C), ISS字段的[0-15]位,为immediate field(即:BRK指令的imm16字段!)

      例:修改PC寄存器中的命令为BRK64_OPCODE_KPROBES(0xd4200080),即: (AARCH64_BREAK_MON | (KPROBES_BRK_IMM << 5))。当CPU执行这条命令时,会触发异常陷入内核。陷入内核时,ESR寄存器中的内容的低16位为:0x0004(即:KPROBES_BRK_IMM)。

四、具体代码

1、kprobe数据结构

struct kprobe {
	struct hlist_node hlist;				// 用于挂载到全局哈希表kprobe_table上的node节点

	struct list_head list;					/* list of kprobes for multi-handler support (对于aggr_kprobe, 该成员为链表头. 对于普通kprobe, 该成员为挂载到aggr_kprobe->list的链表节点) */ 
	
	unsigned long nmissed;					/*count the number of times this probe was temporarily disarmed. 代表CPU正在执行其他kprobe过程中, hit到了该kprobe指令, 从到导致该kprobe指令仅被执行探测指令本身, 但未执行pre_handler和post_handler. 即: 该kprobe点被hit到,但pre_handler和post_handler未被执行的次数. */

	kprobe_opcode_t *addr;					/* location of the probe point */

	const char *symbol_name;				/* Allow user to indicate symbol name of the probe point */

	unsigned int offset;					/* Offset into the symbol */

	kprobe_pre_handler_t pre_handler;		/* Called before addr is executed. */

	kprobe_post_handler_t post_handler;		/* Called after addr is executed, unless... */

	kprobe_opcode_t opcode;					/* Saved opcode (which has been replaced with breakpoint) (被探测的指令内容) */

	struct arch_specific_insn ainsn;		/* copy of the original instruction (指令槽, 用于存放被探测指令和软断点指令) */

	/*
	 * Indicates various status flags.
	 * Protected by kprobe_mutex after this kprobe is registered.
	 */
	u32 flags;
};


#define	arch_specific_insn	arch_probes_insn

struct arch_probe_insn {
	probe_opcode_t *insn;
	pstate_check_t *pstate_cc;
	probes_handler_t *handler;
	/* restore address after step xol */
	unsigned long restore;
};

struct arch_specific_insn {
	struct arch_probe_insn api;
};

2、注册kporbe

int register_kprobe(struct kprobe *p) {
	kprobe_opcode_t *addr
	
	addr = kprobe_addr(p)
	
	p->addr = addr
	
	ret = warn_kprobe_rereg(p)
	if (ret)
		return ret
	
	/* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */
	p->flags &= KPROBE_FLAG_DISABLED;
	p->nmissed = 0;
	INIT_LIST_HEAD(&p->list);
	
	check_kprobe_address_safe	// 检查probe地址安全性 (Detail see below)
	
	mutex_lock(&kprobe_mutex)

	old_p = get_kprobe(p->addr)
	if (old_p)
		...
	
	cpus_read_lock()
	mutex_lock(&text_mutex)		// Prevent text modification
	prepare_kprobe(p) {
		/* Must ensure p->addr is really on ftrace */
		if (kprobe_ftrace(p))
			...
		
		arch_prepare_kprobe(p) {
			unsigned long probe_addr = (unsigned long)p->addr
			
			/* copy instruction */
			p->opcode = le32_to_cpu(*p->addr)
			
			if (search_exception_tables(probe_addr))
				return -EINVAL
			
			enum probe_insn decoded = arm_kprobe_decode_insn(p->addr, &p->ainsn)	/* decode instruction (Detail see below) */
			switch (decoded) {
				case INSN_REJECTED:		/* insn not supported */
					return -EINVAL;
				case INSN_GOOD_NO_SLOT:	/* insn need simulation */
					p->ainsn.api.insn = NULL
					break
				case INSN_GOOD:			/* instruction uses slot */
					p->ainsn.api.insn = get_insn_slot()
					if (!p->ainsn.api.insn)
						return -ENOMEM
					break
			}
			
			/* prepare the instruction. 即: 将2条指令写到指令槽中, 记录probe指令的下一条指令 */
			if (p->ainsn.api.insn) {
				### 分配保存两条指令的地址(ainsn.api.insn[0] 和 ainsn.api.insn[1]),在这2个指令地址上分别填写 探测的指令内容(即: p->opcode) 以及 软断点BRK指令. 
				### 同时在kprobe->ainsn.api.restore中记录探测指令的下一条指令.
				###
				### 【kprobe->ainsn.api.insn这个字段记录的两条指令地址的执行时机】
				###  BRK64_OPCODE_KPROBES断点指令触发后且执行完pre_handler后,就会执行kprobe->ainsn.api.insn中2条指令地址上的指令. 
				### 【具体实现】
				###  通过KPROBES_BRK_IMM类型异常的handler, 将PC指向p->ainsn.api.insn
				###  kprobes_break_hook.fn
				###  A.K.A
				###  kprobe_breakpoint_handler
				###  	kprobe_handler
				###  		setup_singlestep
				###  			instruction_pointer_set(regs, (unsigned long)p->ainsn.api.insn)
				###  				regs->pc = (unsigned long)p->ainsn.api.insn
				arch_prepare_ss_slot(p) {
					kprobe_opcode_t *addr = p->ainsn.api.insn
					void *addrs[] = {addr, addr + 1}						// 指令地址
					u32 insns[]   = {p->opcode, BRK64_OPCODE_KPROBES_SS}	// 指令内容
					
					/* prepare insn slot. 将insns中保存的2条指令内容, 填写到p->ainsn.api.insn所代表的指令槽中 */
					aarch64_insn_patch_text(addrs, insns, cnt = 2)
					
					flush_icache_range((uintptr_t)addr, (uintptr_t)(addr + MAX_INSN_SIZE))   
						...//TODO
					
					### 保存观测指令的下一条指令, 即: 观测指令地址 + 4
					/* Needs restoring of return address after stepping xol. */
					p->ainsn.api.restore = (unsigned long) p->addr + sizeof(kprobe_opcode_t)
				}
			} else {
				arch_prepare_simulate(p) {
					/* This instructions is not executed xol. No need to adjust the PC */
					p->ainsn.api.restore = 0
				}
			}
		}
	}
	mutex_unlock(&text_mutex)
	cpus_read_unlock()
	
	INIT_HLIST_NODE(&p->hlist)
	hlist_add_head_rcu(&p->hlist, &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)])
	
	### 若kprobe->flags含有(KPROBE_FLAG_DISABLED | KPROBE_FLAG_GONE)中的一位, 就不arm kprobe!!!	  《《《《《《《《《《 !!!《《《《《《《《《《
	if (!kprobes_all_disarmed && !kprobe_disabled(p))	
		arm_kprobe(p)									// ##### <<<<< Install breakpoint for kprobe in text. (Details see below)
	
	try_to_optimize_kprobe(p)	/* Try to optimize kprobe */
	
	mutex_unlock(&kprobe_mutex)
}

3、第一次 BRK(KPROBE_BRK_IMM)同步异常,触发后的处理流程

el1h_64_sync_handler(struct pt_regs *regs) {		// arch/arm64/kernel/entry-common.c
	unsigned long esr = read_sysreg(esr_el1)
	switch (ESR_ELx_EC(esr)) {
		case ESR_ELx_EC_BRK64:
		el1_dbg(regs, esr) {
			/*
			 * Handle IRQ/context state management when entering a debug exception from
			 * kernel mode. Before this function is called it is not safe to call regular
			 * kernel code, intrumentable code, or any code which may trigger an exception.
			 */
			arm64_enter_el1_dbg(regs)
			do_debug_exception(far, esr, regs) {
				const struct fault_info *inf = esr_to_debug_fault_info(esr)
					return debug_fault_info + DBG_ESR_EVT(esr)
				inf->fn(addr_if_watchpoint, esr, regs)
				A.K.A
				brk_handler {
					call_break_hook(regs, esr) { 		// <<<<< used for kprobes
						list = user_mode(regs) ? &user_break_hook : &kernel_break_hook
						list_for_each_entry_rcu(hook, list, node) {						// arch_init_kprobes中会将kprobes_break_hook注册到kernel_break_hook list
							unsigned int comment = esr & ESR_ELx_BRK64_ISS_COMMENT_MASK
							if ((comment & ~hook->mask) == hook->imm)					// hook->imm: KPROBES_BRK_IMM
								fn = hook->fn
						}
						
						return fn ? fn(regs, esr) : DBG_HOOK_ERROR
						A.K.A
						kprobe_breakpoint_handler {						// ##### <<<< 执行观测指令前, 会先触发异常, 进到这里
							kprobe_handler(regs) {
								struct kprobe *p, *cur_kprobe
								struct kprobe_ctlblk *kcb
								unsigned long addr = instruction_pointer(regs)
								
								kcb = get_kprobe_ctlblk()
								cur_kprobe = kprobe_running()
								
								p = get_kprobe((kprobe_opcode_t *) addr)
								
								if (p) {
									if (cur_kprobe)
										if (reenter_kprobe(p, regs, kcb))
											return
									else {
										/* Probe hit */
										set_current_kprobe(p)
											__this_cpu_write(current_kprobe, p)
										
										kcb->kprobe_status = KPROBE_HIT_ACTIVE
										
										### 1) 若没有注册pre_handler, 就继续走正常处理(单步执行probe指令, 并触发异常);
										### 2) 若注册pre_handler, 且pre_handler执行完毕返回0, 也继续走正常处理;
										### 3) 若注册pre_handler, 且pre_handler执行完毕返回非0, 则kprobes stops single stepping and just returns to the given address.
										###    This also means post_handler should not be called anymore.
										if (!p->pre_handler || !p->pre_handler(p, regs)) {
											setup_singlestep(struct kprobe *p = p, regs, kcb, int reenter = 0) {
												kcb->kprobe_status = KPROBE_HIT_SS
												
												if (p->ainsn.api.insn) {
													slot = (unsigned long)p->ainsn.api.insn
													kprobes_save_local_irqflag(kcb, regs) {			// <<<<<<<<<<  将regs->PSTATE中DAIF置1, 异常处理返回后, PSTATE寄存器的D、A、I、F标志位都设置为1, 即: 关中断 (kprobe_breakpoint_ss_handler处理完从异常返回时开中断)  >>>>>>>>>>
														kcb->saved_irqflag = regs->pstate & DAIF_MASK
														regs->pstate |= DAIF_MASK
													}
													instruction_pointer_set(regs, slot)				// PC寄存器设为register_kprobe时准备好的slot
														regs->pc = slot
												} else {
													/* insn simulation */
													arch_simulate_insn(p, regs) {
														struct kprobe_ctlblk *kcb = get_kprobe_ctlblk()
														
														if (p->ainsn.api.handler)
															p->ainsn.api.handler((u32)p->opcode, (long)p->addr, regs)
														
														/* single step simulated, now go for post processing */
														post_kprobe_handler(p, kcb, regs) {
															...
														}
													}
												}
											}
										} else 
											reset_current_kprobe()
												__this_cpu_write(current_kprobe, NULL)
									}
								}
							}
						}
					}
				}
			}
			arm64_exit_el1_dbg(regs)
		}
	}
}

4、第二次 BRK(KPROBES_BRK_SS_IMM)同步异常,触发后的处理流程

el1h_64_sync_handler(struct pt_regs *regs) {
	unsigned long esr = read_sysreg(esr_el1)
	switch (ESR_ELx_EC(esr)) {
		case ESR_ELx_EC_BRK64:
		el1_dbg(regs, esr) {
			arm64_enter_el1_dbg(regs)
			do_debug_exception(far, esr, regs) {
				const struct fault_info *inf = esr_to_debug_fault_info(esr)
					return debug_fault_info + DBG_ESR_EVT(esr)
				inf->fn(addr_if_watchpoint, esr, regs)
				A.K.A
				brk_handler {
					call_break_hook(regs, esr) { 		// <<<<< used for kprobes
						list = user_mode(regs) ? &user_break_hook : &kernel_break_hook
						list_for_each_entry_rcu(hook, list, node) {
							unsigned int comment = esr & ESR_ELx_BRK64_ISS_COMMENT_MASK
							if ((comment & ~hook->mask) == hook->imm)					// hook->imm: KPROBES_BRK_SS_IMM
								fn = hook->fn
						}
						
						return fn ? fn(regs, esr) : DBG_HOOK_ERROR
						A.K.A
						kprobe_breakpoint_ss_handler {					// ##### <<<< 执行观测指令后, 会先触发异常, 进到这里
							struct kprobe_ctlblk *kcb = get_kprobe_ctlblk()
							unsigned long addr = instruction_pointer(regs)
							struct kprobe *cur = kprobe_running()
							
							if (cur && (kcb->kprobe_status & (KPROBE_HIT_SS | KPROBE_REENTER)) &&
								((unsigned long)&cur->ainsn.api.insn[1] == addr)) {
								kprobes_restore_local_irqflag(kcb, regs)							// <<<<<<<<<< 将regs->pstate恢复成触发BRK(KPROBES_BRK_IMM)同步异常时的值, 本次异常处理返回后, 会将PSTATE寄存器内容恢复, 即: 开中断 (kprobe_breakpoint_handler处理完从异常返回时关中断) >>>>>>>>>>
								
								post_kprobe_handler(cur, kcb, regs) {
									/* return addr restore if non-branching insn */
									if (cur->ainsn.api.restore != 0)					// 将probe指令的下一条直接填到PC中, 这样从异常处理返回后就会继续执行probe指令的下一条
										instruction_pointer_set(regs, cur->ainsn.api.restore)
											regs->pc = cur->ainsn.api.restore
										
									/* restore back original saved kprobe variables and continue */
									if (kcb->kprobe_status == KPROBE_REENTER) {
										restore_previous_kprobe(kcb) {
											__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp)
											kcb->kprobe_status = kcb->prev_kprobe.status
										}
										return 
									}
									/* call post handler */
									kcb->kprobe_status = KPROBE_HIT_SSDONE
									if (cur->post_handler)
										cur->post_handler(cur, regs, 0)					// 调用用户注册的post_handler
									
									reset_current_kprobe()
										__this_cpu_write(current_kprobe, NULL)
								}
								
								return DBG_HOOK_HANDLED
							}
							/* not ours, kprobes should ignore it */
							return DBG_HOOK_ERROR
						}
					}
				}
			}
			arm64_exit_el1_dbg(regs)
		}
	}
}

以上就是 linux kprobe 的完整实现逻辑,感谢大伙的收看 !~

接下来将会陆续更新以下文章,敬请期待 ^_^

kretprobe详解、aggregative kprobe详解、reenter kprobe详解、kprobe跳转优化详解。

浅析Linux追踪技术之kprobe:基于kprobes的Event Tracing 常规的Event Tracing(事件追踪)是通过散落在Linux内核代码各处的Tracepoint来实现的,这些Tracepoint数量有限,在出现问题时,往往不能覆盖到要追踪的函数;而利用kprobes机制,则可以实现对所有支持kprobes插入的代码点进行追踪。这种方式是 kprobe 和 ftrace 结合使用,通过 kprobe 来优化 ftrace 来跟踪函数的调用。 阅读详情

相关推荐

告别连接难题:Windows 11下Multisim主数据库稳定运行终极配置指南

本文详细解析了Windows 11下Multisim 14.0主数据库连接失败的三大根源,并提供了四步终极解决方案,包括系统环境优化、软件权限配置、注册表修复和网络验证绕过技巧。通过实测数据对比,本方案显著提升了启动速度和稳定性,解决了电子仿真中的常见连接问题。

weixin_33738555的博客 423

Linux kprobe的使用

Linux kprobe的简单使用

小立仔 5331

保姆级教程:手把手教你用Python+Zemax仿真一个简易的Nd:YAG固体激光器谐振腔

本文提供了一份详细的Python与Zemax结合的Nd:YAG固体激光器谐振腔仿真教程。从基础理论到实战操作,涵盖晶体参数化、谐振腔设计、泵浦建模、动态仿真及热效应补偿等关键步骤,适合光学专业学生和工程师快速掌握激光器仿真技术。

weixin_30500473的博客 730

Linux kprobe原理

Linux kprobe原理,以及其优化简介

小立仔 3974

OI 生涯回忆录 《Pilgrimage》

前言 于 NOI2020 后写下本文。 本文简单提及了在写作时尚能回忆起来的,在我的 OI 生涯中对我的影响重大的人、事、比赛等。 写作本文,旨在在回忆允许的范围内,对 OI 生涯进行一定程度上的梳理,总结。 开端 入门 我最早接触计算机程序设计,是在小学。 那时候,我的数学成绩不错,就被老师推荐去学习编程。 就这样,我在局前街小学的何静老师的指导下,走上了编程的道路。 小学时的编程,与其说是 “竞赛” ,不如说是 “兴趣班” 。 当时,包括我在内,很多小孩子天性是浮躁的。支撑我对着无聊的代码学下去的,并不

cz_xuyixuan的博客 1万+

COMSOL电磁仿真案例——感应线圈

COMSOL电磁建模仿真案例——感应线圈

冲击10w 6万+

Linux内核调试技术之kprobes:基本原理与使用

Linux kprobes技术是一种可以跟踪内核函数执行状态的轻量级内核调试技术,利用kprobes技术可以在运行的内核中动态的插入探测点,当内核运行到该探测点后可以执行用户预定义的回调函数,以收集所需的调试状态信息而基本不影响内核原有的执行流程。{return 0;}.symbol_name = "do_fork", // 要追踪的内核函数为 do_fork.pre_handler = handler_pre // pre_handler 回调函数。

Aspiresky的专栏 3160

杰理芯片外挂Flash音乐播放功能避坑指南(附FAT文件系统配置)

本文详细解析了杰理芯片外挂Flash实现音乐播放功能的技术要点与常见问题,包括硬件连接、SPI驱动配置、FAT文件系统烧录及音乐播放集成等关键环节。特别针对Flash选型、FAT文件系统配置等易错点提供实用解决方案,帮助开发者高效完成嵌入式音频系统开发。

yhn45678901的博客 827

kprobe 原理详细分析

内核调试机制 kprobe 原理详细分析,使用 kprobe 可以在内核任意位置设置 hook 并跟踪调试

看我眼色行事的博客 1640

Spring Cloud 整合(一) CRUD

Springcloud 整合之 CRUDSpringcloud介绍功能概述为什么要选用Springcloud Springcloud介绍 功能概述 实现微服务 Spring Cloud为开发人员提供了工具,以快速构建分布式系统中的某些常见模式(例如,配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式会话,群集状态)。分布式系统的协调导致样板式样,并且使用Spring Cloud开发人员可以快速站起来实现这些样板的服务和应用程序。 为什么要选用Springcloud

Kerwin-Lin的博客 1491

基于企业微信客服与GPT-3构建合规微信AI助手:从原理到部署实践

在人工智能与即时通讯融合的浪潮中,自然语言处理(NLP)与API集成成为构建智能对话系统的核心技术。其原理在于通过API网关接收用户输入,调用云端大语言模型进行处理,再将结果返回给用户,实现自动化交互。这项技术的核心价值在于将前沿AI能力无缝嵌入到日常高频应用场景中,极大地提升了客服自动化、智能问答与个性化服务的效率与体验。企业微信作为官方认可的企服平台,其开放的客服API接口为开发者提供了稳定、合规的消息通道,是连接微信生态与外部AI服务的理想桥梁。本文聚焦于如何利用企业微信客服API与OpenAI的GP

weixin_28727943的博客 619

【原创】Linux kprobe 实现原理 图文详解 (二) kretprobe实现原理

目录 一、kretprobe 基本介绍 二、kretprobe 使用示例 三、kretprobe 实现原理 四、具体代码 (代码:linux 6.3.1,架构:arm64) One look is worth a thousand words. —— Tess Flanders 一、kretprobe 基本介绍 Kretprobe是一种基于Kprobe的探测技术,用于探测内核函数的入口点、返回点。在这两处可以调用用户注册的钩子函数,该技术一般用于获取:函数运行时间、函数返回

h_b__k的博客 2302

哨兵1号回波数据(L0级)包格式解析与成像参数提取

提取哨兵1号数据包的辅助数据、回波数据、定标数据。matlab代码在文末

3114

【原创】Linux kprobe 实现原理 图文详解 (四) 指令替换、cpu stopper

本文主要介绍kprobe指令替换的细节,并介绍cpu stopper机制的实现原理

h_b__k的博客 1571

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【原创】Linux kprobe 实现原理 图文详解 (三) kprobe跳转优化

图文详细介绍kprobe跳转优化的底层实现原理

h_b__k的博客 964

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Linux内核调试技术——kprobe使用与实现

Linux kprobes调试技术是内核开发者们专门为了便于跟踪内核函数执行状态所设计的一种轻量级内核调试技术。利用kprobes技术,内核开发人员可以在内核的绝大多数指定函数中动态的插入探测点来收集所需的调试状态信息而基本不影响内核原有的执行流程。

My Linux Journey 5万+

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

linux kprobe实现原理

linux kprobes kprobes出现了非常长的时间,最早是2.6.9版本中,最早能够追溯到2004年,距离现在15年,一直没有为人所知,但却是隐藏在诸多技术后的一个基础组件,例如ftrace,perf,SystemTap,LTTng还有最近非常火热的ebpf. kprobes是什么? 它是kernel probes(我翻译成探针),是一种debug机制,它是由IBM开发的,最初计划用来和...

faxiang1230的专栏 1830

kprobe实现原理解析

一、简介 kprobe是内核的动态探测工具,几乎可以探测任何一条内核指令。kprobe根据探测点类型可分为三种: kprobes, jprobes和kretprobes (也叫返回探测点)。 kprobes是可以被插入到内核的任何指令位置的探测点,jprobes则只能被插入到一个内核函数的入口,而kretprobes则是在指定的内核函数返回时才被执行。 kprobe...

hjkfcz的博客 3485

深入ftrace kprobe原理解析

至此,我们知道Kprobe实现的本质是breakpoint和single-step的结合,这一点和大多数调试工具一样,比如kgdb/gdb。当 kprobe 被注册后,内核会将对应地址的指令进行拷贝并替换为断点指令(比如 X86 中的int 3)随后当内核执行到对应地址时,中断会被触发从而执行流程会被重定向到我们注册的函数当对应地址的原始指令执行完后,内核会再次执行从而实现指令级别的内核动态监控。也就是说,kprobe 不仅可以跟踪任意带有符号的内核函数,也可以跟踪函数中间的任意指令。

奇小葩 5457

Linux内核调试利器|kprobe 原理与实现

本文主要介绍了 kprobe 的原理与实现,正如本文开始时所说,kprobe 机制的细节很多,所以本文不可能对所有细节进行分析。如果大家对 kprobe 的所有实现细节有兴趣,可以自行阅读源码。

weixin_60043341的博客 794

Linux Kprobe原理与应用

首先kprobe是最基本的探测方式,是实现后两种的基础,它可以在任意的位置放置探测点(就连函数内部的某条指令处也可以),它提供了探测点的调用前、调用后和内存访问出错3种回调方式,分别是pre_handler、post_handler和fault_handler,其中pre_handler函数将在被探测指令被执行前回调,post_handler会在被探测指令执行完毕后回调(注意不是被探测函数),fault_handler会在内存访问出错时被调用;2、一般情况下,可以探测内核中的任何函数,包括中断处理函数。

chi's blog 767

Linux内核调试技术——kprobe使用与实现(一)

;struct hlist_node hlist:被用于kprobe全局hash,索引值为被探测点的地址;struct list_head list:用于链接同一被探测点的不同探测kprobe;kprobe_opcode_t *addr:被探测点的地址;const char *symbol_name:被探测函数的名字;

嵌入式Linux内核的博客 961

kprobe 内核实现原理

kprobe内核实现原理代码分析

OS Developer的博客 663

分析kprobe原理

Linux kprobe原理分析

greenandblue的专栏 745
下一篇: 【原创】Linux kprobe 实现原理 图文详解 (二) kretprobe实现原理
码农hbk
博客等级 码龄9年 434粉丝 28原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值