Skip to content

fix: prevent crash when QCamera initialization fails - #537

Draft
re2zero wants to merge 109 commits into
linuxdeepin:masterfrom
re2zero:agent/agent/69970d504b15
Draft

re2zero wants to merge 109 commits into
linuxdeepin:masterfrom
re2zero:agent/agent/69970d504b15

Conversation

@re2zero

@re2zero re2zero commented Oct 29, 2026

Copy link
Copy Markdown
Contributor

Root Cause Analysis

When a UVC camera device control query times out (GET_MAX returns -110 ETIMEDOUT),
QCamera construction fails internally, leaving its private state invalid. In
startCamera() (src/src/camera.cpp:244), QCameraInfo cameraInfo(*m_camera)
is constructed immediately after new QCamera() without any error check, causing
a null pointer dereference at offset 8 (segfault at 8) inside libQt5Core.so.
The same QCameraInfo(*m_camera) pattern in restartCamera() (camera.cpp:136)
has an identical risk.

Fix Approach

Added QCamera::error() check after new QCamera() in startCamera() — on
error, clean up via stopCamera(), emit cameraCannotUsed(), and return early.
Connected QCamera::error signal to cameraCannotUsed() so runtime errors are
also handled. QCameraInfo is only constructed when QCamera is in a valid
state. Applied the same error() guard in restartCamera() before
QCameraInfo(*m_camera) construction.

Change Safety Assessment

Code Safety

  • Risk Level: Low
  • Only adds null check / early return and signal connection; no function
    signature changes, no public member modifications, no behavior change on
    the normal path
  • Does not revert any historical fix; 4e4a444 (unplug crash fix) addressed a
    different code path and remains intact

Business Impact Scope

Affects camera initialization and device hot-plug/restart paths. When camera
hardware initialization fails (e.g., UVC timeout via USB passthrough), the app
emits cameraCannotUsed() and recovers gracefully instead of crashing. Valid
camera devices are unaffected.

Verification Suggestion

Test camera open with a working UVC camera (normal path should be unchanged).
Simulate camera initialization failure (e.g., faulty USB passthrough device)
and verify the app shows "camera unavailable" instead of crashing.


根因分析

当 UVC 相机设备控制查询超时(GET_MAX 返回 -110 ETIMEDOUT)时,QCamera 构造函数内部
初始化失败,私有状态无效。startCamera()(src/src/camera.cpp:244)在 new QCamera()
后未做任何错误检查即构造 QCameraInfo cameraInfo(*m_camera),导致 libQt5Core.so 内部
空指针解引用(segfault at 8)。restartCamera()(camera.cpp:136)中的
QCameraInfo(*m_camera) 存在相同风险。

修复方案

在 startCamera() 的 new QCamera() 后增加 QCamera::error() 检查——错误时通过
stopCamera() 清理、发出 cameraCannotUsed() 信号并提前返回。连接 QCamera::error
信号到 cameraCannotUsed() 以处理运行时错误。仅在 QCamera 有效时才构造
QCameraInfo。在 restartCamera() 的 QCameraInfo(*m_camera) 构造前同步增加
error() 检查。

改动安全评估

代码安全评估

  • 风险等级: 低风险
  • 仅增加空指针检查 / 提前返回和信号连接,不改变函数签名、不修改公开成员、
    正常路径无行为变化
  • 不撤销任何历史修复;4e4a444(拔摄像头崩溃修复)覆盖不同代码路径,不受影响

业务影响范围

影响相机初始化和设备热插拔/重启路径。当相机硬件初始化失败(如 USB 透传环境下 UVC
超时)时,应用发出 cameraCannotUsed() 信号并优雅恢复,而非崩溃。有效相机设备不受影响。

验证建议

使用正常 UVC 相机测试打开功能(验证正常路径无回归)。模拟相机初始化失败(如故障 USB
透传设备),验证应用提示"相机不可用"而非崩溃。

feeengli and others added 30 commits January 11, 2023 06:53
添加h264编码器检测,不存在时不支持mp4视频录制

Log: 添加h264编码器检测,不存在时不支持mp4视频录制
判断库函数是否导出成功

Log: 判断库函数是否导出成功
通过正则表达式匹配libavcodec库文件

