Slicer 在 GNU/Linux 下的 C++ 调试实战:GDB 附加、执行器环境与 Core 转储分析
医疗健康图像处理数据可视化桌面应用3D渲染【免费下载链接】SlicerMulti-platform, free open source software for visualization and image computing.项目地址https://gitcode.com/gh_mirrors/sl/Slicer点击查看免费下载本文基于 Slicer 官方文档Docs/developer_guide/debugging/linuxcpp.md系统讲解在 GNU/Linux 上调试 Slicer C 代码的四种 GDB 工作流附加运行中进程、通过执行器启动参数、跟随 fork 子进程、exec-wrapper 包装脚本以及崩溃 core 文件的获取与分析方法。读完后你将能够绕过 Slicer 双层可执行结构Slicer启动器 SlicerApp-real真实进程带来的调试障碍独立完成断点调试与 segfault 回溯并可进一步衔接 Qt Creator、VS Code 等跨平台 IDE 调试方案。为什么 Linux 下调试 Slicer 比常规 Qt 项目麻烦Slicer 在 Linux 上并不是一个可执行文件的结构。从构建系统 CMake/SlicerMacroBuildApplication.cmake 可以看到在非 Apple 平台上真实的应用二进制会被命名为应用名App-realset(executable_name ${SLICERAPP_APPLICATION_NAME}) if(NOT APPLE) set(executable_name ${executable_name}App-real) endif()即最终产生两个可执行文件Slicer由 CTKAppLauncher 生成的启动器launcher负责设置LD_LIBRARY_PATH、PATH、PYTHONPATH等环境变量后 fork/exec 出真实进程SlicerApp-real真正运行的应用程序包含全部符号断点必须打在这里。这就是本文所有调试技巧的共同出发点要么在SlicerApp-real运行时把它 attach 进 GDB要么设法让 GDB 越过启动器直接调试真实进程。方法一GDB 附加到运行中进程推荐文档将 attach 方式列为推荐方案流程分四步。1. 解除 yama ptrace 限制自 Ubuntu 10.10 起内核的 yama LSM 默认禁止普通用户 ptrace 非子进程只有父进程才能附加到自己的子进程。临时放开$ echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope永久放开则编辑/etc/sysctl.d/10-ptrace.conf将kernel.yama.ptrace_scope 1改为kernel.yama.ptrace_scope 02. 用--attach-process拿到 PID$ ./Slicer --attach-process该参数会在加载任何模块之前弹出一个显示当前进程PID的消息框因此既方便 attach也适合调试模块加载阶段就发生的崩溃。这个行为可以在源码中确认Base/QTCore/qSlicerCoreApplication.cxx 中应用初始化环境时检查该参数并弹出提示// allow a debugger to be attached during startup if (qApp-arguments().contains(--attach-process)) { // Message for developers - do not translate. QString msg(/*no tr*/ This message box is here to give you time to attach your debugger to process [PID %1]); QMessageBox::information(nullptr, /*no tr*/ Attach process, msg.arg(QCoreApplication::applicationPid())); }如果不使用该参数也可以直接查询进程$ ps -Afww | grep SlicerApp-real3. 附加进程并继续执行$ gdb --pid $PIDABOVE进入 GDB 后执行(gdb) continue让被暂停的进程恢复运行此时即可正常下断点。小技巧在 GDB 中打印QString需要借助 Qt 提供的调试辅助函数可参考文档给出的 printQString 资料文档原文指向 silmor.de 的printqstring页面属于 Qt 通用技巧。方法二利用执行器的启动参数Slicer 的执行器app launcher本身就提供了携带 Slicer 环境启动其他程序的能力这是 CTKAppLauncher 的通用特性在 CMake/SlicerMacroBuildApplication.cmake 中通过ctkAppLauncherAppendExtraAppToLaunchToList逐个注册附加可执行程序例如构建树上自动注册--gnome-terminal、--xterm、--designer等选项。与调试相关的两个选项--launch executable [parameters]执行任意程序且程序继承 Slicer 的完整环境变量。例如Slicer --launch /usr/bin/gnome-terminal启动一个 gnome-terminal随后即可在该终端里直接对SlicerApp-real运行 GDB--gdb直接启动 GDB并在调试器环境内执行SlicerApp-real。方法三让 GDB 跟随 fork 出的子进程既然Slicer只是启动器可以直接对启动器下 GDB再让 GDB 切换到 fork 出来的SlicerApp-realgdb SlicerGDB 会提示Slicer没有调试符号——这是正常的因为它只是 launcher。接着设置跟随模式并运行(gdb) set follow-fork-mode child (gdb) runGDB 启动Slicer后会自动 attach 到 fork 出的SlicerApp-real之后即可正常调试。方法四使用 exec-wrapper 直接调试适合 IDE 集成exec-wrapper 方案用一个包装脚本模拟 app launcher 的环境变量行为使 GDB 或任何控制 GDB 的程序如 IDE可以在不 attach的情况下交互式调试。包装脚本的核心思想与 CMake/SlicerBlockCTKAppLauncherSettings.cmake 中定义的 launcher 设置一一对应该 CMake 文件分构建树 / 安装树两组维护SLICER_LIBRARY_PATHS、SLICER_PATHS、SLICER_ENVVARS等变量最终生成SlicerLauncherSettings.ini[LibraryPaths]的内容进入LD_LIBRARY_PATH[Paths]的内容进入PATH[EnvironmentVariables]中的每一项逐一设置如SLICER_HOME、PYTHONHOME、PYTHONPATH、QT_PLUGIN_PATH等。然后启动 GDB(gdb) set exec-wrapper ./WrapSlicer (gdb) exec-file ./bin/SlicerQT-real (gdb) runSlicerQT-real为文档撰写时期的进程名对应现版本的SlicerApp-real。关闭线程事件噪声由于 VTK 和 ITK 包含大量多线程过滤器渲染和处理期间 GDB 默认会刷屏输出类似[New Thread 0x7fff8378f700 (LWP 20510)] [Thread 0x7fff8b0aa700 (LWP 20506) exited]用以下命令关闭set print thread-events off生成 wrapper 脚本的实用技巧最简单的方式是让 launcher 自己示范环境变量。执行Slicer --launch which gnome-terminal或Slicer --gnome-terminal然后在弹出的终端中查看LD_LIBRARY_PATH的取值注意文档提醒通过--xterm启动时该变量似乎不会被设置再对照[EnvironmentVariables]检查其余变量。文档附了一份当时的SlicerLauncherSettings.ini完整示例展示了 launcher 配置的五个主要区块[General]、[Application]、[ExtraApplicationToLaunch]、[LibraryPaths]、[Paths]、[EnvironmentVariables]。关键部分摘录如下完整文件见 Docs/developer_guide/debugging/linuxcpp.md[General] launcherSplashImagePath... launcherSplashScreenHideDelayMs3000 additionalLauncherHelpShortArgument-h additionalLauncherHelpLongArgument--help additionalLauncherNoSplashArguments--no-splash,--help,--version,--home,--program-path,--no-main-window [Application] pathAPPLAUNCHER_DIR/bin/./SlicerQT-real arguments [ExtraApplicationToLaunch] gnome-terminal/shortArgument gnome-terminal/helpStart gnome-terminal gnome-terminal/path/usr/bin/gnome-terminal gnome-terminal/arguments gdb/shortArgument gdb/helpStart gdb gdb/path/usr/bin/gdb gdb/arguments [LibraryPaths] 1\path... 8\pathAPPLAUNCHER_DIR/bin/. 9\path../lib/Slicer-4.0/qt-loadable-modules ... size18 [Paths] 1\pathAPPLAUNCHER_DIR/bin/. ... size5 [EnvironmentVariables] QT_PLUGIN_PATHAPPLAUNCHER_DIR/binPATHSEP... SLICER_HOME... PYTHONHOME... PYTHONPATH... TCL_LIBRARY... TK_LIBRARY... TCLLIBPATH...其中APPLAUNCHER_DIR、PATHSEP是 CTKAppLauncher 的占位符分别在运行时被替换为启动器所在目录与平台路径分隔符。当前仓库中这些路径并非手维护而是由 CMake/SlicerBlockCTKAppLauncherSettings.cmake 程序化生成——例如构建树的SLICER_LIBRARY_PATHS_BUILD、SLICER_PATHS_BUILD、SLICER_PYTHONPATH_BUILD以及安装树对应的*_INSTALLED变量——阅读该文件即可理解任何一次生成的SlicerLauncherSettings.ini的来龙去脉。如果--launch方式不可用上述 ini 设置可以直接翻译为如下 bash 包装脚本#!/bin/bash BASE_DIR/cmn/git/Slicer4-sb/ APPLAUNCHER_DIR$BASE_DIR/Slicer-build LD_PATHS /cmn/git/Slicer4-sb/VTK-build/bin/. /cmn/git/Slicer4-sb/CTK-build/CTK-build/bin/. /usr/lib /cmn/git/Slicer4-sb/ITKv3-build/bin/. /cmn/git/Slicer4-sb/SlicerExecutionModel-build/ModuleDescriptionParser/bin/. /cmn/git/Slicer4-sb/teem-build/bin/. /cmn/git/Slicer4-sb/LibArchive-install/lib $APPLAUNCHER_DIR/bin/. ../lib/Slicer-4.0/qt-loadable-modules $APPLAUNCHER_DIR/lib/Slicer-4.0/cli-modules/. $APPLAUNCHER_DIR/lib/Slicer-4.0/qt-loadable-modules/. /cmn/git/Slicer4-sb/tcl-build/lib /cmn/git/Slicer4-sb/OpenIGTLink-build /cmn/git/Slicer4-sb/OpenIGTLink-build/bin/. /cmn/git/Slicer4-sb/CTK-build/PythonQt-build/. /cmn/git/Slicer4-sb/python-build/lib /cmn/git/Slicer4-sb/python-build/lib/python2.6/site-packages/numpy/core /cmn/git/Slicer4-sb/python-build/lib/python2.6/site-packages/numpy/lib for STR in $LD_PATHS; do LD_LIBRARY_PATH${STR}:${LD_LIBRARY_PATH}; done QT_PLUGIN_PATH$APPLAUNCHER_DIR/bin:/cmn/git/Slicer4-sb/CTK-build/CTK-build/bin:/usr/lib/qt4/plugins SLICER_HOME/cmn/git/Slicer4-sb/Slicer-build PYTHONHOME/cmn/git/Slicer4-sb/python-build PYTHONPATH$APPLAUNCHER_DIR:/bin:$APPLAUNCHER_DIR:/bin/Python:/cmn/git/Slicer4-sb/python-build/lib/python2.6/site-packages:$APPLAUNCHER_DIR/lib/Slicer-4.0/qt-loadable-modules/.:$APPLAUNCHER_DIR/lib/Slicer-4.0/qt-loadable-modules/Python TCL_LIBRARY/cmn/git/Slicer4-sb/tcl-build/lib/tcl8.4 TK_LIBRARY/cmn/git/Slicer4-sb/tcl-build/lib/tk8.4 TCLLIBPATH/cmn/git/Slicer4-sb/tcl-build/lib/itcl3.2:/cmn/git/Slicer4-sb/tcl-build/lib/itk3.2 export QTPLUGIN_PATH$QT_PLUGIN_PATH export SLICER_HOME$SLICER_HOME export PYTHONHOME$PYTHONHOME export PYTHONPATH$PYTHONPATH export TCL_LIBRARY$TCL_LIBRARY export TK_LIBRARY$TK_LIBRARY export TCLLIBPATH$TCLLIBPATH export LD_LIBRARY_PATH$LD_LIBRARY_PATH exec $脚本末尾的exec $是关键GDB 的exec-wrapper机制会用脚本 被调试程序作为命令执行真实进程成为脚本的子进程exec保证 GDB attach 到的就是它本身。分析段错误Segmentation Fault在构建树中复现并加载 core$ ulimit -c unlimited $ ./Slicer ... make it crash $ ./Slicer --gdb ./bin/SlicerApp-real (gdb) core core (gdb) backtrace ...在已安装的 Slicer 中$ ulimit -c unlimited $ ./Slicer ... make it crash $ ./Slicer --launch bash $ gdb ./bin/SlicerApp-real (gdb) core core (gdb) backtrace ...已安装版本用--launch bash开一个继承 Slicer 环境的 shell再在其中启动 GDB 加载SlicerApp-real对应的 core 文件。注意GDB 自身依赖 Python而 GDB 链接的 Python 与 Slicer 自带的 Python 并非同一套可能造成启动问题。若 GDB 因缺少_sysconfigdata__linux_x86_64-linux-gnu.py而无法启动需要把 Slicer 的 sysconfigdata 文件复制为期望的文件名例如cd ~/Slicer-4.13.0-2021-09-10-linux-amd64/lib/Python/lib/python3.6 cp _sysconfigdata_m_linux2_.py _sysconfigdata__linux_x86_64-linux-gnu.pysystemd 系统上的 coredump 处理在启用 systemd 的发行版中coredump 由 systemd 的 coredump 守护进程接管以.lz4压缩格式存储在/var/lib/systemd/coredump/core.SlicerApp-real.xxxx.lz4即使设置了ulimit -c unlimitedcoredump 仍可能被截断truncated。用coredumpctl list查看最近的 coredump 及对应 PIDcoredumpctl list Thu 2018-05-24 16:37:46 EDT 22544 1000 1000 11 missing /usr/lib/firefox/firefox Fri 2018-05-25 15:50:52 EDT 14721 1000 1000 6 truncated /path/Slicer-build/bin/SlicerApp-real Mon 2018-05-28 11:35:43 EDT 17249 1000 1000 6 present /path/Slicer-build/bin/SlicerApp-real若状态为truncated可修改/etc/systemd/coredump.conf提高默认最大文件尺寸[Coredump] #Storageexternal #Compressyes ProcessSizeMax8G ExternalSizeMax8G JournalSizeMax6G #MaxUse #KeepFree修改后再次触发崩溃core 文件状态应变为present。随后用coredumpctl直接拉起 GDB不带 PID 时默认使用最新一个 coredumpcoredumpctl gdb $PID若要在其他 IDE 或 ddd 中使用需先解压 coredump可通过修改coredump.conf的Compress选项或直接导出coredumpctl dump $PID /tmp/corefile进一步跨平台 IDE 调试文档最后指出上述 GDB 工作流可与 IDE 集成仓库中对应有三篇姊妹篇文档可继续深入Debugging using CodeLiteDebugging using Qt CreatorDebugging using Visual Studio Code其中 Qt Creator 篇给出了典型做法先用./Slicer --launch /path/to/qtcreator启动 IDE 以继承 Slicer 环境这正是前文--launch选项的应用再打开CMakeLists.txt选择 Slicer-build 目录进行构建配置。总结四种方式的选择依据| 场景 | 推荐方式 | | | | | 快速对运行中的 Slicer 下断点 |--attach-processgdb --pid需先放开 yama ptrace_scope | | 需要带 Slicer 环境的手动调试 |Slicer --gdb或Slicer --launch bash| | 不想预先启动 Slicer让 GDB 全程托管 |set follow-fork-mode child跟随 fork | | IDE 集成、需要完整控制 GDB 生命周期 | exec-wrapper 包装脚本 | | 程序已崩溃只剩 core 文件 |ulimit -c unlimited复现 core/backtracesystemd 系统改用coredumpctl|所有流程的共同前提是要清楚Slicerlauncher与SlicerApp-real真实进程的分工断点、符号、core 分析都必须针对后者进行而 launcher 的价值在于替你准备好一整套可复现的调试环境。赞分享医疗健康图像处理数据可视化桌面应用3D渲染【免费下载链接】SlicerMulti-platform, free open source software for visualization and image computing.项目地址https://gitcode.com/gh_mirrors/sl/Slicer点击查看免费下载相关推荐Ceph 开发环境 GDB 调试指南附加运行进程与 Teuthology 故障分析Ceph 开发环境 GDB 调试指南附加运行进程与 Teuthology 故障分析 GDBGNU Project Debugger是分析进程执行流程、定位存储分布式文件系统对象存储后端高可用tflite-micro 在 QEMU 上运行 Cortex-M 单元测试环境搭建、测试执行与 GDB 调试实战指南tflite micro 在 QEMU 上运行 Cortex M 单元测试环境搭建、测试执行与 GDB 调试实战指南 本篇技术指南以 qemu.md http人工智能深度学习推理引擎本地部署嵌入式物联网UE4SS C Mod 调试实战使用 await_debugger 附加调试器逐行排查UE4SS C Mod 调试实战使用 await_debugger 附加调试器逐行排查 本文面向 UE4SS C Mod 开发者当日志输出不足以定位游戏开发逆向工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

