0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux中ftracer用于用户空间分析

Linux阅码场 来源:相遇Linux 作者:相遇Linux 2021-03-10 15:33 次阅读

gcc4.6 添加了一个编译选项 -mfentry, 当程序编译之后,程序中的所有函数,除了notrace属性

#define notrace __attribute__((no_instrument_function))

的函数头上都会添加上call __fentry__,占用5个字节,__fentry__函数在程序中可以自定义, 比如在Linux kernel中被定义为 retq直接返回。

SYM_FUNC_START(__fentry__)

retq

SYM_FUNC_END(__fentry__)

定义成retq的意思是我不想直接使用__fentry__, 其实现也是在内核启动的时候把__fentry__换成了nopl, 然后在需要trace内核函数时,再替换成对应的trampoline(中文: 蹦床)。

本篇讲解ftrace(function trace)在用户空间的应用。

以下代码来自此git工程:

https://github.com/x-lugoo/ftracer.git

ftracer.c中对__fentry__函数进行了自定义:

ftracer.c

asm(

“ .globl __fentry__

“__fentry__:

/* save arguments */

“ push %rax

“ push %rdi

“ push %rsi

“ push %rdx

“ push %rcx

“ push %r8

“ push %r9

“ movq %rsp,%rdi

“ call ftracer

“ pop %r9

“ pop %r8

“ pop %rcx

“ pop %rdx

“ pop %rsi

“ pop %rdi

“ pop %rax

“ ret

”);

上面__fentry__函数的实现把所有传参寄存器(x86_64架构)全部压栈,然后把sp指针传给ftracer()的第一个参数

__attribute__((used)) void ftracer(struct frame *fr)

{

if (!tenabled)

return;

struct trace *t = &tbuf[tcur++];

if (tcur 》= TSIZE)

tcur = 0;

t-》tstamp = __builtin_ia32_rdtsc();

t-》src = fr-》caller;

t-》dst = fr-》callee;

t-》arg1 = fr-》rdi;

t-》arg2 = fr-》rsi;

t-》arg3 = fr-》rdx;

}

struct frame {

uint64_t r9;

uint64_t r8;

uint64_t rcx;

uint64_t rdx;

uint64_t rsi;

uint64_t rdi;

uint64_t rax;

uint64_t callee;

uint64_t caller;

};

其中callee是被调用函数地址,caller是调用函数地址 ,比如f1()调用f2(), f2函数头上调用了__fentry__, 那么__fentry__ 就可以从frame结构中的rax变量地址之后找到callee和caller

