news 2026/9/14 5:22:09

Linux 内核 BPF 子系统开发实战指南:缺陷报告、补丁提交、Stable 回合与测试工具链全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 内核 BPF 子系统开发实战指南:缺陷报告、补丁提交、Stable 回合与测试工具链全流程

Linux 内核 BPF 子系统开发实战指南:缺陷报告、补丁提交、Stable 回合与测试工具链全流程

【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux

本文基于内核树中 Documentation/bpf/bpf_devel_QA.rst("HOWTO interact with BPF subsystem")整理并扩充,面向希望参与 BPF 子系统开发的工程师:读完你将掌握 BPF 的缺陷报告渠道、补丁从自测到进入 mainline 的完整流转路径(bpf/bpf-next → net/net-next → mainline)、BPF selftests 的运行方法与配置要点,以及 BPF JIT/LLVM 协同开发中的关键约定(-mcpu=probe--target=bpf等),从而具备独立向 BPF 社区提交补丁并完成验证的全部能力。

一、总览:BPF 开发的协作入口

BPF(eBPF)内核开发、bpftool 以及 iproute2 BPF loader 的开发统一通过bpf 内核邮件列表bpf@vger.kernel.org进行。通用补丁提交规范请参阅 Documentation/process/submitting-patches.rst,本文只补充 BPF 特有的约定。

从源码结构看,当前仓库的 MAINTAINERS 文件将 BPF 细分为多个维护条目,可据此定位各方向的负责人:

