匿名
未登录
登录
百问网嵌入式Linux wiki
搜索
查看“Ftrace”的源代码
来自百问网嵌入式Linux wiki
名字空间
页面
讨论
更多
更多
页面选项
Read
查看源代码
历史
←
Ftrace
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看与复制此页面的源代码。
=Ftrace= ==文章目的== : 本文提供了开始使用Linux内核工具所需的基本信息:ftrace [1 ]。 ==简介== : 下表简要介绍了该工具及其可用性,具体取决于软件包: * 是:该工具已经存在(可以使用或激活),也可以在软件包中集成和激活。 * 没有:该工具不存在且无法集成,或者存在但无法在软件包中激活。 {| class="wikitable" !colspan="3" | 工具 |- | 名称 | 类别 | 目的 |- |ftrace |追踪工具 |ftrace [1 ](函数跟踪程序)是功能强大的内核跟踪实用程序,例如,它可以跟踪每个内核函数调用和内核事件,而无需在内核源代码中添加任何额外的代码 没有 没有 是 没有 没有 是 |- !colspan="3" | STM32MPU嵌入式软件发行版 |- | 入门资料包 | 开发者资料包 | 发行版资料包 |- |没有 |没有 |是 |- !colspan="3" | 适用于 Android 的STM32MPU嵌入式软件发行版 |- | 入门资料包 | 开发者资料包 | 发行版资料包 |- |没有 |没有 |是 |} : 注意:在Linux内核4.1之前,所有ftrace跟踪控制文件都在debugfs文件系统中,该文件系统通常位于 /sys/kernel/debug/tracing 中。现在,它位于/ sys/kernel/tracing中,并且独立于debugfs。 : 为了向后兼容,在安装 debugfs 文件系统时,tracefs 文件系统会自动安装在: /sys/kernel/debug/tracing.。 : 位于tracefs文件系统中的所有文件也位于该debugfs文件系统目录中。 : {{redtext|请注意,符号表中存在的所有函数都可用于ftrace。要知道符号列表中是否有可用的函数,可以使用命令 "nm vmlinux | grep <function_name>"}} ==在目标板上安装跟踪和调试工具== : ftrace是一项内核功能,在OpenSTLinux发行版中默认情况下未启用,因为这会影响Linux内核大小(vmlinux大约增加1.5%),并且还会对整体性能产生影响,因为其触发了跟踪内核事件和函数调用。 : 为了使用ftrace所需的“内核功能跟踪程序” ,Linux内核配置必须使用Linux内核menuconfig工具激活 CONFIG_FUNCTION_TRACER 和 CONFIG_FUNCTION_GRAPH_TRACER 配置: <syntaxhighlight lang="bash"> Symbol: FUNCTION_TRACER Location: Kernel Hacking ---> Tracers --> [*] Kernel Function Tracer Symbol: FUNCTION_GRAPH_TRACER Location: Kernel Hacking ---> Tracers --> [*] Kernel Function Tracer [*] Kernel Function Graph Tracer </syntaxhighlight> ===使用STM32MPU嵌入式软件发行版=== ====开发人员软件包==== : 不建议使用Developer Package启用ftrace内核配置,因为所有外部模块需要重新编译(例如GPU STM32MP1的gcnano驱动程序),而Developer Package则无法实现,因为它不需要提供所有资料来源。 : 这就是为什么将此设置为“开发人员包”不支持的原因。 ====分发包==== : 启用所需的Linux内核配置 : 要在Linux内核配置中启用CONFIG_FUNCTION_TRACER和CONFIG_FUNCTION_GRAPH_TRACER,请参阅 [https://wiki.st.com/stm32mpu/wiki/Menuconfig_or_how_to_configure_kernel Menuconfig或如何配置内核] 一文,以获取有关在Distribution Package上下文中修改配置和重新编译Linux内核镜像的说明。 : 还必须重新编译不属于Linux内核源代码树的外部Linux内核模块(如果存在)。 : GPU STM32MP1的gcnano驱动程序示例: <syntaxhighlight lang="bash"> PC $> bitbake gcnano-driver-stm32mp </syntaxhighlight> : 重新构建完整的OpenSTLinux镜像,以便重新编译所有依赖项并具有正确的rootfs(包括外部Linux内核模块) <syntaxhighlight lang="bash"> PC $> bitbake st-image-weston </syntaxhighlight> : 注意:如前所述,启用ftrace配置时,未压缩的Linux内核镜像的大小会增加。 : 根据目标板的内存配置(在设备树中定义),内核镜像的增加可能与放置在其后的某些保留区域重叠。 : 在这种情况下,突出显示了编译错误。 : 如果此重叠影响很小(意味着某些功能不再起作用,但并不关键),则可以通过使用Linux内核Menuconfig工具(Menuconfig或如何配置内核)激活Linux内核配置CONFIG_SECTION_MISMATCH_WARN_ONLY来避免编译错误。) <syntaxhighlight lang="bash"> Symbol: SECTION_MISMATCH_WARN_ONLY Location: Kernel Hacking ---> Compile-time checks and compiler options --> [*] Make section mismatch errors non-fatal </syntaxhighlight> ===使用适用于 Android 的 STM32MPU 嵌入式软件发行版=== ====分发包==== : 启用所需的Linux内核配置 : 要在Linux内核配置中启用CONFIG_FUNCTION_TRACER和CONFIG_FUNCTION_GRAPH_TRACER,请参阅[https://wiki.st.com/stm32mpu/wiki/How_to_customize_kernel_for_Android 如何为Android定制内核] 一文,以获取有关修改配置的说明 : 在Android分发包中重新编译Linux内核镜像和模块。 <syntaxhighlight lang="bash"> PC $> build_kernel vmlinux -i PC $> build_kernel modules -i </syntaxhighlight> : 还必须重新编译不属于Linux内核源代码树的外部Linux内核模块(如果存在的话)。 GPU STM32MP1的gcnano驱动程序示例: <syntaxhighlight lang="bash"> PC $> build_kernel gpu -i </syntaxhighlight> : 重建完整的Android镜像,以便重新编译所有依赖关系并考虑Linux内核镜像和模块的新的预构建镜像: <syntaxhighlight lang="bash"> PC $> make -j </syntaxhighlight> : 注意:如前所述,启用ftrace配置时,未压缩的Linux内核镜像的大小会增加。 : 根据目标板的内存配置(在设备树中定义),内核镜像的增加可能会覆盖后面放置的一些保留区域。 : 在这种情况下,突出显示了编译错误。 : 如果此重叠影响很小(意味着某些功能不再起作用,但并不关键),则可以通过使用Linux内核Menuconfig工具激活Linux内核配置CONFIG_SECTION_MISMATCH_WARN_ONLY来绕过编译错误(如何为Android定制内核)) <syntaxhighlight lang="bash"> Symbol: SECTION_MISMATCH_WARN_ONLY Location: Kernel Hacking ---> Compile-time checks and compiler options --> [*] Make section mismatch errors non-fatal </syntaxhighlight> ==使用入门== ===在运行时使用ftrace=== : 首先,你需要从目标启用/激活 ftrace 功能。 : 目标启动并登录后,安装 tracefs: <syntaxhighlight lang="bash"> Board $> mount -t tracefs nodev /sys/kernel/tracing </syntaxhighlight> : 注意:以下信息与 Android 发行版有关 :: 需要启用root访问权限 :: 使用ADB Shell可以使用ADB链接: <syntaxhighlight lang="bash"> PC $> adb root PC $> adb shell Board $> ... </syntaxhighlight> :: 使用UART控制台shell: <syntaxhighlight lang="bash"> Board $> su Board $> ... </syntaxhighlight> : 在那一步,所有的"ftrace”功能都发生在文件系统目录路径 /sys/kernel/tracing 中。 : 要找出可用的跟踪器,只需在跟踪目录中放置 available_tracers 文件即可: <syntaxhighlight lang="bash"> Board $> cat /sys/kernel/tracing/available_tracers function_graph function nop </syntaxhighlight> : 内核构建配置可以添加更多的跟踪器。请参阅 深入学习 一节。 ===过滤器选项=== : 注意:{{redtext|ftrace使用函数/ graph_function过滤器,而不是驱动程序过滤器。因此,跟踪* myDriver *函数不会从myDriver跟踪myHelper函数。}} : 你可以使用以下命令获取可用的过滤器功能的列表: <syntaxhighlight lang="bash"> Board $> cat /sys/kernel/tracing/available_filter_functions </syntaxhighlight> ====功能跟踪器模式==== : 开始跟踪会话 <syntaxhighlight lang="bash"> Board $> echo 1 > /sys/kernel/tracing/tracing_on </syntaxhighlight> : 要启用函数跟踪器,只需将函数写入 current_tracer 文件。然后,你可以验证当前值: <syntaxhighlight lang="bash"> Board $> echo function > /sys/kernel/tracing/current_tracer Board $> cat /sys/kernel/tracing/current_tracer function </syntaxhighlight> <syntaxhighlight lang="bash"> Board $> cat /sys/kernel/tracing/trace | head -20 # tracer: function # # entries-in-buffer/entries-written: 144045/33695515 #P:2 # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | date-3591 [001] ...3 3278.796042: memblock_is_map_memory <-pfn_valid date-3591 [001] ...3 3278.796046: unlock_page <-filemap_map_pages date-3591 [001] ...3 3278.796051: alloc_set_pte <-filemap_map_pages date-3591 [001] ...3 3278.796053: add_mm_counter_fast <-alloc_set_pte date-3591 [001] ...3 3278.796055: page_add_file_rmap <-alloc_set_pte date-3591 [001] ...3 3278.796057: __sync_icache_dcache <-alloc_set_pte date-3591 [001] ...3 3278.796059: pfn_valid <-__sync_icache_dcache date-3591 [001] ...3 3278.796061: memblock_is_map_memory <-pfn_valid date-3591 [001] ...3 3278.796064: unlock_page <-filemap_map_pages </syntaxhighlight> : 要应用功能过滤器,你可以在 /sys/kernel/tracing/set_ftrace_filter 中设置值,然后检查跟踪的新内容: <syntaxhighlight lang="bash"> # Here we take the example with all uart functions Board $> echo "*uart*" > /sys/kernel/tracing/set_ftrace_filter # Clean the existing trace Board $> echo > /sys/kernel/tracing/trace # Display new trace content (in that case, please do some actions in the console to get some traces) Board $> cat /sys/kernel/tracing/trace | head -20 # tracer: function # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | sh-343 [000] .... 9313.041827: uart_ioctl <-tty_ioctl sh-343 [000] .... 9313.041855: uart_ioctl <-tty_ioctl sh-343 [000] .... 9313.041866: uart_chars_in_buffer <-tty_wait_until_sent sh-343 [000] .... 9313.041870: uart_wait_until_sent <-tty_wait_until_sent sh-343 [000] .... 9313.041875: uart_set_termios <-tty_set_termios sh-343 [000] .... 9313.041968: uart_write_room <-tty_write_room sh-343 [000] .... 9313.041974: uart_write <-n_tty_write sh-343 [000] d..1 9313.041979: __uart_start <-uart_write sh-343 [000] d..1 9313.041987: uart_write_wakeup <-stm32_transmit_chars sh-343 [000] d.h2 9313.042007: uart_write_wakeup <-stm32_transmit_chars sh-343 [000] d.h2 9313.042022: uart_write_wakeup <-stm32_transmit_chars </syntaxhighlight> : Linux文档ftrace [2 ]中提供了有关过滤选项和配置的更多信息。 : 要清空跟踪,请参阅段落 "擦除跟踪” : 要清除过滤器,以便再次记录所有功能: <syntaxhighlight lang="bash"> Board $> echo > /sys/kernel/tracing/set_ftrace_filter </syntaxhighlight> ====图形功能跟踪器模式==== : 开始跟踪会话: <syntaxhighlight lang="bash"> Board $> echo 1 > /sys/kernel/tracing/tracing_on </syntaxhighlight> : 要启用功能跟踪器,只需将function_graph写入current_tracer文件。然后,你可以验证当前值: <syntaxhighlight lang="bash"> Board $> echo function_graph > /sys/kernel/tracing/current_tracer Board $> cat /sys/kernel/tracing/current_tracer function_graph </syntaxhighlight> <syntaxhighlight lang="bash"> Board $> cat /sys/kernel/tracing/trace | head -20 # tracer: function_graph # # CPU DURATION FUNCTION CALLS # | | | | | | | 1) 1.015 us | _spin_lock_irqsave(); 1) 0.476 us | internal_add_timer(); 1) 0.423 us | wake_up_idle_cpu(); 1) 0.461 us | _spin_unlock_irqrestore(); 1) 4.770 us | } 1) 5.725 us | } 1) 0.450 us | mutex_unlock(); 1) + 24.243 us | } 1) 0.483 us | _spin_lock_irq(); 1) 0.517 us | _spin_unlock_irq(); 1) | prepare_to_wait() { 1) 0.468 us | _spin_lock_irqsave(); 1) 0.502 us | _spin_unlock_irqrestore(); 1) 2.411 us | } 1) 0.449 us | kthread_should_stop(); 1) | schedule() { </syntaxhighlight> : 要应用图形函数过滤器,可以在 /sys/kernel/tracing/set_graph_function 中设置值,然后检查跟踪的新内容: <syntaxhighlight lang="bash"> # Here we take the example with all uart functions Board $> echo "*uart*" > /sys/kernel/tracing/set_graph_function # Clean the existing trace Board $> echo > /sys/kernel/tracing/trace </syntaxhighlight> <syntaxhighlight lang="bash"> # Display the new trace content (in that case, please do some action in the console to get some traces) Board $> cat /sys/kernel/tracing/trace | head -20 # tracer: function_graph # # CPU DURATION FUNCTION CALLS # | | | | | | | 1) | uart_ioctl() { 1) 0.875 us | mutex_lock(); 1) 0.792 us | mutex_unlock(); 1) + 15.542 us | } 1) | uart_ioctl() { 1) 0.583 us | mutex_lock(); 1) 0.584 us | mutex_unlock(); 1) 9.792 us | } 1) | uart_chars_in_buffer() { 1) | _raw_spin_lock_irqsave() { 1) 0.667 us | preempt_count_add(); 1) 5.458 us | } 1) | _raw_spin_unlock_irqrestore() { 1) 0.583 us | preempt_count_sub(); 1) 5.000 us | } 1) + 19.459 us | } 1) 1.541 us | uart_wait_until_sent(); 1) | uart_set_termios() { 1) 0.583 us | mutex_lock(); 1) 0.583 us | mutex_unlock(); 1) + 10.291 us | } 1) | uart_write_room() { 1) | _raw_spin_lock_irqsave() { 1) 0.666 us | preempt_count_add(); 1) 5.333 us | } 1) | _raw_spin_unlock_irqrestore() { 1) 0.583 us | preempt_count_sub(); 1) 5.000 us | } 1) + 19.625 us | } 1) | uart_write() { 1) | _raw_spin_lock_irqsave() { 1) 0.625 us | preempt_count_add(); 1) 5.209 us | } 1) | __uart_start() { 1) | stm32_start_tx() { 1) | stm32_transmit_chars() { </syntaxhighlight> : 有关ftrace [2 ]的Linux文档,有关过滤选项和配置的更多信息。 : 要清空跟踪,请参阅段落 "擦除跟踪” : 要清除此特殊过滤器,以便再次记录所有功能: <syntaxhighlight lang="bash"> Board $> echo > /sys/kernel/tracing/set_graph_function </syntaxhighlight> ===缓冲区大小=== : 为每个CPU分配一个缓冲区。为了进行跟踪分析,你可以更改此缓冲区的大小(增加或减少)。 : 可以读取每个CPU的给定大小值,或总计(值以千字节为单位): <syntaxhighlight lang="bash"> # Per CPU Board $> cat /sys/kernel/tracing/buffer_size_kb 1411 or Board $> cat /sys/kernel/tracing/per_cpu/cpuX/buffer_size_kb 1411 </syntaxhighlight> <syntaxhighlight lang="bash"> # Total for all CPUs: combined size of all the trace buffers Board $> cat /sys/kernel/tracing/buffer_total_size_kb 2822 </syntaxhighlight> : 要更改该值({{redtext|请注意,跟踪缓冲区是在页面中分配的(内核用于分配的你存块,通常大小为4 KB)}}) <syntaxhighlight lang="bash"> # Same value for each CPU (here 1000*4096/1024=4000) Board $> echo 4000 > /sys/kernel/tracing/buffer_size_kb or # Change buffer size value for a specific CPU X (here 1000*4096/1024=4000) Board $> echo 4000 > /sys/kernel/tracing/per_cpu/cpuX/buffer_size_kb </syntaxhighlight> ===在启动时使用ftrace=== : 你可以从内核启动中使用ftrace,这对于调试启动问题非常有用。 : 为此,你必须使用内核命令行参数: :: - 如果要添加过滤器,则可选 {{redtext|ftrace}}以及{{redtext|ftrace_filter}}或{{redtext|ftrace_graph_filter}}。 ====使用STM32MPU嵌入式软件包==== : 例如,要修改内核bootargs,可以通过以下方式进行: :: 从Linux内核控制台挂载引导分区,然后使用vi编辑器更新extlinux.conf文件(请参见手册页[3 ]或简介页[4 ])。例如: <syntaxhighlight lang="bash"> Board $> mount /dev/mmcblk0p4 /boot # As example for SDCard boot on STM32MP15 Evaluation board, otherwise /boot/<bootdevice>_<platform>-<boardId>_extlinux/extlinux.conf Board $> vi /boot/mmc0_stm32mp157c-ev1_extlinux/extlinux.conf </syntaxhighlight> :: 通过添加ftrace参数来更新内核命令行: ::: - 功能跟踪器模式 <syntaxhighlight lang="bash"> root=/dev/mmcblk0p5 rootwait rw console=ttyS3,115200 ftrace=function ftrace_filter=*uart* </syntaxhighlight> ::: - function_graph追踪模式 <syntaxhighlight lang="bash"> root=/dev/mmcblk0p5 rootwait rw console=ttyS3,115200 ftrace=function_graph ftrace_graph_filter=*uart* </syntaxhighlight> :: 保存并退出文件更新,然后重新启动主板 :: 或者 :: 编辑来自microSD?卡的extlinux.conf文件(如果用作引导设备) : 注意:需要管理员权限 :: -将microSD卡插入主机PC :: -检查是否安装了引导分区(即 /media/$USER/bootfs) :: -编辑与你的设置相对应的extlinux文件(即 /media/$USER/bootfs/mmc0_stm32mp157c-ev1_extlinux/extlinux.conf) :: -按照所需的ftrace跟踪器配置修改命令行(请参见上文) :: -保存修改,然后将microSD卡插入目标 :: -引导并检查内核命令行 ====使用适用于Android的STM32MPU嵌入式软件包==== : 例如,要修改内核bootargs,可以通过以下方式来完成,这需要重建启动镜像: : 编辑文件 device/stm/<STM32Series>/<BoardId>/Boardconfig.mk : 通过在BOARD_KERNEL_CMDLINE变量中添加ftrace参数来更新内核命令行: :: - 功能跟踪器模式 <syntaxhighlight lang="bash"> ... # =========================================================== # # Kernel command line # # =========================================================== # BOARD_KERNEL_CMDLINE := console=ttySTM0,115200 androidboot.console=/dev/ttySTM0 consoleblank=0 earlyprintk BOARD_KERNEL_CMDLINE += skip_initramfs ro rootfstype=ext4 rootwait BOARD_KERNEL_CMDLINE += init=/init firmware_class.path=/vendor/firmware BOARD_KERNEL_CMDLINE += androidboot.hardware=stm BOARD_KERNEL_CMDLINE += ftrace=function ftrace_filter=*uart* ... </syntaxhighlight> :: - function_graph追踪模式 <syntaxhighlight lang="bash"> ... # =========================================================== # # Kernel command line # # =========================================================== # BOARD_KERNEL_CMDLINE := console=ttySTM0,115200 androidboot.console=/dev/ttySTM0 consoleblank=0 earlyprintk BOARD_KERNEL_CMDLINE += skip_initramfs ro rootfstype=ext4 rootwait BOARD_KERNEL_CMDLINE += init=/init firmware_class.path=/vendor/firmware BOARD_KERNEL_CMDLINE += androidboot.hardware=stm BOARD_KERNEL_CMDLINE += ftrace=function_graph ftrace_graph_filter=*uart* ... </syntaxhighlight> : 重建并重新加载启动镜像 ====检查跟踪==== : 引导后,要检查跟踪,必须先挂载tracefs: <syntaxhighlight lang="bash"> Board $> mount -t tracefs nodev /sys/kernel/tracing </syntaxhighlight> : 注意:以下信息与 Android 发行版有关 :: 需要启用root访问权限 :: 使用ADB Shell可以使用ADB链接: <syntaxhighlight lang="bash"> PC $> adb root PC $> adb shell Board $> ... </syntaxhighlight> :: 使用UART控制台shell: <syntaxhighlight lang="bash"> Board $> su Board $> ... </syntaxhighlight> : 然后查看跟踪内容(即函数跟踪): <syntaxhighlight lang="bash"> Board $> cat /sys/kernel/tracing/trace | head -20 # tracer: function # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | systemd-1 [000] .... 1.087213: uart_register_driver <-usart_init systemd-1 [000] .... 1.087847: uart_get_rs485_mode <-stm32_serial_probe systemd-1 [000] .... 1.088436: uart_add_one_port <-stm32_serial_probe systemd-1 [000] .... 1.098000: uart_parse_options <-stm32_console_setup systemd-1 [000] .... 1.098007: uart_set_options <-stm32_console_setup systemd-1 [000] .... 1.098014: uart_get_baud_rate <-stm32_set_termios systemd-1 [000] d..1 1.098019: uart_update_timeout <-stm32_set_termios systemd-1 [000] d..1 1.098090: uart_console_write <-stm32_console_write systemd-1 [000] d..1 1.105231: uart_console_write <-stm32_console_write systemd-1 [000] d..1 1.114697: uart_console_write <-stm32_console_write systemd-1 [000] d..1 1.120300: uart_console_write <-stm32_console_write </syntaxhighlight> ====捕获(从启动)oops到串行控制台==== : 在启动时启用ftrace的一个有趣的应用程序是通过在内核命令行上放置以下参数来捕获导致不稳定的函数调用: <syntaxhighlight lang="bash"> root=/dev/mmcblk0p5 rootwait rw console=ttyS3,115200 ftrace=function ftrace_dump_on_oops </syntaxhighlight> : 当发生oops时,ftrace缓冲区将自动转储到控制台消息中。 ===删除痕迹=== : 使用以下命令可以擦除ftrace的跟踪内容: <syntaxhighlight lang="bash"> Board $> echo > /sys/kernel/tracing/trace </syntaxhighlight> ==深入学习== ===为ftrace添加打印信息=== : 除了打印Linux内核功能之外,还可以使用trace_printk函数使用ftrace跟踪特定的调试信息。 : 它可以像printk()一样使用,也可以在任何上下文中使用(中断代码,NMI代码和调度程序代码)。 : trace_printk不会输出到控制台,但会写入ftrace环形缓冲区,并且可以通过跟踪文件读取。 : 要使用trace_printk函数,必须在源代码中包含linux/ftrace.h: <syntaxhighlight lang="bash"> ... #include <linux/ftrace.h> ... </syntaxhighlight> : 然后使用trace_printk语法作为printk(请参见以下示例): <syntaxhighlight lang="bash"> ... trace_printk("%s: %d uart_tx_stopped(port) %i\n", __FUNCTION__, __LINE__, uart_tx_stopped(port)); ... </syntaxhighlight> ===堆栈跟踪=== : 从内核文档中提取了ftrace [2 ]。 : 由于内核具有固定大小的堆栈,因此重要的是不要在功能上浪费它。内核开发人员必须知道函数在堆栈上分配了什么。如果它们增加太大的大小,则系统可能处于堆栈溢出的危险中,并且会发生损坏,通常会导致系统死机。 : 有一些工具可以检查此情况,通常使用中断定期检查其使用情况。但是,如果你可以在每个函数调用中执行检查,这将非常有用。由于ftrace提供了一个函数跟踪程序,因此可以方便地在每次函数调用时检查堆栈大小。这是通过堆栈跟踪器启用的。 : Linux内核配置选项CONFIG_STACK_TRACER启用ftrace堆栈跟踪功能。 <syntaxhighlight lang="bash"> Symbol: STACK_TRACER Location: Kernel Hacking ---> Tracers --> [*] Trace max stack </syntaxhighlight> : 要启用它,请将 '1' 写入 /proc/sys/kernel/stack_tracer_enabled 中。 <syntaxhighlight lang="bash"> Board $> echo 1 > /proc/sys/kernel/stack_tracer_enabled </syntaxhighlight> : 你还可以通过在内核命令行参数中添加"stacktrace”,在内核命令行中启用它以在启动过程中跟踪内核的堆栈大小。 <syntaxhighlight lang="bash"> root =/dev/mmcblk0p5 rootwait读写控制台= ttyS3,115200 stacktrace </syntaxhighlight> : 启动后,要检查跟踪,你必须先安装 tracefs,然后显示跟踪内容: <syntaxhighlight lang="bash"> Board $> mount -t tracefs nodev /sys/kernel/tracing Board $> cat /sys/kernel/tracing/stack_max_size 2928 Board $> cat /sys/kernel/tracing/stack_trace Depth Size Location (82 entries) ----- ---- -------- 0) 4328 4 __rcu_read_unlock+0x14/0x68 1) 4324 180 select_task_rq_fair+0x8ac/0xb7c 2) 4144 64 try_to_wake_up+0x100/0x3fc 3) 4080 16 wake_up_process+0x20/0x24 4) 4064 24 swake_up_locked.part.0+0x20/0x38 5) 4040 24 swake_up+0x38/0x48 6) 4016 16 rcu_gp_kthread_wake+0x4c/0x50 7) 4000 24 rcu_report_qs_rsp+0x50/0x84 8) 3976 120 rcu_report_qs_rnp+0x258/0x2ec 9) 3856 80 rcu_process_callbacks+0x290/0x43c 10) 3776 96 __do_softirq+0x12c/0x3ec 11) 3680 16 irq_exit+0xd0/0x118 12) 3664 48 __handle_domain_irq+0x90/0xfc 13) 3616 40 gic_handle_irq+0x5c/0xa0 14) 3576 68 __irq_svc+0x6c/0xa8 15) 3508 28 unwind_get_byte+0x20/0x74 16) 3480 160 unwind_frame+0x1a8/0x6b0 17) 3320 32 walk_stackframe+0x34/0x40 18) 3288 56 __save_stack_trace+0xa4/0xa8 19) 3232 16 save_stack_trace+0x30/0x34 20) 3216 72 create_object+0x120/0x278 21) 3144 40 kmemleak_alloc+0x8c/0xd4 22) 3104 64 kmem_cache_alloc+0x184/0x2f0 23) 3040 64 __kernfs_new_node+0x58/0x15c 24) 2976 24 kernfs_new_node+0x2c/0x48 25) 2952 24 __kernfs_create_file+0x28/0xb8 26) 2928 56 sysfs_add_file_mode_ns+0xc4/0x1a0 27) 2872 24 sysfs_create_file_ns+0x4c/0x58 28) 2848 56 kobject_add_internal+0x174/0x358 29) 2792 40 kobject_add+0x50/0x98 30) 2752 32 irq_sysfs_add+0x44/0x60 31) 2720 72 __irq_alloc_descs+0x174/0x234 32) 2648 48 irq_domain_alloc_descs+0x64/0xe4 33) 2600 56 irq_create_mapping+0x108/0x1fc 34) 2544 56 irq_create_fwspec_mapping+0x140/0x318 35) 2488 88 irq_create_of_mapping+0x5c/0x64 36) 2400 168 of_irq_get+0x68/0x78 37) 2232 24 stpmu1_regulator_parse_dt+0x68/0x80 38) 2208 96 regulator_register+0x218/0x970 39) 2112 32 devm_regulator_register+0x54/0x84 40) 2080 136 stpmu1_regulator_probe+0x350/0x5f4 41) 1944 32 platform_drv_probe+0x60/0xbc 42) 1912 64 driver_probe_device+0x2f4/0x488 43) 1848 32 __device_attach_driver+0xac/0x14c 44) 1816 40 bus_for_each_drv+0x54/0xa4 45) 1776 40 __device_attach+0xc0/0x150 46) 1736 16 device_initial_probe+0x1c/0x20 47) 1720 32 bus_probe_device+0x94/0x9c 48) 1688 64 device_add+0x3c0/0x5d0 49) 1624 16 of_device_add+0x44/0x4c 50) 1608 40 of_platform_device_create_pdata+0x84/0xb4 51) 1568 104 of_platform_bus_create+0x160/0x2f8 52) 1464 56 of_platform_populate+0x9c/0x134 53) 1408 32 stpmu1_probe+0x6c/0xac 54) 1376 40 i2c_device_probe+0x290/0x2dc 55) 1336 64 driver_probe_device+0x2f4/0x488 56) 1272 32 __device_attach_driver+0xac/0x14c 57) 1240 40 bus_for_each_drv+0x54/0xa4 58) 1200 40 __device_attach+0xc0/0x150 59) 1160 16 device_initial_probe+0x1c/0x20 60) 1144 32 bus_probe_device+0x94/0x9c 61) 1112 64 device_add+0x3c0/0x5d0 62) 1048 24 device_register+0x24/0x28 63) 1024 48 i2c_new_device+0x14c/0x2f4 64) 976 96 of_i2c_register_device+0x134/0x1dc 65) 880 40 of_i2c_register_devices+0x8c/0x100 66) 840 48 i2c_register_adapter+0x184/0x404 67) 792 48 i2c_add_adapter+0xa4/0x138 68) 744 160 stm32f7_i2c_probe+0x954/0xd08 69) 584 32 platform_drv_probe+0x60/0xbc 70) 552 64 driver_probe_device+0x2f4/0x488 71) 488 32 __driver_attach+0x110/0x12c 72) 456 40 bus_for_each_dev+0x5c/0xac 73) 416 16 driver_attach+0x2c/0x30 74) 400 48 bus_add_driver+0x1d0/0x274 75) 352 24 driver_register+0x88/0x104 76) 328 16 __platform_driver_register+0x50/0x58 77) 312 16 stm32f7_i2c_driver_init+0x24/0x28 78) 296 112 do_one_initcall+0x54/0x178 79) 184 72 kernel_init_freeable+0x1dc/0x274 80) 112 24 kernel_init+0x18/0x124 81) 88 88 ret_from_fork+0x14/0x24 </syntaxhighlight> ===更多示踪剂=== : 更多跟踪器可用于ftrace。请参阅Linux内核文档中的ftrace [2 ]。 {| class="wikitable" |- ! 跟踪器名称 !! 描述 |- |blk || 块跟踪器。blktrace用户应用程序 使用的跟踪器 |- |hwlat || 硬件延迟跟踪器。它用于检测硬件是否产生任何延迟 |- |irqsoff || 跟踪禁用中断的区域,并以最长的最大延迟保存跟踪 |- |preemptoff || 与irqsoff类似,但跟踪并记录禁用抢占的时间 |- |preemptirqsoff || 与irqsoff和preemptoff类似,但是跟踪并记录禁用irqs和/或抢占的最大时间 |- |wakeup || 跟踪并记录唤醒后优先级最高的任务安排所需的最大延迟 |- |wakeup_rt || 跟踪并记录仅RT任务所需的最大延迟(就像当前的“唤醒”一样) |- |wakeup_dl || 跟踪并记录唤醒SCHED_DEADLINE任务所需的最大延迟(如"wakeup”和"wakeup_rt”一样) |- |mmiotrace || 一种特殊的跟踪器,用于跟踪二进制模块。它跟踪模块对硬件的所有调用 |- |branch || 在跟踪内核中可能/不太可能发生的调用时可以配置此跟踪器 |- |nop || 这是“空的”追踪器 |} ===辅助工具=== : 尽管 [https://wiki.st.com/stm32mpu/wiki/Debugfs debugfs] 接口非常简单,但使用起来也很尴尬。建议使用一些工具来简化ftrace的用户体验。 * [https://wiki.st.com/stm32mpu/wiki/Trace-cmd_and_kernelshark_trace_viewer trace-cmd命令行阅读器和kernelshark跟踪查看器] :: trace-cmd是一种命令行工具,可以与ftrace配合使用并与之交互,而不是将命令回显到特定文件中并从另一个文件读取结果。它提出了一个高级用户命令界面来简化ftrace的使用。 :: 与trace-cmd相关联的kernelshark工具提出了一个跟踪查看器,可用于分析跟踪。 * [https://wiki.st.com/stm32mpu/wiki/LTTng Linux跟踪工具套件(LTTng)和Trace Compass查看器] :: LTTng是部分基于ftrace的Linux开源跟踪框架,该框架还通过命令行提出了高级用户界面。我们将主机PC端的Trace Compass与日志查看器关联。 ==参考== * 1. [https://elinux.org/Ftrace https://elinux.org/Ftrace] * 2. [https://github.com/STMicroelectronics/linux/blob/v4.19-stm32mp/Documentation/trace/ftrace.rst Documentation/trace/ftrace.rst] * 3. [http://ex-vi.sourceforge.net/vi.html http://ex-vi.sourceforge.net/vi.html] * 4. [http://ex-vi.sourceforge.net/viin/paper.html http://ex-vi.sourceforge.net/viin/paper.html] * 有用的外部链接 {| class="wikitable" |- ! 文件链接 !! 文件类型 !! 描述 |- | [https://www.kernel.org/doc/Documentation/trace/ftrace.txt ftrace(kernel.org文档)] || 标准 || Linux内核来源的文档 |- | [http://lwn.net/Articles/365835/ 使用Ftrace调试内核-第1部分] || 用户指南 || [http://lwn.net http://lwn.net] |- | [http://lwn.net/Articles/366796/ 使用Ftrace调试内核-第2部分] || 用户指南 || [http://lwn.net http://lwn.net] |- | [http://lwn.net/Articles/379903 使用TRACE_EVENT()宏(带有CREATE_TRACE_POINTS)] || 训练 || [http://lwn.net http://lwn.net] |- | [https://wiki.linaro.org/WorkingGroups/PowerManagement/Resources/Tools/load-perf-analyses#Using_ftrace 使用ftrace加载性能分析] || 用户指南 || Linaro |} [[Category:Linux_Operating_System]] [[Category:Linux_tracing_tools]]
该页面使用的模板:
模板:Redtext
(
查看源代码
)
返回至
Ftrace
。
导航
导航
WIKI首页
官方店铺
资料下载
交流社区
所有页面
所有产品
MPU-Linux开发板
MCU-单片机开发板
Linux开发系列视频
单片机开发系列视频
所有模块配件
Wiki工具
Wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志