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
    +关注

    关注

    88

    文章

    11814

    浏览量

    219534
  • 程序
    +关注

    关注

    117

    文章

    3848

    浏览量

    85461

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何理解Linux内核的PCIe驱动

    各异的芯片组,加上各种 PCI 设备自身独特的功能需求,Linux 内核的 PCI 支持远比我们希望的要复杂得多。今天这篇文章,我们将从驱动开发的视角,梳理 Linux PCI 设备驱动的核心生命周期与关键 API。
    的头像 发表于 04-11 17:22 1255次阅读

    Linux下扩充Swap交换空间:解决内存不足的实用指南,这些影响要注意!

    大家在使用 Linux 系统(比如常用的 Ubuntu)时,是不是偶尔会遇到 “内存不足” 的弹窗?比如运行大型编译任务、多开虚拟机、做数据分析,或者把 Linux 当服务器用的时候,物理内存一旦 “告急”,系统就会卡顿甚至崩溃
    的头像 发表于 02-09 16:33 516次阅读
    <b class='flag-5'>Linux</b>下扩充Swap交换<b class='flag-5'>空间</b>:解决内存不足的实用指南,这些影响要注意!

    Linux进程树分析工具pstree详解与实战指南(另一视角优化Linux系统)

    Linux 系统开发与运维,理解进程的运行状态和相互关系是排查问题、优化性能的基础。pstree 作为一款轻量高效的进程树可视化工具,能直观展示系统中所有进程的父子关系,为系统分析提供关键线索。本文将从基础用法到实战优化,
    的头像 发表于 02-04 16:21 893次阅读
    <b class='flag-5'>Linux</b>进程树<b class='flag-5'>分析</b>工具pstree详解与实战指南(另一视角优化<b class='flag-5'>Linux</b>系统)

    【「Linux 设备驱动开发(第 2 版)」阅读体验】+读深入理解Linux内核内存分配

    每个内存地址是虚拟的,不是直接指向RAM的任何地址。当用户访问内存的存储单元时,都会进行地址转换以匹配相应的物理内存。书籍的第10章讨论了五个主题,对Linux内核内存分配进行详细
    发表于 01-16 20:05

    利用拼多多用户API进行粉丝数据分析,有效提升用户粘性

    ​ 在电商运营,理解并维系核心用户群体至关重要。拼多多开放平台提供的用户API,特别是与粉丝数据相关的接口,为商家深入分析粉丝行为、精准运营、提升
    的头像 发表于 12-30 10:38 367次阅读
    利用拼多多<b class='flag-5'>用户</b>API进行粉丝数据<b class='flag-5'>分析</b>,有效提升<b class='flag-5'>用户</b>粘性

    如何在Linux列出USB设备

    Electronics Co., Ltd ... 这些命令将帮助你轻松列出Linux系统连接的USB设备,以及获取相关信息。安装相应的工具来执行这些命令,你将能够更好地管理和调试USB设备。无论是普通用户,还是系统管理员,都
    发表于 12-24 08:19

    解析Linux的进程、线程和协程

    )进程间通信(IPC):Linux提供了多种IPC机制,如管道、信号、共享内存和消息队列,用于进程之间的通信。 线程管理 在Linux,线程可以通过pthread库来管理。线程共享同
    发表于 12-22 11:00

    请问如何利用 Keil 分析 MCU 堆栈空间

    如何利用 Keil 分析 MCU 堆栈空间
    发表于 11-26 07:38

    探索操作系统底层的关键接口

      在linux,将程序的运行空间分为内核空间用户空间(内核态和
    的头像 发表于 11-08 12:42 870次阅读

    深入了解系统调用API:探索操作系统底层的关键接口

    一、前言 为什么用户程序不能直接访问系统内核模式提供的服务? 在linux,将程序的运行空间分为内核空间
    的头像 发表于 11-03 09:20 867次阅读

    linux系统,通过I2C和CCG5通讯,有没有和CCG5通过I2C进行固件升级?状态配置的有没有可以参考的源代码?

    linux系统,通过I2C和CCG5通讯,有没有和CCG5通过I2C进行固件升级,状态配置的 有没有可以参考的源代码? 固件升级是在linux kernel里面实现 还是在用户
    发表于 07-17 06:59

    Linux嵌入式和单片机嵌入式的区别?

    、可定制性、开放源代码、良好的兼容性、强大的网络支持、多任务支持、丰富的软件生态系统。 架构:应用程序运行在用户空间,硬件访问和控制通常在内核空间的驱动层实现。 运行芯片:通常称为M
    发表于 06-20 09:46

    Linux系统管理的核心概念

    在前一篇文章,我们深入探讨了Linux的文件操作命令,如cp、mv、rm,以及文本处理命令grep、wc和管道符。本文将继续深入Linux系统管理的核心概念,包括root
    的头像 发表于 05-15 17:05 823次阅读

    Linux主要的性能有哪些?

      什么是Linux?   Linux是一套自由传播的类Unix操作系统,是一个基于posix和unix的多用户、多任务、支持多线程和多cpu的操作系统。它的基本思想有两点,一切都是文件和每个软件
    的头像 发表于 04-30 18:09 765次阅读
    <b class='flag-5'>Linux</b>主要的性能有哪些?

    Linux系统用户权限详解

    Linux 是一种开源的、基于 Unix 的操作系统,它因其灵活性、稳定性和高性能而广泛应用于服务器、嵌入式系统、超级计算机、桌面计算等领域。
    的头像 发表于 04-25 10:56 1076次阅读
    <b class='flag-5'>Linux</b>系统<b class='flag-5'>用户</b>权限详解