条目说明关键路径
BPF [CORE]verifier、syscall 等核心kernel/bpf/verifier.c、kernel/bpf/syscall.c
BPF [GENERAL]BPF 总维护(含 selftests、libbpf、samples)tools/testing/selftests/bpf/、tools/bpf/、samples/bpf/、arch/*/net/*
BPF [JIT for X86/ARM/ARM64/RISC-V/…]各架构 JITarch/<arch>/net/
BPF [TOOLING] (bpftool)用户态调试工具tools/bpf/bpftool/
BPF [LIBRARY] (libbpf)用户态库tools/lib/bpf/
BPF [SELFTESTS]测试基础设施tools/testing/selftests/bpf/

BPF [GENERAL]条目(MAINTAINERS)中列出的维护者包括 Alexei Starovoitov、Daniel Borkmann、Andrii Nakryiko、Eduard Zingerman、Kumar Kartikeya Dwivedi 等,并给出了 patchwork 队列(netdevbpf 项目的 'bpf' delegate)以及bpf/bpf-next两棵 git 树,与文档正文描述完全一致。

二、如何报告 BPF 缺陷

所有BPF 内核代码问题(包括 XDP、BPF tracing 等)都发到bpf@vger.kernel.org。由于 netdev 列表流量巨大,报告中务必 Cc BPF 维护者(可从内核 MAINTAINERS 文件确认):

  • Alexei Starovoitov <ast@kernel.org>
  • Daniel Borkmann <daniel@iogearbox.net>

如果已经定位到有问题的提交,还需把该提交的作者也加入 Cc(可通过内核 git 树查询)。

重要约定:请勿把 BPF 问题提交到 bugzilla——文档明确警告,这样做基本保证问题会被忽视。

三、补丁提交流程

3.1 发送前:在 BPF CI 上自测

BPF CI 基于 GitHub,托管在 kernel-patches 组织的bpf仓库中。文档以 UI 工作流为主,步骤如下:

  1. 在自己的 GitHub 账号中 fork 该仓库(一次性操作);
  2. 本地 clone 自己的 fork,检出跟踪bpf-nextbpf分支的新分支,并把待测补丁叠加其上;
  3. 把本地分支推送到自己的 fork,并向bpf_next_basebpf_base分支(分别对应上游 bpf-next 与 bpf)发起 Pull Request。

PR 创建后不久 CI 工作流即会运行。注意两点:

  • CI 容量与上游提交者共享,按排队情况运行时间可能较长;
  • bpf-next_basebpf_base会随上游分支推进而更新,因此你的补丁集会被自动尝试 rebase到新基线,这可能导致当前 CI 运行被中止并以新基线重启。

tools/testing/selftests/bpf/README.rst 进一步说明:CI 系统对系列中的每个补丁运行 selftests,并在多种架构上执行,内核配置由 selftests 目录下通用与架构相关的配置片段(如 tools/testing/selftests/bpf/config 与config.x86_64等)推导而来;测试结果会反馈到 patchwork,失败会像 checkpatch 违例一样被高亮显示。

3.2 补丁发往哪个邮件列表?

BPF 补丁提交到bpf@vger.kernel.org。若补丁横跨多个子系统(网络、tracing、security 等),务必同时 Cc 相应子系统的邮件列表与维护者,以便他们审查并给出Acked-by

3.3 在哪里查看正在讨论的补丁?

Cc 到 netdev 的补丁都会进入 patchwork 的netdevbpf项目队列;目标为 BPF 的补丁会被分配给 'bpf' delegate 由 BPF 维护者处理(对应 MAINTAINERS 中Q:字段登记的 netdevbpf delegate 队列)。补丁状态含义:

  • Accepted:BPF 社区审查通过、维护者批准,补丁已应用到 bpf 或 bpf-next 之一,提交者会收到邮件通知;
  • Changes Requested:需要修改重发,补丁被移出当前审查队列;被拒绝或不适用于 BPF 树的补丁同样会被清除。

3.4 补丁如何进入 Linux 主线?

BPF 维护两棵内核 git 树:bpfbpf-next(均只有 master 一个分支,简化 rebase 目标选择):

  • bpf:仅接收修复
  • bpf-next:接收新功能、清理与其他改进("next 型"内容)。

这与网络子系统的 net / net-next 类比。两棵树累积的补丁会定期以 pull request 形式并入由 David S. Miller 维护的net / net-next树,再从中进入 Linus Torvalds 维护的 mainline。net/net-next 的合入机制见 Documentation/process/maintainer-netdev.rst。

偶尔为规避合并冲突,BPF 维护者会向其他树(如 tracing)发送只含少量补丁的 pull request,但 net / net-next 始终是主要合入目标。pull request 带高层摘要,可在 netdev 列表中按主题行搜索(yyyy-mm-dd为日期):

pull-request: bpf yyyy-mm-dd pull-request: bpf-next yyyy-mm-dd

如何指定目标树?流程与 netdev 文档(Documentation/process/maintainer-netdev.rst)一致,关键在主题行:

  • 修复(最终走 bpf → net):
git format-patch --subject-prefix='PATCH bpf' start..finish
  • 功能/改进(最终走 bpf-next → net-next):
git format-patch --subject-prefix='PATCH bpf-next' start..finish

若不确定该进 bpf 还是 net、bpf-next 还是 net-next,主题行写 net / net-next 也没关系,维护者会负责分配。若明确目标为 bpf / bpf-next,请先对相应树做 rebase 以减少冲突。第二轮及以后的修订版本必须在主题前缀中加版本号,例如:

git format-patch --subject-prefix='PATCH bpf-next v2' start..finish

收到修改意见后,必须重新发送完整补丁系列(吸收反馈后),而不是在旧系列上只发个别 diff。

3.5 补丁被应用到 bpf / bpf-next 意味着什么?

意味着"从 BPF 角度看该补丁适合进入主线",但这不是最终裁决:补丁进入 net / net-next 前,bpf 列表上任何时间点都可能出现新的 review。若讨论结论是无法按原样合入,维护者会追加后续修复或干脆从树中移除,并保留在必要时rebase 整棵树的权利。树的存在目的有二:

i) 累积并暂存 BPF 补丁,以便向 net / net-next 集成; ii) 在补丁继续前进之前,对其运行完整的 BPF 测试套件与 workload。

当 David S. Miller 接受 BPF pull request 后,补丁进入 net / net-next,再进一步流向 mainline(合入频率等细节见 netdev 文档)。

3.6 反馈与 pull request 的节奏

  • 反馈延迟:维护者尽量压低延迟,通常2~3 个工作日,视改动复杂度与补丁负载浮动;
  • pull request 频率:为避免积累过多补丁,会较频繁发送;经验法则是每周末每棵树一次,视负载与紧急程度也可能在周中加发;
  • merge window 期间:合入窗口开启时 bpf-next 停止处理(与 net-next 类似,细节见 Documentation/process/maintainer-netdev.rst)。这两周内维护者可能要求你在 bpf-next 重新开放后重发补丁系列;Linus 在合入窗口后发布v*-rc1,bpf-next 处理即恢复。非邮件列表订阅者可参考 David S. Miller 维护的 net-next 状态页获取指引。

3.7 Verifier 改动必须附带 selftests

如果补丁改变了 verifier 行为,必须向 BPF 内核 selftests 增加测试用例;若缺失且维护者认为必要,会在接受改动前要求补充。tools/testing/selftests/bpf/test_verifier.c 追踪了大量 BPF 测试用例(包括 LLVM BPF 后端从受限 C 代码可能生成的诸多 corner case),因此:

未被 test_verifier.c 追踪的 verifier 行为,未来存在被变更的可能。

3.8 selftests 还是 samples/bpf?

总体优先向 BPF 内核 selftests 添加,因为 selftests 会被各类机器人定期运行以捕获内核回归——用例越多,覆盖越好,意外破坏的概率越低;selftests 本身也可以演示特性用法。分工建议:

  • samples/bpf/:适合入门级的简单功能演示;
  • selftests:功能测试与 corner case 测试;
  • 如果你的"sample"看起来像测试用例,请放进 selftests。

3.9 何时扩展 bpftool?

bpftool(源码位于tools/bpf/bpftool/)的核心定位是内核中活跃 BPF 程序与 map 的统一用户态调试/内省工具。如果 BPF 相关 UAPI 变更允许 dump 出程序或 map 的更多信息,应当同步扩展 bpftool 支持这些 dump。

3.10 何时扩展 iproute2 的 BPF loader?

XDP 或 tc 层(如cls_bpf,对应源码 net/sched/cls_bpf.c)的 UAPI 变更,约定要在用户态一侧同步加入 iproute2 BPF loader 的支持——这既有利于 UAPI 本身被设计得真正可用,也能让主流下游发行版用户及时受益。

iproute2 BPF loader 的补丁规则:

  • 发送到netdev@vger.kernel.org(不由 BPF 内核维护者处理,但请保留他们在 Cc 以便 review);
  • iproute2 官方 git 仓库由 Stephen Hemminger 维护;
  • 主题前缀为[PATCH iproute2 master][PATCH iproute2 net-next]:内核改动进了 net-next,则对应的 iproute2 改动进其 net-next 分支,否则进 master;iproute2 的 net-next 分支在当前 master 版本发布后合入 master;
  • 与 BPF 相同,补丁进入 netdev 项目的 patchwork 并委派给 'shemminger' 处理。

3.11 提交前最低要求

  1. 充分自测是硬性要求,绝不仓促提交;
  2. 进入bpf树的修复必须带Fixes:标签;目标为 bpf-next 且受影响提交在 net-next(或个别情况在 bpf-next)中的修复同样需要Fixes:——它用于识别后续提交并极大帮助 backport 人员,缺一不可;
  3. 不接受空提交信息。高质量 commit message 至关重要:一个月后看代码的其他开发者需要理解为什么这样改、原分析中是否有缺陷,因此必须给出充分理由与用例描述;
  4. 超过 1 个补丁的系列必须有 cover letter,给出系列高层描述——它会进入 BPF 维护者的 merge commit,从而可从 git log 中长期检索。

3.12 涉及 BPF JIT 和/或 LLVM 的新特性

维护者努力保持所有 BPF JIT 同步更新,保证不同架构上运行 BPF 程序时体验一致,避免程序在内核 JIT 开启时"降级"到低效的解释器。注意事项:

  • 若你无法自行实现/测试某架构的 JIT 改动,请尽早与该架构的 BPF JIT 开发者协作;从源码结构看,各架构 JIT 代码位于arch/*/net/,可结合 git log 找到合适的协作者(MAINTAINERS 中每个架构均有独立的 "BPF JIT" 条目);
  • 为新指令始终添加 BPF 测试用例(如test_bpf.ctest_verifier.c),以获得广泛测试覆盖并帮助运行时测试各 JIT;
  • 新 BPF 指令被内核接受后,还要实现 LLVM BPF 后端的相应支持(见下文 LLVM 部分)。

