内核ftrace的实现

在动态ftrace原理中已经介绍了内核通过gcc -pg -fentry为函数增加5 Byte的stub,系统启动后这5 Byte被修改为NOP指令:66 66 66 66 90H。

开始trace时要将NOP指令修改为跳转指令,去执行各种trace对应的hook函数。function trace对应的hook函数就是function_trace_call。

本文将会介绍内核是如何修改代码段以控制函数去执行指定的hook函数。

运行时修改代码段

系统运行时修改代码段是一个很危险的操作,因为被修改的5 Byte有可能跨两个cache line,如果其它Core正在执行,有可能取到被修改了一半的结果,导致系统crash。

ftrace修改代码段是在ftrace_replace_code中完成的,这个函数里有三个大循环

  • add_breakpoints: 首先找到需要trace的函数,将第一个字节修改为0xCC,即int 3(也叫break指令)
  • add_update: 修改为callq trampoline指令,但是第一个字节保留为0xCC
  • finish_update: 将0xCC修改为0xE8,即为call指令
# echo expand_files > set_ftrace_filter
# echo function > current_tracer 

以上面的操作举例,配置ftrace跟踪expand_files函数,该函数前5 Byte变化如下面所示:

0xffffffff8114aae0 <expand_files>: 
66 66 66 66 90H        <-- NOP
    |
    |
    V
CC 66 66 66 90H        <-- int 3
    |
    |
    V
CC 1b 55 eb 1eH        <-- 跳转的偏移已经修改好了,但opcode还是int 3
    |
    |
    V
e8 1b 55 eb 1eH        <-- callq  0xffffffffa0000000

内核在修改代码段时先将第一个Byte修改为0xCC,如果有其它Core执行到这里会触发异常,但是在int 3异常处理程序中直接返回并再次触发异常,直至int 3被修改为call指令后才跳出循环

dotraplinkage void notrace do_int3(struct pt_regs *regs, long error_code)
{
#ifdef CONFIG_DYNAMIC_FTRACE
    /*
     * ftrace must be first, everything else may cause a recursive crash.
     * See note by declaration of modifying_ftrace_code in ftrace.c
     */
    if (unlikely(atomic_read(&modifying_ftrace_code)) &&
        ftrace_int3_handler(regs))
        return;
#endif
    
    ...

跳转目标

前面说到trace的原理是修改函数开始的5 Byte,让其先去执行指定的hook函数。不同的tracer有不同的hook函数,function tracer的hook函数是function_trace_call,这个函数的功能比较简单,只是向ring buffer中记录了ip和parent_ip

内核提供了<font color=cornflowerblue>.ftrace_caller</font>和<font color=cornflowerblue>.ftrace_regs_caller</font>两段汇编代码作为wrapper,用来完成保存/恢复寄存器等通用的工作,其中的<font color=cornflowerblue>call ftrace_stub</font >会被修改为各种tracer对应的hook function

ENTRY(ftrace_caller)
    /* save_mcount_regs fills in first two parameters */
    save_mcount_regs

GLOBAL(ftrace_caller_op_ptr)
    /* Load the ftrace_ops into the 3rd parameter */
    movq function_trace_op(%rip), %rdx

    /* regs go into 4th parameter (but make it NULL) */
    movq $0, %rcx

GLOBAL(ftrace_call)
    call ftrace_stub

    restore_mcount_regs

GLOBAL(ftrace_caller_end)

GLOBAL(ftrace_return)

#ifdef CONFIG_FUNCTION_GRAPH_TRACER
GLOBAL(ftrace_graph_call)
    jmp ftrace_stub
#endif

GLOBAL(ftrace_stub)
    retq
END(ftrace_caller)

但是内核也没有直接调用<font color=cornflowerblue>.ftrace_caller</font>和<font color=cornflowerblue>.ftrace_regs_caller</font>,而是在内存中构造了一个trampoline,将<font color=cornflowerblue>.ftrace_caller</font>拷贝到这段trampoline中,并修改其中的相对偏移。

多个tracer同时工作

未完待续

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容