Log: 通过正则表达式匹配libavcodec库文件

Bug: https://pms.uniontech.com/bug-view-183421.html
去除多余连接

Bug: https://pms.uniontech.com/bug-view-177273.html
Log: 修复部分已知问题
更新changlog

Log: 更新changlog
添加翻译配置文件

Log: 添加翻译配置文件
new version 1.4.10

Log: modify changelog
设置初始位置为标题栏

Bug: https://pms.uniontech.com/bug-view-120099.html
Log: 修复部分已知问题
New tag 1.4.11

Log: New tag 1.4.11
修复wayland锁屏后拔插摄像头,解锁后点击录像按钮崩溃

Log: 修复wayland锁屏后拔插摄像头崩溃问题

Bug: https://pms.uniontech.com/bug-view-198571.html
修复锁屏后快速解锁,相机崩溃问题

Log: 修复锁屏后快速解锁,相机崩溃问题

Bug: https://pms.uniontech.com/bug-view-198939.html
New version 1.4.12

Log: new version 1.4.12
sync by github workflow

Log: none
Influence: none
修复最小化后无法通过全局搜索唤醒

Log: 修复最小化后无法通过全局搜索唤醒

Bug: https://pms.uniontech.com/bug-view-200273.html
new version 1.4.13

Log: new version 1.4.13
通过kwayland接口获取wayland下窗口信息,当全屏覆盖相机时停止录像

Bug: https://pms.uniontech.com/bug-view-102292.html
Log: 修复部分已知问题
Update changelog

Log: Update changelog
当环境无版本文件时不查找

Log: 修复部分已知问题
去除多余依赖

Log: 修复部分已知问题
Update changelog

Log: Update changelog
规避USB声卡端口状态正常,但无法获取音频数据时,点击结束录像崩溃问题

Log: 规避USB声卡端口状态正常,但无法获取音频数据时录像崩溃问题

Bug: https://pms.uniontech.com/bug-view-207319.html
修复wayland下接口未定义

Log: 修复wayland下接口未定义
Update changelog

Log: Update changelog
获取分辨率时过滤异常分辨率

Log: 修复部分已知问题
Optimize preview efficiency

Log: Optimize preview efficiency
  base master1698f2b6 into eagle

Log: master into eagle
the correct get the product machine name

Log: the correct get the product machine name
Bug: https://pms.uniontech.com/bug-view-267231.html
mask the 7d55 for encoder

Log: make the video record use softencode

Bug: https://pms.uniontech.com/bug-view-278369.html
Resurgamz and others added 23 commits April 30, 2026 13:34
bump version

Log: bump version
…reaWidget

Add setIconOpacity(1) calls for flashlight, delay, filters, and exposure buttons when entering photo mode to restore correct visual state

修复(ui): 拍照模式下恢复按钮图标透明度状态

进入拍照模式时对闪光灯、延迟拍摄、滤镜、曝光按钮调用 setIconOpacity(1), 恢复按钮图标正常透明度显示

Log: 修复拍照模式按钮图标透明度异常
Bug: https://pms.uniontech.com/bug-view-196565.html
… photo setting area

  - Change scrollLayout spacing from 2px to 0px to eliminate visible gaps between filter preview
  buttons
  - The 2px spacing combined with WA_TranslucentBackground caused the underlying viewport background
  to show through, creating transparent separator lines between each filter option

  修复(ui): 去掉拍照设置区域滤镜按钮之间的透明分割线

  - 将 scrollLayout 间距从 2px 改为 0px,消除滤镜预览按钮之间的可见间隙
  - 2px 间距与 WA_TranslucentBackground 配合导致下层 viewport
  背景透出,在每个滤镜选项之间形成透明分割线

  Log: 去掉滤镜选择面板中各滤镜之间的透明分割线,将 QVBoxLayout 间距从 2px 改为 0px
  Bug: https://pms.uniontech.com/bug-view-160651.html
  ON 阶段 setData 触发 DTK widget 重建时读到 OFF 阶段清零的 value=0,
  中间态的 resolutionchanged 异步将相机切到错误分辨率,settingDialog 重新打开时
  以相机当前错误分辨率覆盖了已保存的用户选择。

  - ON 分支用 m_updatingResolution 标志抑制 setData/setOption 的中间态信号,
    QTimer::singleShot 在所有排队信号处理后发射一次正确值
  - settingDialog 优先读 option 已保存值,设备分辨率作为 fallback
  - switchCameraSuccess 连接 setNewResolutionList,启动和重连均触发 ON 分支恢复
  - switchCameraSuccess 无条件发射,构造函数路径也能进入 ON 分支

  Log: 修复摄像头重连和应用重启后分辨率恢复为默认值
  Bug: https://pms.uniontech.com/bug-view-363077.html
  setNewResolutionList 排序条件使用了 <=,相同宽度时无条件交换,
  导致排序结果与 settingDialog 不一致。摄像头重连后保存的索引值
  在重新打开设置界面时映射到了错误的分辨率(如 640x480 显示为 640x360)。

Log: 修复 setNewResolutionList 排序不一致导致分辨率索引错位
Bug: https://pms.uniontech.com/bug-view-363077.html
  当编码包大小超过输出缓冲区时,替换原有的静默丢弃行为为动态扩容(1.5倍                                增长),最大分配上限为 max(width*height/2, 2MB),防止内存无限增长。

  Log: 修复编码器输出缓冲区溢出时静默丢帧的问题
  Bug: https://pms.uniontech.com/bug-view-345769.html
Log: 支持通过配置标记低性能设备
Bug: https://pms.uniontech.com/bug-view-358869.html
Influence: 可通过配置直接识别低性能设备,优化低性能设备判断逻辑。
  将原先在 enum_v4l2_devices 中硬编码的摄像头卡片关键字迁移到
  org.deepin.camera.encode.json 的 CardKeywords 配置项中,并在启动时
  从 DConfig 读取后动态传递给 libcam 使用,支持后续通过配置增删过滤关键字。

Log: 将摄像头卡片过滤关键字设置为DConfig配置
Bug: https://pms.uniontech.com/bug-view-363739.html
Audio PTS was derived from the hardware device timestamp while video PTS
  used CLOCK_MONOTONIC, causing progressive A/V drift. Unify both to
  ns_time_monotonic(). Also preserve original_pts for the muxer to avoid
  precision loss from audio codec time_base rescaling.

log: fix bug

Bug:https://pms.uniontech.com/bug-view-363537.html
  Log: 修复摄像头被占用时仍显示倒计时的问题
  Bug: https://pms.uniontech.com/bug-view-364831.html
  Influence: 摄像头被其它应用占用时,点击拍照或录像不再显示0或负数倒计时;日志中的camera_connected仅在摄
  像头可用时记录为true。
Add DConfig option "useRgbData" to control whether YUV frames are
converted to RGB for preview rendering. Supports three modes:
-1: auto (default, let system decide)
0: force disable
1: force enable

添加DConfig配置项"useRgbData",控制预览时是否将YUV帧数据转换为RGB格式。
支持三态:-1自动判断(默认)、0强制关闭、1强制开启。

Log: 添加RGB预览模式配置项
PMS: BUG-366739
Influence: 通过DConfig配置可强制控制预览RGB数据的使用,便于排查特定机型显示异常问题。
When preferredResolution is set via DConfig, use it directly instead
of the locally cached resolution from config file on first launch.

DConfig的preferredResolution配置优先于本地配置文件中的分辨率,
修复首次打开应用时仍使用本地旧配置的问题。

Log: 修复preferredResolution首次启动不生效的问题
PMS: BUG-366203
Influence: 设置preferredResolution后首次启动即可生效,无需重启两次。
Added a .gitignore file to exclude common C++ object files, Qt build
artifacts, and QtCreator-specific configurations. This prevents
generated files and local IDE settings from being accidentally
committed to the repository.
Replace QSound with QSoundEffect and silently warm the audio stream before playing each shutter sound.\n\n使用 QSoundEffect 替换 QSound,并在播放快门音前静音预热音频流。\n\nLog: 修复快门音首声音量偏小的问题\nPMS: https://pms.uniontech.com/bug-view-369937.html\nInfluence: 空闲后的快门声音量正常,且不维持持续音频流。
Sync my_config width/height with actual values after
v4l2core_prepare_new_resolution to avoid config mismatch.