3.13BPF_INTERNAL符号命名空间

BPF_INTERNAL方式导出的符号只能被 BPF 基础设施(如带轻量 skeleton 的 preload 内核模块)使用;BPF_INTERNAL之外的大多数符号同样不应被 BPF 之外的代码使用。某些符号缺少该标注,可能是因为它们早于命名空间机制,或属于疏漏。

四、Stable 内核回合

4.1 需要某个 BPF 修复进入 stable?

先在 stable 仓库(linux-stable.git 的linux-*.y分支)确认该提交是否已经存在。若不存在,给 BPF 维护者发邮件并在 Cc 中加入netdev@vger.kernel.org,请求排队该修复。整体流程与 netdev 一致(见 Documentation/process/maintainer-netdev.rst)。

4.2 会回合到已停止维护的内核吗?

不会。需要 BPF 提交进入当前不再由 stable 维护者维护的内核,需要自行处理。当前 stable 与 LTS 内核清单以 kernel.org 官方列表为准。

4.3 自己的补丁需要进 stable 怎么办?

规则与 netdev 补丁提交一致。永远不要在补丁描述里加Cc: stable@vger.kernel.org,而应请 BPF 维护者代为排队:可以在补丁中---之后(不会进入 git log 的部分)加一段说明,也可以直接用邮件单独请求。

