可靠的堆栈跟踪 【ChatGPT】

简介: 可靠的堆栈跟踪 【ChatGPT】

可靠的堆栈跟踪

本文档概述了关于可靠的堆栈跟踪的基本信息。

1. 介绍

内核热补丁一致性模型依赖于准确识别可能具有活动状态的函数,因此可能不安全进行补丁。识别哪些函数是活动的一种方法是使用堆栈跟踪。

现有的堆栈跟踪代码可能并不总是准确反映所有具有活动状态的函数,而对于调试有帮助的尽力而为的方法对于热补丁是不可靠的。热补丁依赖于体系结构提供可靠的堆栈跟踪,以确保它从跟踪中永远不会省略任何活动函数。

2. 要求

体系结构必须实现可靠的堆栈跟踪函数之一。使用 CONFIG_ARCH_STACKWALK 的体系结构必须实现 'arch_stack_walk_reliable',其他体系结构必须实现 'save_stack_trace_tsk_reliable'。

主要地,可靠的堆栈跟踪函数必须确保:

  • 跟踪包括任务可能返回到的所有函数,并且返回代码为零以指示跟踪是可靠的。
  • 返回代码为非零以指示跟踪不可靠。

注意: 在某些情况下,省略特定函数是合法的,但必须报告所有其他函数。这些情况在下面进一步详细描述。

其次,可靠的堆栈跟踪函数必须能够应对堆栈或其他展开状态损坏或不可靠的情况。该函数应尝试检测这种情况并返回非零错误代码,并且不应陷入无限循环或以不安全的方式访问内存。具体情况在下面进一步详细描述。

3. 编译时分析

为了确保内核代码在所有情况下都能正确展开,体系结构可能需要验证代码是否按照展开器所期望的方式进行了编译。例如,展开器可能期望函数以有限的方式操作堆栈指针,或者所有函数使用特定的序言和结语序列。具有这些要求的体系结构应使用 objtool 验证内核编译。

在某些情况下,展开器可能需要元数据才能正确展开。必要时,应在构建时使用 objtool 生成这些元数据。

4. 考虑因素

展开过程在各种体系结构、它们各自的过程调用标准和内核配置中有所不同。本节描述了体系结构应考虑的常见细节。

4.1. 识别成功终止

展开可能因多种原因提前终止,包括:

  • 堆栈或帧指针损坏。
  • 对于不常见情况缺少展开支持,或者展开器中的错误。

为确保这不会导致函数被从跟踪中省略,即使未被其他检查捕获,强烈建议体系结构验证堆栈跟踪是否在预期位置结束,例如:

  • 在作为内核入口点的特定函数内。
  • 在作为内核入口点的预期堆栈上的特定位置。
  • 在作为内核入口点的预期堆栈上的特定堆栈上(例如,如果体系结构具有单独的任务和中断请求(IRQ)堆栈)。

4.2. 识别可展开的代码

展开通常依赖于遵循特定约定的代码(例如,操作帧指针),但可能存在不遵循这些约定的代码,可能需要展开器进行特殊处理,例如:

  • 异常向量和入口汇编。
  • 过程链接表(PLT)条目和装饰函数。
  • 跳板汇编(例如,ftrace,kprobes)。
  • 动态生成的代码(例如,eBPF,optprobe 跳板)。
  • 外部代码(例如,EFI 运行时服务)。

为确保这些情况不会导致函数被从跟踪中省略,强烈建议体系结构积极识别已知可靠展开的代码,并拒绝从所有其他代码进行展开。

内核代码包括模块和 eBPF 可以使用 '__kernel_text_address()' 区分外部代码。检查这一点还有助于检测堆栈损坏。

体系结构可以通过几种方式识别被视为不可靠展开的内核代码,例如:

  • 将此类代码放入特殊的链接器部分,并拒绝从这些部分中的任何代码进行展开。
  • 使用边界信息识别代码的特定部分。

4.3. 跨中断和异常的展开

在函数调用边界处,堆栈和其他展开状态预期处于适合可靠展开的一致状态,但在函数的执行过程中可能不是这样。例如,在函数序言或结语期间,帧指针可能是瞬时无效的,或者在函数体内,返回地址可能保存在任意通用寄存器中。对于某些体系结构,这可能会在运行时由于动态插装的结果而发生变化。

如果在堆栈或其他展开状态处于不一致状态时发生中断或其他异常,可能无法可靠展开,并且可能无法确定此类展开是否可靠。请参见下文的示例。

无法确定何时可以可靠展开这些情况(或者永远不可靠)的体系结构必须拒绝跨异常边界进行展开。请注意,跨某些异常(例如,IRQ)进行展开可能是可靠的,但跨其他异常(例如,NMI)进行展开可能是不可靠的。

可以确定何时可以可靠展开这些情况(或者没有这些情况)的体系结构应尝试跨异常边界进行展开,因为这样可以防止不必要地阻塞热补丁一致性检查,并且可以使热补丁转换更快地完成。