基于向量数据库与感知哈希的本地视频检索与去重

基于向量数据库与感知哈希的本地视频检索与去重

简介:这是一款基于脚本语言实现的JAV元数据爬取与管理工具,面向需要自动化采集、整理视频站点数据的开发者和自建媒体库用户,核心是解决资源分散、检索不便的问题。项目具备在线播放、全自动爬取下载上传处理能力,视频与图片数据不…

2026/10/13 13:59:47 阅读更多 →
目标跟踪评估指标详解:从中心位置误差到成功率曲线的MATLAB实现

目标跟踪评估指标详解:从中心位置误差到成功率曲线的MATLAB实现

做目标跟踪的同学应该都有过这种感觉:算法自己跑起来看着“挺稳的”,框跟得很顺,偶尔目标晃两下也能拉回来。但一旦放到公开评测集上跑一遍,看到排名表上那些指标,心里落差很大。这不是算法不行,而是你还没…

2026/10/13 13:59:47 阅读更多 →
如何给AI Agent仪表盘上锁:TenacitOS认证、登录限流与安全终端机制源码剖析

如何给AI Agent仪表盘上锁:TenacitOS认证、登录限流与安全终端机制源码剖析

前端AI 应用数据可视化 【免费下载链接】tenacitOS OpenClaw Mission Control Dashboard 项目地址: https://gitcode.com/gh_mirrors/te/tenacitOS 点击查看 免费下载 TenacitOS 是面向 OpenClaw AI Agent 实例的 Mission Control 仪表盘(AI Agent 仪表…

