<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Linux on To the Moon</title><link>https://pycv.github.io/blog/tags/linux/</link><description>Recent content in Linux on To the Moon</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Sat, 14 Mar 2026 16:20:15 +0800</lastBuildDate><atom:link href="https://pycv.github.io/blog/tags/linux/index.xml" rel="self" type="application/rss+xml"/><item><title>一个数组越界，竟让我排查了几天——嵌入式段错误定位实录</title><link>https://pycv.github.io/blog/excerpts/2026-03-14-embedded-segmentation-fault-debugging/</link><pubDate>Sat, 14 Mar 2026 16:19:35 +0800</pubDate><guid>https://pycv.github.io/blog/excerpts/2026-03-14-embedded-segmentation-fault-debugging/</guid><description>&#10; &lt;blockquote&gt;&#10; &lt;p&gt;本文由 AI 自动摘录整理，原始链接：&lt;a class="link" href="https://mp.weixin.qq.com/s/7cFIPWiEzTIJQEHmR7gOjQ" target="_blank" rel="noopener"&#10; &gt;一个数组越界，竟让我排查了几天&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;推荐指数&lt;/strong&gt;：8/10（推荐读原文）&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;h2 id="背景"&gt;背景&#10;&lt;/h2&gt;&lt;p&gt;程序跑了几天好好的，换个位置就段错误死机。屏蔽两行三角函数代码就正常，打开就必崩——但问题根源和那两行代码毫无关系。最终真凶是一个&amp;quot;隔山打牛&amp;quot;式的数组越界。&lt;/p&gt;&#10;&lt;h2 id="核心观点"&gt;核心观点&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;打印法可能把你带偏&lt;/strong&gt;：屏蔽代码后&amp;quot;不崩了&amp;quot;，只是切断了越界的触发路径，并没有解决根本问题。表象往往和根因相隔甚远。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;远程 GDB 精确定位崩溃点&lt;/strong&gt;：gdbserver + VSCode 远程调试，段错误发生时能精确知道崩溃的代码行号，比打印法更可靠。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;数组越界&amp;quot;隔山打牛&amp;quot;&lt;/strong&gt;：一个 5 元素的 float 数组 &lt;code&gt;arr&lt;/code&gt;，实际写到了 &lt;code&gt;arr[5]&lt;/code&gt;、&lt;code&gt;arr[6]&lt;/code&gt;、&lt;code&gt;arr[7]&lt;/code&gt;、&lt;code&gt;arr[8]&lt;/code&gt;。而 &lt;code&gt;arr[8]&lt;/code&gt; 的地址正好是静态全局变量 &lt;code&gt;fd&lt;/code&gt; 的地址，写入操作直接篡改了 &lt;code&gt;fd&lt;/code&gt; 的值，导致段错误。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="关键技巧"&gt;关键技巧&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;-fdata-sections 编译参数&lt;/strong&gt;：让每个变量放到独立的 section 中，链接器生成 map 文件时就会包含 static 变量的地址信息，方便分析内存布局。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;AddressSanitizer（-fsanitize=address）&lt;/strong&gt;：对付内存类 bug 的&amp;quot;大杀器&amp;quot;，会直接报出数组越界的精确位置和调用栈，可能 10 分钟就能定位根因。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="调试工具速查表"&gt;调试工具速查表&#10;&lt;/h2&gt;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;工具/方法&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;适用场景&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;优势&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;log 打印法&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;快速初筛&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;简单直接，零成本&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;远程 GDB&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;精确定位崩溃行&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;可看调用栈和变量值&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;core dump + gdb&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;事后分析&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;不需要复现，离线分析&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;strace&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;系统调用级跟踪&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;排查文件/网络/权限问题&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;AddressSanitizer&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;内存越界/溢出/UAF&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;编译期插桩，精确到行&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;map 文件 + -fdata-sections&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;分析变量内存布局&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;查看 static 变量地址&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="经验总结"&gt;经验总结&#10;&lt;/h2&gt;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;表象 ≠ 根因&lt;/strong&gt;：通过屏蔽/打开某些代码来定位问题时，看到的可能只是 bug 的表象。要多思考&amp;quot;为什么&amp;quot;，从根本上解决。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;选对工具事半功倍&lt;/strong&gt;：打印法虽然常用，但遇到内存踩踏类 bug 时容易把人带偏。远程 GDB 和 map 文件是更高效的手段。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;AI 辅助排查&lt;/strong&gt;：有明显代码缺陷的代码，AI review 分分钟就能检测出来。结对分析可以让 AI 检查可疑代码是否存在缺陷。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;hr&gt;&#10;&lt;p&gt;&lt;em&gt;摘录时间：2026-03-14&lt;/em&gt;&lt;/p&gt;&#10;</description></item><item><title>从0到1吃透MMU与分页：内存管理的底层原理</title><link>https://pycv.github.io/blog/excerpts/2026-03-13-mmu-paging-memory/</link><pubDate>Fri, 13 Mar 2026 08:53:00 +0800</pubDate><guid>https://pycv.github.io/blog/excerpts/2026-03-13-mmu-paging-memory/</guid><description>&#10; &lt;blockquote&gt;&#10; &lt;p&gt;本文由 AI 自动摘录整理，原始链接：&lt;a class="link" href="https://mp.weixin.qq.com/s/rKKseQQeHcPQzlv76gnUAw" target="_blank" rel="noopener"&#10; &gt;从0到1吃透MMU与分页：内存管理的底层原理&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;推荐指数&lt;/strong&gt;：8/10（推荐读原文）&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;h2 id="背景"&gt;背景&#10;&lt;/h2&gt;&lt;p&gt;这是一篇系统讲解 MMU（内存管理单元）与分页机制的技术文章。从硬件结构到软件实现，详细解释了虚拟地址到物理地址的映射过程，适合嵌入式开发者、操作系统学习者和想夯实底层基础的技术从业者。&lt;/p&gt;&#10;&lt;h2 id="核心观点"&gt;核心观点&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;MMU 是&amp;quot;翻译官&amp;quot;&lt;/strong&gt;：负责将 CPU 发出的虚拟地址翻译成物理内存能识别的物理地址，同时管理内存访问权限（只读、可读写、可执行等）&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;分页机制解决内存碎片&lt;/strong&gt;：将虚拟内存和物理内存划分为固定大小的页（Page）和页框（Page Frame），通过页表建立映射关系，有效解决内存碎片化和地址空间不足问题&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;TLB 是性能关键&lt;/strong&gt;：转换后备缓冲器缓存常用的地址映射，命中率直接影响系统性能。利用程序的空间局部性（顺序访问数组）可显著提高 TLB 命中率&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;多级页表节省内存&lt;/strong&gt;：Linux 采用四级页表结构（PGD→PUD→PMD→PTE），只有实际使用的页表部分才会分配内存，避免单级页表的巨大内存占用&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="补充要点"&gt;补充要点&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;缺页异常处理&lt;/strong&gt;：当访问的页面不在物理内存中时触发，操作系统会从磁盘加载页面并更新页表&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;大页内存（Huge Pages）&lt;/strong&gt;：使用 2MB/1GB 大页可减少 TLB 缺失，提升数据库等内存密集型应用的性能&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;进程内存隔离&lt;/strong&gt;：每个进程拥有独立的虚拟地址空间，MMU 确保不同进程的内存互不干扰&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;内存映射（mmap）&lt;/strong&gt;：将文件直接映射到进程虚拟地址空间，像访问内存一样访问文件&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ASID/PCID 技术&lt;/strong&gt;：避免进程切换时刷新整个 TLB，提升多任务性能&lt;/li&gt;&#10;&lt;/ul&gt;&#10;</description></item><item><title>Linux零拷贝技术终极指南：mmap、sendfile、splice、MSG_ZEROCOPY一次讲透</title><link>https://pycv.github.io/blog/excerpts/2026-03-10-linux-zero-copy-guide/</link><pubDate>Tue, 10 Mar 2026 20:08:00 +0800</pubDate><guid>https://pycv.github.io/blog/excerpts/2026-03-10-linux-zero-copy-guide/</guid><description>&#10; &lt;blockquote&gt;&#10; &lt;p&gt;本文由 AI 自动摘录整理，原始链接：&lt;a class="link" href="https://mp.weixin.qq.com/s/--fMOnUWYIDRSZsKcWnLFw" target="_blank" rel="noopener"&#10; &gt;Linux零拷贝技术终极指南&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;推荐指数&lt;/strong&gt;：8/10（推荐读原文）&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;h2 id="背景"&gt;背景&#10;&lt;/h2&gt;&lt;p&gt;这篇文章系统讲解了 Linux 零拷贝技术，从传统 read+write 的 4 次数据拷贝、4 次上下文切换入手，逐一介绍 mmap、sendfile、splice、MSG_ZEROCOPY 四种零拷贝方案的原理、适用场景和限制。适合需要理解高性能 I/O 的后端开发者。&lt;/p&gt;&#10;&lt;h2 id="核心观点"&gt;核心观点&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;传统 read+write 有多贵&lt;/strong&gt;：一次&amp;quot;读文件发网络&amp;quot;涉及 4 次上下文切换、4 次数据拷贝（2 次 DMA + 2 次 CPU），其中 2 次 CPU 拷贝是纯浪费&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;sendfile 是零拷贝起点&lt;/strong&gt;：Linux 2.1 引入，一个系统调用顶替 read+write，上下文切换从 4 次降到 2 次；配合 SG-DMA 网卡可做到 0 次 CPU 拷贝&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;splice 更灵活&lt;/strong&gt;：可在任意两个 fd 之间传数据（其中一个必须是 pipe），只传页面引用不传数据；Linux 2.6.23 后 sendfile 内部就是基于 splice 实现的&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;MSG_ZEROCOPY 让普通 send 也能零拷贝&lt;/strong&gt;：Linux 4.14 引入，适合需要先处理数据（加密/压缩）再发送的场景，但仅对大数据块（&amp;gt;10KB）有收益&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="补充要点"&gt;补充要点&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;mmap + write：减少一次 CPU 拷贝（从 4 次降到 3 次），但上下文切换还是 4 次&lt;/li&gt;&#10;&lt;li&gt;sendfile 限制：输入必须是文件，输出必须是 socket&lt;/li&gt;&#10;&lt;li&gt;Nginx 静态文件服务用 sendfile，配置 &lt;code&gt;sendfile on;&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Kafka 消费者拉取消息用 sendfile，数据不进 JVM 堆，这是超高吞吐的核心原因之一&lt;/li&gt;&#10;&lt;li&gt;MSG_ZEROCOPY 需要等内核通知才能安全修改 buf，编程模型更复杂&lt;/li&gt;&#10;&lt;li&gt;小数据场景（&amp;lt;10KB）用 MSG_ZEROCOPY 反而更慢，页面 pin/unpin 开销超过拷贝本身&lt;/li&gt;&#10;&lt;/ul&gt;&#10;</description></item><item><title>Linux零拷贝技术终极指南：mmap、sendfile、splice、MSG_ZEROCOPY一次讲透</title><link>https://pycv.github.io/blog/excerpts/2026-03-09-linux-zerocopy-guide/</link><pubDate>Mon, 09 Mar 2026 19:45:00 +0800</pubDate><guid>https://pycv.github.io/blog/excerpts/2026-03-09-linux-zerocopy-guide/</guid><description>&#10; &lt;blockquote&gt;&#10; &lt;p&gt;本文由 AI 自动摘录整理，原始链接：&lt;a class="link" href="https://mp.weixin.qq.com/s/--fMOnUWYIDRSZsKcWnLFw" target="_blank" rel="noopener"&#10; &gt;Linux零拷贝技术终极指南&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;推荐指数&lt;/strong&gt;：9/10（必读原文）&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;h2 id="背景"&gt;背景&#10;&lt;/h2&gt;&lt;p&gt;从 Nginx 静态文件服务到 Kafka 百万级消息吞吐，零拷贝技术是高性能 I/O 的核心秘密。文章系统讲解了 Linux 中的四种零拷贝技术——mmap、sendfile、splice、MSG_ZEROCOPY——的原理、适用场景和选型建议，并配有清晰的数据流图示。&lt;/p&gt;&#10;&lt;h2 id="核心观点"&gt;核心观点&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;传统 read+write 有 4 次拷贝&lt;/strong&gt;：2 次 DMA + 2 次 CPU 拷贝，其中 CPU 拷贝是纯浪费——数据经过用户空间却啥也没处理&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;零拷贝 ≠ 完全不拷贝&lt;/strong&gt;：零拷贝是指零 CPU 拷贝，DMA 拷贝（磁盘→内存、内存→网卡）始终存在，但由硬件完成&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;sendfile 是最常用的零拷贝&lt;/strong&gt;：一次系统调用顶 read+write，上下文切换从 4 次降到 2 次，配合 SG-DMA 网卡可实现零 CPU 拷贝&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;splice 更灵活但需要 pipe&lt;/strong&gt;：可在任意两个 fd 之间零拷贝传输，但其中一个必须是管道；Linux 2.6.23 后 sendfile 内部就是基于 splice 实现&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;MSG_ZEROCOPY 让普通 send 也能零拷贝&lt;/strong&gt;：适合需要先处理数据（加密/压缩）再发送的场景，但只对 &amp;gt;10KB 数据划算&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="补充要点"&gt;补充要点&#10;&lt;/h2&gt;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;mmap 优化有限&lt;/strong&gt;：减少 1 次 CPU 拷贝，但上下文切换仍是 4 次，适合需要读写文件内容的场景&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;sendfile 限制&lt;/strong&gt;：输入必须是文件，输出必须是 socket&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Nginx 配置&lt;/strong&gt;：&lt;code&gt;sendfile on;&lt;/code&gt; + &lt;code&gt;tcp_nopush on;&lt;/code&gt; 是静态文件服务的标配&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Kafka 零拷贝&lt;/strong&gt;：通过 &lt;code&gt;FileChannel.transferTo()&lt;/code&gt; 底层调用 sendfile，数据不进 JVM 堆&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;MSG_ZEROCOPY 注意&lt;/strong&gt;：需要通过 error queue 接收完成通知；若网卡不支持 SG-DMA 会静默退化为有拷贝模式&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;选型建议&lt;/strong&gt;：文件→网络用 sendfile；fd 间透传用 splice；需处理数据再发送且 &amp;gt;10KB 考虑 MSG_ZEROCOPY；读写文件用 mmap&lt;/li&gt;&#10;&lt;/ul&gt;&#10;</description></item></channel></rss>