4.4. 重写返回地址

一些跳板临时修改函数的返回地址,以便在函数返回时拦截该函数的返回到一个返回跳板,例如:

  • ftrace 跳板可能会修改返回地址,以便函数图跟踪可以拦截返回。
  • kprobes(或 optprobes)跳板可能会修改返回地址,以便 kretprobes 可以拦截返回。

当发生这种情况时,原始返回地址将不在其通常位置。对于不受热补丁影响的跳板,如果展开器能够可靠确定原始返回地址,并且跳板未改变任何展开状态,则展开器可以报告原始返回地址代替跳板,并将其报告为可靠。否则,展开器必须将这些情况报告为不可靠。

在识别原始返回地址时需要特别小心,因为这些信息在入口跳板或返回跳板的持续时间内不在一致的位置。例如,考虑 x86_64 的 'return_to_handler' 返回跳板:

SYM_CODE_START(return_to_handler)
        UNWIND_HINT_UNDEFINED
        subq  $24, %rsp
        /* Save the return values */
movq %rax, (%rsp)
movq %rdx, 8(%rsp)
movq %rbp, %rdi
call ftrace_return_to_handler
movq %rax, %rdi
movq 8(%rsp), %rdx
movq (%rsp), %rax
        addq $24, %rsp
        JMP_NOSPEC rdi
SYM_CODE_END(return_to_handler)

当被跟踪的函数运行时,其返回地址指向返回跳板的开始,并且原始返回地址存储在任务的 cur_ret_stack 中。在此期间,展开器可以使用 ftrace_graph_ret_addr() 找到返回地址。

当被跟踪的函数返回到 return_to_handler 时,堆栈上不再有返回地址,尽管原始返回地址仍存储在任务的 cur_ret_stack 中。在 ftrace_return_to_handler() 中,原始返回地址从 cur_ret_stack 中移除,并在返回到 rax 之前由编译器任意移动。return_to_handler 跳板将其移动到 rdi,然后跳转到它。

体系结构可能无法始终展开此类序列,例如当 ftrace_return_to_handler() 已从 cur_ret_stack 中移除地址,并且无法可靠确定返回地址的位置时。

建议体系结构展开尚未返回到 return_to_handler 的情况,但不要求从 return_to_handler 中间进行展开,并且可以将其报告为不可靠。体系结构不需要从其他修改返回地址的跳板进行展开。

4.5. 返回地址的遮蔽

一些跳板不会重写返回地址以拦截返回,但会瞬时破坏返回地址或其他展开状态。

例如,optprobes 的 x86_64 实现会使用 JMP 指令对被探测的函数进行修补,该指令将目标定向到相关的 optprobe 跳板。当触发探测时,CPU 将分支到 optprobe 跳板,并且被探测函数的地址不会保存在任何寄存器或堆栈中。

类似地,DYNAMIC_FTRACE_WITH_REGS 的 arm64 实现会对被跟踪的函数进行以下修补:

MOV X9, X30
BL <trampoline>

MOV 将链接寄存器(X30)保存到 X9 中以保存返回地址,然后 BL 会破坏链接寄存器并跳转到跳板。在跳板的开始处,被跟踪函数的地址在 X9 中,而不是通常情况下的链接寄存器中。

体系结构必须确保展开器能够可靠展开这些情况,或者将展开报告为不可靠。

4.6. 链接寄存器的不可靠性

在一些其他体系结构上,'call' 指令将返回地址放入链接寄存器,并且 'return' 指令从链接寄存器中获取返回地址而不修改寄存器。在这些体系结构上,软件必须在进行函数调用之前将返回地址保存到堆栈中。在函数调用的持续时间内,返回地址可能仅保存在链接寄存器中、仅保存在堆栈中,或者同时保存在这两个位置。

展开器通常假定链接寄存器始终是活动的,但这一假设可能导致不可靠的堆栈跟踪。例如,考虑以下简单函数的 arm64 汇编:

function:
        STP X29, X30, [SP, -16]!
MOV X29, SP
BL <other_function>
        LDP X29, X30, [SP], #16
RET

在函数入口时,链接寄存器(x30)指向调用者,并且帧指针(X29)指向调用者的帧,包括调用者的返回地址。前两条指令创建一个新的堆栈帧并更新帧指针,在这一点上,链接寄存器和帧指针都描述了这个函数的返回地址。此时的跟踪可能会描述这个函数两次,如果正在跟踪函数返回,展开器可能会从 fgraph 返回堆栈中消耗两个条目而不是一个条目。

BL 调用 'other_function' 时,链接寄存器指向这个函数的 LDR,并且帧指针指向这个函数的堆栈帧。当 'other_function' 返回时,链接寄存器指向 BL,并且因此在这一点上的跟踪可能导致 'function' 在回溯中出现两次。

类似地,函数可能会故意破坏 LR,例如:

caller:
        STP X29, X30, [SP, -16]!
MOV X29, SP
        ADR LR, <callee>
        BLR LR
        LDP X29, X30, [SP], #16
RET

ADR 将 'callee' 的地址放入 LR,然后 BLR 跳转到这个地址。如果在 ADR 后立即进行跟踪,'callee' 将看起来是 'caller' 的父函数,而不是子函数。

由于上述情况,可能只能在函数调用边界处可靠获取链接寄存器的值。在这种情况下,体系结构必须拒绝跨异常边界进行展开,除非它们可以可靠地识别何时应使用 LR 或堆栈值(例如,使用 objtool 生成的元数据)。


以上是关于可靠的堆栈跟踪的基本信息和要求,如果需要更多信息或其他帮助,请随时告诉我。

相关文章
|
人工智能 安全 计算机视觉
这款AI已经这么牛了!输入画面关键词就能找到相关画面视频片段素材
大家是否有过这样的经历?看到一个很棒的视频,却只想要其中几秒钟的片段,却要花费很长时间来搜索想要的片段。
3659 0
这款AI已经这么牛了!输入画面关键词就能找到相关画面视频片段素材
|
SQL 关系型数据库 数据库
MySQL · 社区动态 · Online DDL 工具 gh-ost 支持阿里云 RDS
背景 Online DDL 一直都是 DBA 运维时比较头疼的事,一般都会选择在业务低峰期谨慎的操作,比较常用的几个工具比如 percona pt-online-schema-change , Facebook OSC, 本质上它们都是基于触发器的,简单来讲就是通过数据库的触发器把作用在源表的操作在一个事务内同步到修改后的表中,这在业务高峰期时会极大的加重主库的负载。
5501 0
|
存储 Java Nacos
学成在线笔记+踩坑(4)——【媒资管理模块】上传图片,Nacos+Gateway+MinIO
媒资管理模块简介、MinIO构建分布式文件系统、MinIO数据恢复演示 、【媒资模块】上传图片
学成在线笔记+踩坑(4)——【媒资管理模块】上传图片,Nacos+Gateway+MinIO
|
存储 监控 NoSQL
九大核心NoSQL数据库及使用场景详解
【10月更文挑战第6天】在当今大数据与云计算飞速发展的时代,NoSQL数据库以其灵活的数据模型、可扩展性和高性能,成为了众多应用场景下的首选。本文将为您详细介绍九大核心NoSQL数据库及其典型使用场景,帮助您在工作和学习中更好地选择和应用。
674 3
|
机器学习/深度学习 人工智能 算法
AI技术在医疗领域的深度应用与未来展望####
本文深入探讨了人工智能(AI)技术在医疗领域的多维度应用,从疾病早期诊断、个性化治疗方案制定到复杂手术辅助,展现了AI如何重塑医疗服务的面貌。通过分析真实案例与最新研究成果,本文揭示了AI技术提升医疗效率、精准度及患者体验的潜力,同时审视了当前面临的挑战与伦理考量,为未来医疗技术的发展提供了前瞻性的思考框架。 ####
|
人工智能 API 调度
大语言模型 LLM 管理功能特点解析
大语言模型领域正快速发展,涵盖技术革新、跨领域应用及行业影响。随着技术进步,更多创新性AI应用和服务涌现。Botnow加速迭代AI应用开发平台,赋能各行各业。新发布的模型管理功能包括模型仓库和模型服务,支持模型文件托管、部署及推理服务,提升使用效率,降低成本。模型服务具备本地推理和接入外部模型的能力,满足中大型企业对大语言模型自主可控的需求。
|
存储 C语言
【C语言基础篇】ASCII码完整详细介绍
【C语言基础篇】ASCII码完整详细介绍
2599 2
|
机器学习/深度学习 人工智能 自然语言处理
【人工智能】TensorFlow简介,应用场景,使用方法以及项目实践及案例分析,附带源代码
TensorFlow是由Google Brain团队开发的开源机器学习库,广泛用于各种复杂的数学计算,特别是涉及深度学习的计算。它提供了丰富的工具和资源,用于构建和训练机器学习模型。TensorFlow的核心是计算图(Computation Graph),这是一种用于表示计算流程的图结构,由节点(代表操作)和边(代表数据流)组成。
787 0
|
消息中间件 SQL Rust
为什么选择 Kotlin 重写后端服务?
为什么选择 Kotlin 重写后端服务?
1092 0
为什么选择 Kotlin 重写后端服务?
|
人工智能 物联网 vr&ar
AR与VR技术的融合:开启全新的现实体验
在当今快速发展的科技领域中,混合现实(AR)和增强现实(VR)技术成为引人注目的热门话题。本文将探讨AR与VR技术的融合应用,以及它们给我们带来的全新现实体验。通过结合虚拟和真实世界的元素,AR与VR技术正逐渐改变着我们对于交互、娱乐、教育和工作的理解。