2026/10/13 13:59:47 阅读更多 →

最新新闻

TokenTracker:轻量嵌入式LLM Token用量治理工具

TokenTracker:轻量嵌入式LLM Token用量治理工具

1. 这不是又一个“统计面板”,而是一套嵌入式 token 使用量治理闭环你有没有遇到过这样的场景:团队里三个项目共用一套大模型 API 接口,但没人知道谁在调用、调了多少、哪次请求耗 token 最狠?某天账单突然翻倍,排查时…

2026/10/13 15:26:05 阅读更多 →
莫代尔棉内衣:科技纤维的舒适性与耐用性解析

莫代尔棉内衣:科技纤维的舒适性与耐用性解析

1. 莫代尔棉内衣的核心特性解析莫代尔纤维作为21世纪纺织行业的重要创新,本质上是一种再生纤维素纤维。与普通粘胶纤维不同,它采用特殊的纺丝工艺处理榉木浆粕,纤维结晶度和取向度更高。这种分子结构决定了其独特的性能表现——在电子显微镜下…

2026/10/13 15:26:05 阅读更多 →
MFCC特征提取的工程本质:参数选择与matlab实现

MFCC特征提取的工程本质:参数选择与matlab实现

简介:本资源是一份完整的梅尔倒谱系数(MFCC)MATLAB实现代码包,面向语音信号处理初学者、高校课程设计学生及语音识别方向的工程实践者,用于快速掌握MFCC特征提取的核心原理与编程实现。包内共23个文件,涵盖…