在 v4l2core_prepare_new_resolution 调用后同步 my_config 的
宽高配置,避免配置值与实际分辨率不一致。

Log: 同步分辨率配置
PMS: BUG-372317
Influence: 修复相机分辨率配置与实际设置不同步的问题,确保配置文件记录的分辨率与实际使用的分辨率一致。
sync by github workflow

Log: none
Influence: none
Do not preset decoder width/height before avcodec_open2(); let FFmpeg
parse the real size from the JPEG SOF header. Copy decoded frames using
the actual sw_frame/picture dimensions and realloc buffers when needed.
Add jpeg_get_decoded_size() and trim yuv_frame to the real decoded size.

不在 avcodec_open2() 前预设解码器宽高,改由 FFmpeg 从 JPEG SOF 头解析
真实尺寸。按实际解码帧尺寸拷贝并在需要时 realloc 缓冲。新增
jpeg_get_decoded_size(),并在首帧后将 yuv_frame 收紧到真实解码尺寸。

Log: 修复MJPG解码尺寸与协商分辨率不一致导致的解码失败和画面错位
PMS: BUG-372317
Influence: 修复相机协商与实际分辨率不一致导致的解码失败、画面错位及内存浪费。
1. Root cause: startCamera() constructs QCameraInfo from a QCamera
   object immediately after creation without checking error state;
   when UVC control query times out (GET_MAX returns -110), the
   QCamera internal state is invalid and QCameraInfo dereferences
   a null pointer, causing segfault at offset 8
2. Fix: add QCamera::error() check after construction, clean up and
   return early on error; connect QCamera::error signal to emit
   cameraCannotUsed; only construct QCameraInfo when QCamera is
   valid; apply same error() guard in restartCamera() before
   QCameraInfo construction
3. Impact: camera initialization failures are handled gracefully
   instead of crashing; no behavior change for valid camera devices

fix: 修复QCamera初始化失败时的段错误问题

1. 根因:startCamera()在new QCamera()后未检查错误状态即构造
   QCameraInfo,当UVC控制查询超时(GET_MAX返回-110)时QCamera内部
   状态无效,QCameraInfo解引用空指针导致段错误
2. 方案:构造后增加error()检查,错误时清理并提前返回;连接
   QCamera::error信号以发出cameraCannotUsed;仅在QCamera有效时
   构造QCameraInfo;restartCamera()中同类QCameraInfo构造同步
   增加error()检查
3. 影响:相机初始化失败时优雅处理而非崩溃,对有效设备无行为变化

PMS: BUG-236931
@sourcery-ai

sourcery-ai Bot commented Oct 29, 2026

Copy link
Copy Markdown

Sorry @re2zero, your pull request is larger than the review limit of 150,000 diff characters

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: re2zero

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@re2zero
re2zero marked this pull request as draft October 29, 2026 17:09
@github-actions

Copy link
Copy Markdown
  • 检测到敏感词dmidecode变动
详情
    {
    "dmidecode": {
        "src/main.cpp": [
            "        options << QString(QStringLiteral(\"dmidecode -t 11 | grep 'String 4' | awk '{print $NF}' && \"",
            "                                          \"dmidecode -s system-product-name|awk '{print $NF}'\"));"
        ]
    }
}

@github-actions

Copy link
Copy Markdown

TAG Bot

TAG: 6.0.13
EXISTED: no
DISTRIBUTION: unstable

@github-actions

Copy link
Copy Markdown

CLA Assistant Lite bot:

如果你是以企业贡献者的身份进行提交,请联系我们签署企业贡献者许可协议
If you submit as corporate contributor, please contact us to sign our Corporate Contributor License Agreement

感谢您的提交,我们非常感谢。 像许多开源项目一样,在接受您的贡献之前,我们要求您签署我们的个人贡献者许可协议。 您只需发布与以下格式相同的评论即可签署个人贡献者许可协议。
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you all sign our Individual Contributor License Agreement before we can accept your contribution. You can sign the Individual Contributor License Agreement by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA.

3 out of 4 committers have signed the CLA.
✅ pengfeixx
✅ wyu71
✅ LiHua000
❌ Resurgamz
deepin-admin-bot, shuaijie seem not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.