正常
调试现场
这一章值得记的真实坑,都和"边界"或"工具链"有关。
第一个是上面讲的 INT64_MIN。format_decimal 不特判它,-value 溢出,打印 INT64_MIN 会得到一串错的数字。这种 bug 在内核里极难触发(谁会专门打印 INT64_MIN?),但 host 单测一条就抓出来。这也是为什么"纯算法要能 host 测"——它不是为了好看,是真抓 bug。
第二个是串口的 Baud / 配置。init 里设的 LCR=0x03(8N1)必须和 QEMU -serial 默认的 115200 8N1 对上。配错一位,终端收到的就是满屏乱码——能看出"有东西在发",但全是垃圾。判断方法:先发一个固定字符(比如 A),终端看到 A 就说明线路配置对,看到乱码就是 LCR/Baud 问题。
第三个是 puts 不转 \r\n。漏了 \n 前 putc('\r') 的话,终端每换行不回首列,输出会呈阶梯状斜着走。这是串口输出的经典初见坑,一眼能认。
第四个(也是 002 要再次踩的)是对象库与全局构造。format.cpp 被单独编成静态库再链进内核,如果链接/构造函数表没处理好,全局对象的构造可能不被调用。这一章的 linker.ld 特意用 KEEP(*(.init_array)) 防止 .init_array 被链接器当垃圾裁掉——裁掉了,_init_global_ctors 遍历到的就是空,全局对象构造全跳过。test_cpp_basic 里那个"全局对象构造"测试,就是专门盯这个的。