4.4 在哪里查看已排队的 stable 补丁?

修复关键缺陷的补丁进入 bpf 树后,会先排入 patchwork 的 BPF stable bundle(bpf/stable,state=*)。这些补丁至少保留到对应提交进入 mainline,经过更广泛曝光后,才由 BPF 维护者正式提交给 stable 维护者。

五、如何测试补丁:运行 BPF selftests

启动新编译的内核后,从 git 树根目录进入 selftests 目录:

$ cd tools/testing/selftests/bpf/ $ make

运行 verifier 测试:

$ sudo ./test_verifier

verifier 测试会打印当前执行的每一项检查,末尾给出通过/失败汇总,例如:

Summary: 418 PASSED, 0 FAILED

运行全部 BPF selftests:

$ sudo make run_tests

细节参见 Documentation/dev-tools/kselftest/ 下的 kernel selftest 文档。

从源码结构看,几个文档中提到的构建行为均可在 tools/testing/selftests/bpf/Makefile 中得到印证:

  • 为尽量让测试全部通过,被测内核的.config应尽可能贴近 selftests 目录下的配置片段(tools/testing/selftests/bpf/config 及config.x86_64config.aarch64等架构片段);
  • 若无法做到,构建时设置BPF_STRICT_BUILD=0(Makefile 中BPF_STRICT_BUILD ?= 1PERMISSIVE := $(filter 0,$(BPF_STRICT_BUILD))),即可容忍个别编译失败并继续构建其余测试,而不是把每个失败都当作致命错误。

此外,tools/testing/selftests/bpf/README.rst 提供了两条实用补充:

  • DENYLIST 机制:部分架构不支持全部 BPF 特性(如 s390x 的 BPF trampoline),此时DENYLISTDENYLIST.<arch>文件用于阻止测试在该架构运行(三列:测试名、失败报错、原因摘要);
  • vmtest.sh:tools/testing/selftests/bpf/vmtest.sh 可在虚拟机中以接近维护者 CI 的环境运行 selftests——使用树内内核配置、下载 CI 使用的 VM 用户态镜像、重新编译并运行 BPF selftests(默认运行test_progs),结果默认保存在~/.bpf_selftests;依赖 clang(建议源码构建)、pahole、qemu、docutils(rst2man)与 libcap-devel。

pahole 依赖:为支持最新的 BPF Type Format 特性(讨论见 Documentation/bpf/btf.rst),以CONFIG_DEBUG_INFO_BTF=y构建内核时要求pahole 1.16(dwarves 包,或从 dwarves 项目源码构建)。pahole 自 v1.13 起(提交 21507cd3e97b,"pahole: add libbpf as submodule under lib/bpf")开始使用 libbpf 的定义与 API:用 git 仓库构建时,git submodule update --init --recursive会同步 libbpf 子模块;但默认发布的源码包不含 libbpf 子模块源码,会引发构建问题(kernel.org 上的 pahole tarball 同样如此),应改用附带 libbpf 子模块源码的 tarball。部分发行版(如 Fedora、Gentoo)已打包 pahole 1.16。