2026/10/13 15:26:05 阅读更多 →
教学设备管理系统开发实战:从台账编码到扫码流程落地

教学设备管理系统开发实战:从台账编码到扫码流程落地

简介:教学设备管理系统是一套源自《Visual C项目开发案例精粹》的软件应用案例,面向正在学习C/MFC与数据库开发的读者,帮助理解教育机构如何对设备信息、类别和借用归还记录进行数字化管理,覆盖从设备档案录入、查询修改到借用归还…

2026/10/13 15:26:05 阅读更多 →
FCQA:轻量级结构化文档问答对自动生成框架

FCQA:轻量级结构化文档问答对自动生成框架

简介:本资源是一个基于Stylus构建的前端问答系统项目(fcqa),面向Web前端开发者与AI应用实践者,聚焦于全周期问答功能的界面实现与样式工程化管理。项目采用Stylus作为核心样式语言,结合CSS模块化设计思想&a…

2026/10/13 15:26:05 阅读更多 →
GNN应用部署实战:从单机脚本到线上服务的构建与扩展

GNN应用部署实战:从单机脚本到线上服务的构建与扩展

1. 从单机脚本到线上服务:GNN应用部署到底难在哪很多人做图神经网络,卡在的不是模型结构,而是从“跑通一个demo”到“别人能访问的服务”这一步。前面几篇我们把数据准备、邻接矩阵构建、模型搭建、训练调参都过了一遍,但真正把GN…

2026/10/13 15:25:03 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →