ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

TDengine Windows 崩溃调试完全指南:从 .dmp 分析到 ASan 内存检测

TDengine Windows 崩溃调试完全指南:从 .dmp 分析到 ASan 内存检测 TDengine Windows 崩溃调试完全指南从 .dmp 分析到 ASan 内存检测【免费下载链接】tdengineTDengine is an open source, high-performance, cloud native time-series database optimized for Internet of Things (IoT), Connected Cars, Industrial IoT and DevOps.项目地址: https://gitcode.com/taosdata/tdengineTDengine 的 TSDB 服务进程taosd.exe运行在 Windows 上时一旦发生崩溃如何快速定位根因是运维与研发人员必须掌握的技能。本文以官方调试文档为主线结合仓库源码完整讲解两条排查路径一是基于.dmp崩溃转储文件 PDB 符号文件 WinDbg 的经典堆栈分析法二是升级到 AddressSanitizerASan构建的越界访问内存检测法。读完本文你将能独立完成 Windows 上taosd.exe崩溃现场的捕获、符号化、堆栈解析以及 ASan 构建的编译、部署与报告输出重定向。排查总览两条递进式调试路径当taosd.exe在 Windows 上发生崩溃时官方推荐的诊断流程分两步递进优先分析.dmp转储文件只要进程内能捕获异常taosd.exe会在崩溃点自动生成.dmp文件结合 PDB 符号即可还原崩溃堆栈升级为 ASan 构建若.dmp提供的信息不足例如栈/堆损坏导致无法捕获则改用带 AddressSanitizer 的构建版本通过内存越界检测继续定位问题。这种先现场取证、后加强检测的思路对应了两类不同性质的故障普通异常如空指针、非法访问可通过转储直接定位而堆/栈损坏类故障则需要借助进程外的 WER 抓取与 ASan 的运行时插桩才能暴露。定位与获取 .dmp 转储文件崩溃自动生成的 .dmp 文件当taosd.exe崩溃时它会捕获异常并在自身可执行文件所在目录生成.dmp文件。文件命名规则为taosd前缀加崩溃时间戳例如taosd_20260509_124419.dmp文件大小通常在10M~200M之间。这一行为在仓库源码中有明确的实现依据。在 source/os/src/osSysinfo.c 中Windows 平台注册了FlCrashDump异常过滤器崩溃发生时它通过LoadLibraryA(dbghelp.dll)动态加载MiniDumpWriteDump并用GetLocalTime取得当前系统时间按%s%s_%04d%02d%02d_%02d%02d%02d.dmp格式拼接出与文档描述完全一致的转储文件名命名逻辑见源码_snwprintf_s(dmpPath, MAX_PATH, _TRUNCATE, L%s%s_%04d%02d%02d_%02d%02d%02d.dmp, exeDir, exeName, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);MiniDumpWriteDump写入的转储类型为组合标志见源码标志位含义MiniDumpWithDataSegs包含全局/静态变量MiniDumpWithProcessThreadData包含所有线程栈与局部变量MiniDumpWithHandleData包含打开的句柄信息MiniDumpWithIndirectlyReferencedMemory包含局部变量指向的内存MiniDumpWithThreadInfo包含线程时间与起始地址MiniDumpWithFullMemoryInfo包含全部虚拟内存区域的状态注意如果生成的.dmp文件大小为0K说明可能发生了严重的栈或堆损坏stack/heap corruption。此时进程内的转储写入很可能已经失败需要走下面的进程外捕获方案。没有生成 .dmp 文件时的对策启用 WER 进程外转储如果进程崩溃时没有产生任何.dmp文件说明崩溃可能无法从进程内部被捕获例如堆损坏0xC0000374、栈缓冲溢出 fast-fail0xC0000409、栈溢出0xC00000FD等绕过常规 SEH 的异常。此时需要启用 Windows Error ReportingWER的进程外转储能力——由独立的WerFault.exe进程负责写入转储它运行在独立进程中不受taosd.exe栈/堆损坏的影响。这一点在源码注释中有直接佐证source/os/src/osSysinfo.c#L272-L284FlCrashDump在写完进程内转储后返回EXCEPTION_CONTINUE_SEARCH将控制权交还给 WER 作为兜底并给出了LocalDumps注册表项的配置说明。将以下内容保存为.reg文件并双击导入注册表或执行reg importWindows Registry Editor Version 5.00 ; Enable WER out-of-process dump for taosd.exe ; Dumps are written by WerFault.exe (a separate process) and are therefore ; immune to stack/heap corruption in taosd. ; ; Usage: ; 1. Double-click this file, or run: ; reg import wer_localdumps.reg ; 2. Make sure C:\TDengine\core\ exists and is writable by NETWORK SERVICE. [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\taosd.exe] ; Directory where WerFault.exe writes the .dmp files (must exist before crash) DumpFolderC:\\TDengine\\core\\ ; DumpType 2 MiniDumpWithFullMemory (full user-mode dump, best for debugging) DumpTypedword:00000002 ; Keep at most 10 dumps (oldest is deleted when limit is exceeded) DumpCountdword:0000000a ; Suppress the taosd.exe has stopped working dialog on server environments. [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting] DontShowUIdword:00000001配置项说明DumpCount最多保留的.dmp文件数量超过上限时删除最旧的转储文件示例值为 10即十六进制0aDumpFolder.dmp文件的存放目录必须在崩溃前创建好且需保证对 NETWORK SERVICE 账户可写DumpType2表示完整用户态转储MiniDumpWithFullMemory是调试效果最好的类型DontShowUI在服务器环境下抑制taosd.exe 已停止工作的弹窗。值得注意的是源码中同时注册了向量化异常处理器FlVectoredExceptionHandlersource/os/src/osSysinfo.c#L288-L302它先于 SEH 执行专门拦截STATUS_HEAP_CORRUPTION (0xC0000374)、STATUS_STACK_BUFFER_OVERRUN (0xC0000409)、STATUS_STACK_OVERFLOW (0xC00000FD)这三类可能绕过SetUnhandledExceptionFilter的关键异常并直接调用FlCrashDump生成转储——这正是进程内转储 WER 进程外转储双保险机制的前半段。所有处理器均在 taosSetCoreDump 函数 中完成注册包括 CRT 的_set_invalid_parameter_handler、_set_purecall_handler以及SIGABRT处理器。手动生成 .dmp 文件当taosd进程无响应挂起时可手动生成转储文件打开Windows 任务管理器Task Manager在进程Processes选项卡中找到taosd.exe右键点击选择创建转储文件Create dump file在弹出的对话框中选择保存位置。该方式适用于进程虽未崩溃但已卡死、需要现场分析的场景。获取 PDB 符号文件.dmp文件本身只包含崩溃现场的二进制镜像只有结合与版本完全匹配的PDB 符号文件堆栈才能还原为可读的函数名、源文件名与行号。PDB 的获取途径分三种情况社区版用户从 TDengine 官方符号服务器下载必须选择与运行版本完全匹配的版本号企业版用户目前不提供 PDB 下载需联系 TDengine 技术支持获取本地编译的构建PDB 文件与编译产物位于同一目录。对于本地编译场景仓库 CMake 配置保证 Release 构建也会生成完整调试信息在 cmake/define.cmake 中Windows 链接器显式添加了/DEBUG:FULL /OPT:REF /OPT:ICF注释明确指出Release 构建保留 PDB 中的完整调试信息以便现场收集的崩溃转储可以用 WinDbg / VS 完成符号化同时编译标志中的/Zi选项会为每个编译单元生成独立的 PDB见 cmake/define.cmake#L132-L134。使用 WinDbg 分析 .dmp PDB分析.dmp文件需要加载匹配的 PDB 才能查看完整崩溃堆栈步骤如下第 1 步获取 WinDbgWinDbg 是微软官方提供的.dmp分析工具。可以从微软商店应用名 WinDbg下载也可以在安装 Visual Studio 时勾选Windows 调试工具Windows Debugging Tools组件随 VS 一起安装。第 2 步加载 PDB启动 WinDbg打开菜单File → Symbol File Path在弹出的对话框中点击browse...按钮选择存放 PDB 文件的文件夹点击OK保存并关闭。第 3 步分析 .dmp选择菜单File → Open Crash Dump在弹出窗口中选择.dmp文件并打开。打开转储文件后在底部命令行输入k命令显示崩溃堆栈。当 PDB 成功加载后可以看到函数名以及对应的源文件名和行号效果如下此后即可利用 WinDbg 的命令行环境对崩溃原因进行深入分析如查看寄存器、内存、线程等。提示除了 WinDbg仓库还在崩溃发生时同步生成一份_stack.log文本日志source/os/src/osSysinfo.c#L251-L268其中记录了ExceptionCode、ExceptionAddress、ThreadId及taosWinWriteStackTrace输出的堆栈信息——在没有 PDB 的开发侧环境中这份日志也可作为初步定位依据。升级排查手段使用 ASan 构建如果通过.dmp仍无法定位问题可以升级排查手段改用带AddressSanitizerASan的构建版本通过内存越界访问监测继续排查。TDengine 仓库同时支持 Debug 与 Release 两种配置的 ASan 构建构建选项与 Linux 平台一致。注意Windows 上的 ASan不支持内存泄漏检测但能够检测越界访问out-of-bounds和释放后使用use-after-free两类错误——这两类正是.dmp分析中常见但难以定位的根因。编译 ASan 构建构建选项-DBUILD_SANITIZERtrueDebug构建支持任意版本的 VS 2022Release构建要求 VS 2022 版本 17.14.32BUILD_SANITIZER选项定义于 cmake/options.cmake#L5option(BUILD_SANITIZER Enable sanitizers OFF)默认关闭。开启后Windows 编译标志在 cmake/define.cmake 中按构建类型区分处理Release ASan/Zi /O1 /MD /fsanitizeaddress /D_DISABLE_VECTOR_ANNOTATION1 /D_DISABLE_STRING_ANNOTATION1。注释特别说明ASan 与/GL、/O2不兼容因此优化级别降为/O1同时通过_DISABLE_VECTOR_ANNOTATION与_DISABLE_STRING_ANNOTATION抑制 STL 的 ASan 注解避免与未启用/fsanitizeaddress的预编译库如 rocksdb产生 LNK2038 链接冲突Debug ASan/Zi /MDd /fsanitizeaddress /D_DISABLE_VECTOR_ANNOTATION1 /D_DISABLE_STRING_ANNOTATION1。Debug 构建本身不含/GL、/RTC1因此不存在与 Release 类似的兼容性约束。运行 ASan 构建的前置条件要在目标机器上运行 TDengine 的 ASan 构建需要把构建机上的 ASan 运行时 DLL 复制到目标机器。VS 2022 下 ASan 运行时 DLL 位于C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\bin\Hostx64\x64\各构建类型所需 DLL 与放置位置如下构建类型所需 DLL放置位置Release ASanclang_rt.asan_dynamic-x86_64.dll与 taosd 同目录Debug ASanclang_rt.asan_dbg_dynamic-x86_64.dll与 taosd 同目录MSVC ASan 报告输出位置默认情况下ASan 报告写入stderr。报告最终流向哪里取决于taosd的启动方式启动方式默认输出去向命令行直接运行 taosd.exe直接打印到当前终端窗口双击运行无控制台丢失——没有控制台窗口stderr 无处可去作为 Windows 服务运行丢失——服务没有 stderr 控制台将 ASan 输出重定向到文件避免丢失在启动 taosd 前设置ASAN_OPTIONS环境变量即可将报告写入文件# 包含进程名以区分多进程场景下的输出 set ASAN_OPTIONSlog_pathC:\TDengine\log\asan_report:log_exe_name1 taosd.exe生成的文件名格式为asan_report.12345PID 后缀或asan_report.taosd.exe.12345启用log_exe_name时。推荐始终启用log_exe_name1因为 TDengine 部署环境中通常同时存在taosd.exe、taosdump.exe、taos.exe等多个进程。性能开销对比以下基准来自官方文档使用 taosBenchmark 创建 10,000 张子表每张表写入 10,000 行智能电表数据。注意Debug 构建在大量数据写入时会崩溃已知的编译器问题无法参与测试。构建类型写入耗时对比Release204 s基线Release ASan324 s50%从数据可以看出ASan 的运行时插桩会带来约 50% 的写入性能开销因此它定位为排障专用构建只应在问题复现环境使用不应作为生产构建长期运行。ASan 检测示例以下面的测试代码片段为例void test() { char buf[4]; // overflow memcpy(buf, abcdefg01234, 8); }buf只有 4 字节却向其中复制了 8 字节数据属于典型的栈缓冲区越界。ASan 能成功检测到该越界访问并报告 12345ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffde5c1f8f0 at pc 0x0000000000000 bp 0x7ffde5c1f8a0 sp 0x7ffde5c1f890 READ of size 8 at 0x7ffde5c1f8f0 thread T0 #0 0x000000000000 in test() (taosd.exe0x000000000000) #1 0x000000000000 in main (taosd.exe0x000000000000) Address 0x7ffde5c1f8f0 is located in stack of thread T0 at offset 48 in frame #0 0x000000000000 in test() (taosd.exe0x000000000000) This frame has 1 object(s): [32, 36) buf Memory access at offset 48 overflows this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext (longjmp and C exceptions *are* supported) SUMMARY: AddressSanitizer: stack-buffer-overflow in test() (taosd.exe0x000000000000)报告的关键信息解读ERROR: AddressSanitizer: stack-buffer-overflow错误类型为栈缓冲区越界READ of size 8非法访问为 8 字节读#0 ... in test() (taosd.exe...)崩溃调用栈加载 PDB 后此处会显示源文件名与行号This frame has 1 object(s): [32, 36) buf Memory access at offset 48 overflows this variable明确指出越界访问命中变量buf其占用的栈区间为[32, 36)而访问偏移到达 48超出该变量。服务崩溃追踪当 TSDB 服务进程taosd.exe崩溃退出时Windows 服务管理器SCM会检测到服务退出并尝试重启服务。为防止陷入崩溃-重启的无限循环服务最多只会被自动重启三次。排查时可前往控制面板 → 事件查看器Windows Event Viewer查看服务启动日志服务停止日志也会记录在其中。结合事件查看器中的服务停止时间戳与崩溃转储时间戳可以确认崩溃频率与重启策略的实际生效情况。总结Windows 平台上 TDengine 崩溃排障的完整路径可归纳为崩溃发生后优先在taosd.exe所在目录查找taosd_时间戳.dmp转储文件若进程内捕获失败转储缺失或大小为 0K则通过LocalDumps注册表项启用 WER 进程外转储获取与版本匹配的 PDB 符号文件用 WinDbg 加载符号路径后打开.dmp执行k命令查看符号化堆栈定位根因若.dmp信息不足则编译-DBUILD_SANITIZERtrue的 ASan 构建部署时同步拷贝对应的 ASan 运行时 DLL并通过ASAN_OPTIONSlog_path...:log_exe_name1将报告重定向到文件利用越界访问/释放后使用检测继续排查结合事件查看器的服务停止记录确认崩溃频率与三次重启策略。整个排障链路中进程内转储FlCrashDumpMiniDumpWriteDump、向量化异常兜底FlVectoredExceptionHandler与 WER 进程外转储形成了完整的三层捕获体系其实现均可追溯至 source/os/src/osSysinfo.c而 ASan 构建的编译标志与链接选项则在 cmake/define.cmake 中给出了具体细节。掌握这套方法后无论是生产环境的偶发崩溃还是疑难的内存越界问题都能找到一条可复现、可执行的定位路径。【免费下载链接】tdengineTDengine is an open source, high-performance, cloud native time-series database optimized for Internet of Things (IoT), Connected Cars, Industrial IoT and DevOps.项目地址: https://gitcode.com/taosdata/tdengine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表