selftests 版本匹配:运行内核xyz,就应运行内核xyz自带的 BPF selftests,不要指望最新 mainline 树的 selftests 永远全绿。尤其test_bpf.c(其用例已迁入 selftests 框架的prog_tests/组织)与test_verifier.c用例量大且持续更新:既新增 BPF 测试序列,也会随 verifier 变"聪明"而调整既有用例。

六、LLVM 工具链

6.1 哪里获得带 BPF 支持的 LLVM?

LLVM 的 BPF 后端自LLVM 3.7.1起已在上游,主流发行版均提供带 BPF 后端的 LLVM 包,多数场景直接安装发行版软件包即可,无需手工编译。

llc --version检查目标列表,确认 BPF 目标在册:

$ llc --version LLVM (http://llvm.org/): LLVM version 10.0.0 Optimized build. Default target: x86_64-unknown-linux-gnu Host CPU: skylake Registered Targets: aarch64 - AAArch64 (little endian) bpf - BPF (host endian) bpfeb - BPF (big endian) bpfel - BPF (little endian) x86 - 32-bit X86: Pentium-Pro and above x86-64 - 64-bit X86: EM64T and AMD64

为使用 LLVM BPF 后端的新特性,建议开发者跟踪最新 LLVM 发布——新 BPF 内核特性(如指令集扩展)的 LLVM 支持往往与内核侧同步开发。

6.2 手工构建 LLVM

追求最快增量构建的开发者推荐使用 Ninja(包管理器中一般为ninjaninja-build)。需要 ninja、cmake 与 g++。从 git 仓库构建最新 LLVM/Clang:

$ git clone https://github.com/llvm/llvm-project.git $ mkdir -p llvm-project/llvm/build $ cd llvm-project/llvm/build $ cmake .. -G "Ninja" -DLLVM_TARGETS_TO_BUILD="BPF;X86" \ -DLLVM_ENABLE_PROJECTS="clang" \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_BUILD_RUNTIME=OFF $ ninja

产物位于build/bin/,可将PATH指向该目录。-DLLVM_TARGETS_TO_BUILD设为你需要的目标,完整列表见llvm-project/llvm/lib/Target

6.3 报告 LLVM BPF 后端问题

LLVM BPF 后端与内核侧 verifier 深度耦合,任一侧的问题都需要排查修复。发现"LLVM 生成的代码被 verifier 拒绝"或 BPF 代码生成缺陷时,应当到 netdev 邮件列表提出并 Cc 内核与 LLVM 两侧的开发者(Yonghong Song、Alexei Starovoitov、Daniel Borkmann)。LLVM 的 issue tracker 中也能检索 BPF 相关 bug,但文档建议优先走邮件列表并 Cc 维护者。

6.4 新 BPF 指令的内核/LLVM 集成

LLVM 的 BPF 后端提供-mcpu选择器以挑选指令集扩展版本:LLVM 20 之前默认generic(基础指令集v1);自 LLVM 20 起默认处理器目标改为指令集v3-mcpu=probe会让 LLVM 探测宿主内核支持的扩展并自动选择最优集合。

交叉编译时可手动指定版本:

$ llc -march bpf -mcpu=help Available CPUs for this target: generic - Select the generic processor. probe - Select the probe processor. v1 - Select the v1 processor. v2 - Select the v2 processor. [...]

向内核新增 BPF 指令必须遵循同一方案:提升指令集版本并实现相应的 probing,使-mcpu=probe用户在升级内核后能透明获得优化。若你无法自行实现 LLVM 支持,请向 BPF 开发者求助。顺带一提:BPF 内核 selftests 使用-mcpu=probe运行以获得更好的测试覆盖——从源码结构看,tools/testing/selftests/bpf/Makefile 确实按 clang 支持情况以-mcpu=v2/-mcpu=v3/-mcpu=v4分档编译测试对象(例如探测到 v4 支持时启用相应路径)。

6.5--target=bpf还是默认(宿主架构)目标?

尽管 LLVM IR 生成与优化力求架构无关,--target=<arch>仍会影响生成代码:

  • BPF 程序可能递归包含带文件作用域内联汇编的宿主头文件;默认(宿主)目标能正确处理,而bpf目标在 BPF 后端汇编器不识别这些宿主汇编时会失败(大多数情况如此);
  • 不带-g编译时,默认目标可能在目标文件中产生.eh_frame.rela.eh_frame等额外 ELF 段,bpf目标则不会;
  • 默认目标可能把 C switch 语句优化为跳转表(switch table),跳转表位于全局只读段,会导致 BPF 程序加载失败;bpf目标不做该优化。可用-fno-jump-tables关闭跳转表生成;
  • --target=bpf保证pointerlong/unsigned long恒为 64 位,无论 clang 二进制/默认目标/内核是 32 位还是 64 位;而原生目标按宿主架构惯例编译这些类型——在 32 位架构上,BPF context 结构中的指针/long 将是 32 位宽,而 BPF LLVM 后端始终按 64 位运行。

何时用默认目标:程序包含最终拉入宿主文件作用域汇编的头文件(例如 ptrace.h);也可叠加-fno-jump-tables规避跳转表问题。

何时必须用bpf目标:程序使用含pointer/long/unsigned long字段并与 BPF helper 或 context 数据结构交互的结构体——verifier 会校验对这些结构的访问,若宿主架构与 BPF 架构(如 64 位)不对齐就会校验失败。文档给出的明确例子是BPF_PROG_TYPE_SK_MSG必须使用--target=bpf。原生目标的主要用途是 tracing 中遍历pt_regs或其他依赖 CPU 寄存器宽度的内核结构。除此之外,一般推荐clang --target=bpf

结语

BPF 子系统的开发协作可以概括为一条清晰的主线:bpf 邮件列表是唯一入口,bpf/bpf-next 两棵树承担累积与测试,patchwork 状态反映审查进度,net/net-next 是通向 mainline 的主通道,stable 队列由维护者统一代管。开发者的自我要求则是三件事:改动 verifier 就补 selftests,改动 UAPI 就同步 bpftool 或 iproute2 loader,改动指令集就同步所有 JIT 与 LLVM 后端并遵循指令集版本探测方案。做到这些,即可按 Documentation/bpf/bpf_devel_QA.rst 的约定顺利参与 BPF 开发——Happy BPF hacking!

【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 5:19:56

蓝牙模块量产选型必须索要的6类射频与功耗证据

1. 这不是买蓝牙模块&#xff0c;是买一份可量产的射频交付物“蓝牙模块选型”这六个字&#xff0c;听起来像在电子市场挑一块板子——查查型号、比比价格、看看尺寸、测测通电。但如果你正负责一款要出货5万台的智能体脂秤、一款要过CE/FCC认证的工业手持终端&#xff0c;或者…

作者头像 李华
网站建设 2026/9/14 5:19:17

用 Obsidian 打造你的 LLM 知识库:大模型学习与个人 Wiki 实践指南

llm_wiki&#xff1a;用 Obsidian 建立你的第一座大模型知识库 入行做 NLP 这几年&#xff0c;我电脑里的资料比头发掉得还快。PDF 论文、微信公众号文章、GitHub 上的教程、飞书文档链接&#xff0c;散落在各个文件夹里&#xff0c;真到用的时候什么都找不到。后来我花了一个…

作者头像 李华
网站建设 2026/9/14 5:17:55

STM32环境监测系统实战:从选型到调试的完整工程闭环

1. 项目概述&#xff1a;一个能真正落地的环境质量监测系统长什么样&#xff1f;“STM32项目开源&#xff1a;环境质量监测系统&#xff08;代码原理图仿真&#xff09;”——这个标题在嵌入式学习圈里出现频率极高&#xff0c;但真正打开下载包后能跑通、能看懂、能改、能用的…

作者头像 李华
网站建设 2026/9/14 5:17:38

grep、sed、awk三剑客实战:从日志分析到文本处理的完整方案

开头想直接扔一段"grep、sed、awk三兄弟"的废话&#xff1f;不行。我见过太多次这样的场景了&#xff1a;开发同事线上排查问题&#xff0c;日志文件几百兆&#xff0c;他打开编辑器从头翻到尾&#xff0c;小半天过去了还在骂骂咧咧找某个异常栈&#xff1b;或者是报…

作者头像 李华