f1() {

call f2

f2() {

call __fentry__

ftracer()的实现把函数调用参数,被调用函数,调用函数,函数执行时间戳都存在tbuf中

使用一个测试程序验证ftrace功能:

test.c

#include “ftracer.h”

#define mb() asm volatile (“” ::: “memory”)

void f3(int a, int b, int c)

{

mb();

}

void f2(int a, int b, int c)

{

f3(4, 5, 6);

}

void f1(int a, int b, int c)

{

f2(7, 8, 9);

}

main()

{

ftrace_dump_at_exit(0);

ftrace_enable();

f1(1, 2, 3);

}

函数调用关系:main-》f1-》f2-》f3

编译:

gcc -c ftracer.cgcc -pg -mfentry ftracer.o test.c -o test

执行。/test的时候调用ftrace_dump(), 打印出tbuf中的数据,

void ftrace_dump(unsigned max)

t = &tbuf[i];

printf(“%llx %llx-》%llx %llx %llx %llx

”,

t-》tstamp,

t-》src, t-》dst,

t-》arg1, t-》arg2, t-》arg3);

tbuf中包含函数调用关系和函数执行时时间戳:

。/test

2b4fcfe84137ab 4008d1-》400893 4 5 6 (f2-》f3)

2b4fcfe8413763 4008fe-》4008ac 7 8 9 (f1-》f2)

2b4fcfe84136ee 40092d-》4008d9 1 2 3 (main-》f1)

以上函数调用关系对应各个函数代码段:

function f2:

0x00000000004008a7 《+0》: callq 0x400657 《__fentry__》

0x00000000004008ac 《+5》: push %rbp

0x00000000004008ad 《+6》: mov %rsp,%rbp

0x00000000004008cc 《+37》: callq 0x40088e 《f3》

0x00000000004008d1 《+42》: nop

0x00000000004008d2 《+43》: leaveq

0x00000000004008d3 《+44》: retq

function f3:

0x000000000040088e 《+0》: callq 0x400657 《__fentry__》

0x0000000000400893 《+5》: push %rbp

0x00000000004008a6 《+24》: retq

function f1

0x00000000004008d4 《+0》: callq 0x400657 《__fentry__》

0x00000000004008d9 《+5》: push %rbp

0x00000000004008f4 《+32》: mov $0x7,%edi

0x00000000004008f9 《+37》: callq 0x4008a7 《f2》

0x00000000004008fe 《+42》: nop

0x00000000004008ff 《+43》: leaveq

0x0000000000400900 《+44》: retq

function main

0x0000000000400901 《+0》: callq 0x400657 《__fentry__》

0x0000000000400928 《+39》: callq 0x4008d4 《f1》

0x000000000040092d 《+44》: mov $0x0,%eax

0x0000000000400932 《+49》: pop %rbp

0x0000000000400933 《+50》: retq

总结:以上分析了ftracer用于用户空间,可以跟踪函数调用参数和函数执行时间戳。

小编最新一直被催更微信公众号文章,我最近一直在设计优化tracer视频课程,内容已经迭代了四五次了,希望到时候能通俗易懂、图文并茂地讲解Linux内核中function tracer /function graph/ kprobe/kretprobe/trace event 的最底层原理和应用,预期三月下旬发布。

掌握之后将对Linux kernel的研究学习方式和debug方式带来很大的帮助,big picture 如下图所示:

原文标题:当ftrace用于用户空间

文章出处:【微信公众号:Linuxer】欢迎添加关注!文章转载请注明出处。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11199

    浏览量

    208691
  • 程序
    +关注

    关注

    116

    文章

    3754

    浏览量

    80738

原文标题:当ftrace用于用户空间

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux系统shell命令解析

    shell是Linux系统的用户界面,提供了用户与内核交互的一种接口,它接收用户输入的命令并到送到内核去执行,因此也被称为Linux的命令解
    的头像 发表于 11-05 15:40 92次阅读

    Linux用户管理详解

    用户分为普通用户和超级用户,超级用户在Windows系统为Administrator在Linux
    的头像 发表于 11-01 09:48 83次阅读

    详解linux内核的uevent机制

    linux内核,uevent机制是一种内核和用户空间通信的机制,用于通知用户
    的头像 发表于 09-29 17:01 349次阅读

    linux驱动程序运行在什么空间

    空间拥有对硬件的直接访问权限,而用户空间则受到限制,以保护系统的稳定性和安全性。 1. Linux 内核和驱动程序概述 Linux 内核是操
    的头像 发表于 08-30 14:37 264次阅读

    高质量激光光束光学系统空间滤波

    空间滤波是光学的一项关键技术,用于细化激光束,提高其质量,并最大限度地减少像差和不必要的衍射效应。通过采用透镜和光阑的组合,空间滤波选择性地从激光束中去除不想要的成分,例如噪声、衍射
    发表于 08-14 11:54

    stm8l051的bootrom空间怎么用来做bootloader?

    stm8l051有一块bootrom空间(define region BootROM = [from 0x6000 to 0x67FF];), 这块空间是开放给用户的吗,开放的话怎么
    发表于 05-08 06:27

    gis空间分析包括哪些内容

    GIS(地理信息系统)空间分析是指通过使用GIS软件和方法,对地理空间数据进行处理、分析、建模和展示的过程。它结合了地理学、数学、计算机科学和统计学的原理和方法,在解决地理问题和支持决
    的头像 发表于 02-25 13:50 1610次阅读

    gis中常用的空间分析方法

    GIS中常用的空间分析方法 GIS(地理信息系统)是一种用于收集、存储、处理、分析和展示地理数据的技术。空间
    的头像 发表于 02-25 13:44 4814次阅读

    arcgis空间分析方法有哪些

    (Spatial Query):通过定义空间关系,如邻近、包含、相交等,来检索满足条件的要素。 缓冲区分析(Buffer Analysis):创建一定距离范围内的缓冲区,用于分析要素的
    的头像 发表于 02-25 11:36 2127次阅读

    Linux系统的FBE实现方案和特点

    方案和特点,后续章节会以eCryptfs为例做详细分析。 FUSE-Based FUSE即Filesystem in Userspace,用户态文件系统。FUSE设计初衷就是为方便用户不修改编译
    的头像 发表于 11-29 11:23 982次阅读
    <b class='flag-5'>Linux</b>系统<b class='flag-5'>中</b>的FBE实现方案和特点

    如何在Ubuntu Linux上释放/boot分区空间

    在Ubuntu Linux上,/boot分区是用于存储启动相关的文件的。随着时间的推移,这个分区可能会变满,导致系统无法安装新的内核和更新。本文将介绍如何释放/boot分区空间,并
    的头像 发表于 11-28 10:04 818次阅读

    Linux把目录权限给指定用户

    Linux是一个开放源代码的操作系统,它基于Unix的设计原则,提供了丰富的权限管理功能,允许用户对系统的文件和目录进行精确的控制。在Linux
    的头像 发表于 11-23 10:30 7896次阅读

    linux修改用户名的命令

    Linux修改用户名可以使用用户管理命令usermod来执行,下面将详细介绍如何修改Linux系统
    的头像 发表于 11-17 09:42 2308次阅读

    Linux 内存管理总结

    一、Linux内存管理概述 Linux内存管理是指对系统内存的分配、释放、映射、管理、交换、压缩等一系列操作的管理。在Linux,内存被划分为多个区域,每个区域有不同的作用,包括内核
    的头像 发表于 11-10 14:58 484次阅读
    <b class='flag-5'>Linux</b> 内存管理总结

    Linux perf 简要介绍

    的性能剩余工具,它可以在Linux系统上检测和调试各种性能问题。Linux内核集成了perf工具,可用于探测内核性能事件、硬件性能计数器以及用户级应用程序性能事件。 perf工具可以
    的头像 发表于 11-09 17:06 762次阅读