Skip to content

fix: improve process name resolution for DBus clients - #154

Merged
18202781743 merged 1 commit into
linuxdeepin:masterfrom
18202781743:master
Jul 14, 2026
Merged

fix: improve process name resolution for DBus clients#154
18202781743 merged 1 commit into
linuxdeepin:masterfrom
18202781743:master

Conversation

@18202781743

@18202781743 18202781743 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor
  1. Change process name detection to prefer /proc/{pid}/exe symlink for
    accuracy
  2. Add fallback to /proc/{pid}/cmdline on permission errors (daemon runs
    as deepin-daemon)
  3. Ensure command line content is non-empty before returning
  4. In getAppid(): avoid caching stale app names across different DBus
    services
  5. Move m_appName assignment outside the isEmpty guard to refresh per
    connection
  6. Always return testappid only when not called from DBus

Log: Improved process identification for DConfig clients

Influence:

  1. Test DConfig access from multiple DBus services with different PIDs
  2. Verify process name is correctly resolved for processes with
    permission constraints
  3. Verify cached app name is refreshed when the same connection handles
    different DBus services
  4. Confirm fallback to PID number when both exe and cmdline fail
  5. Test non-DBus calls (e.g., unit tests) return "testappid" correctly

fix: 改进DBus客户端的进程名称解析

  1. 将进程名称检测改为优先使用 /proc/{pid}/exe 符号链接以提高准确性
  2. 在权限错误时回退到 /proc/{pid}/cmdline(守护进程以deepin-daemon身份
    运行)
  3. 确保命令行内容非空后才返回
  4. 在getAppid()中:避免在不同DBus服务间缓存过时的应用名称
  5. 将m_appName赋值移出isEmpty检查,确保每个连接刷新
  6. 仅在非DBus调用时返回"testappid"

Log: 改进DConfig客户端的进程识别功能

Influence:

  1. 测试从多个不同DBus服务访问DConfig,验证PID正确
  2. 验证受限权限下进程名称能正确解析
  3. 验证同一连接处理不同DBus服务时,缓存的app名称刷新
  4. 确认当exe和cmdline都失败时回退到PID
  5. 测试非DBus调用(如单元测试)正确返回"testappid"

Summary by Sourcery

Improve process name resolution for DConfig DBus clients and adjust app ID handling for DBus vs non-DBus connections.

Bug Fixes:

  • Ensure process name detection falls back to a non-empty /proc/{pid}/cmdline and ultimately to the PID when resolution fails.
  • Prevent stale cached app IDs from being reused across different DBus services on the same connection.
  • Ensure non-DBus callers consistently receive a fixed test app ID instead of reusing DBus-derived names.

Enhancements:

  • Prefer the /proc/{pid}/exe symlink for more accurate process name resolution on Linux.
  • Track the last DBus service per connection to refresh the cached app name only when the service changes.

1. Change process name detection to prefer /proc/{pid}/exe symlink for
accuracy
2. Add fallback to /proc/{pid}/cmdline on permission errors (daemon runs
as deepin-daemon)
3. Ensure command line content is non-empty before returning
4. In getAppid(): avoid caching stale app names across different DBus
services
5. Move m_appName assignment outside the isEmpty guard to refresh per
connection
6. Always return testappid only when not called from DBus

Log: Improved process identification for DConfig clients

Influence:
1. Test DConfig access from multiple DBus services with different PIDs
2. Verify process name is correctly resolved for processes with
permission constraints
3. Verify cached app name is refreshed when the same connection handles
different DBus services
4. Confirm fallback to PID number when both exe and cmdline fail
5. Test non-DBus calls (e.g., unit tests) return "testappid" correctly

fix: 改进DBus客户端的进程名称解析

1. 将进程名称检测改为优先使用 /proc/{pid}/exe 符号链接以提高准确性
2. 在权限错误时回退到 /proc/{pid}/cmdline(守护进程以deepin-daemon身份
运行)
3. 确保命令行内容非空后才返回
4. 在getAppid()中:避免在不同DBus服务间缓存过时的应用名称
5. 将m_appName赋值移出isEmpty检查,确保每个连接刷新
6. 仅在非DBus调用时返回"testappid"

Log: 改进DConfig客户端的进程识别功能

Influence:
1. 测试从多个不同DBus服务访问DConfig,验证PID正确
2. 验证受限权限下进程名称能正确解析
3. 验证同一连接处理不同DBus服务时,缓存的app名称刷新
4. 确认当exe和cmdline都失败时回退到PID
5. 测试非DBus调用(如单元测试)正确返回"testappid"
@18202781743
18202781743 requested review from BLumia and mhduiy July 14, 2026 03:36
@sourcery-ai

sourcery-ai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Reviewer's Guide

Improves DConfig daemon process name resolution for DBus clients by preferring /proc/{pid}/exe with a robust fallback strategy, and fixes app ID caching so that application names are refreshed per DBus service and test calls consistently return a static app ID.

Sequence diagram for updated DSGConfigConn::getAppid behavior

sequenceDiagram
    participant Client
    participant DSGConfigConn
    participant DBusConnection as QDBusConnection
    participant DBusInterface as QDBusConnectionInterface

    Client->>DSGConfigConn: getAppid
    alt calledFromDBus
        DSGConfigConn->>DSGConfigConn: calledFromDBus
        DSGConfigConn->>DSGConfigConn: message
        DSGConfigConn->>DSGConfigConn: compare m_lastService with service
        alt m_lastService != service
            DSGConfigConn->>DBusConnection: connection
            DBusConnection->>DBusInterface: servicePid service
            DBusInterface-->>DSGConfigConn: pid
            DSGConfigConn->>DSGConfigConn: getProcessNameByPid pid
            DSGConfigConn->>DSGConfigConn: update m_lastService and m_appName
        end
        DSGConfigConn-->>Client: m_appName
    else not calledFromDBus
        DSGConfigConn-->>Client: QString testappid
    end
Loading

Flow diagram for updated getProcessNameByPid logic

flowchart TD
    A[Start getProcessNameByPid pid] --> B[QFile::symLinkTarget /proc/pid/exe]
    B --> C{exePath is empty?}
    C -- No --> D[return exePath]
    C -- Yes --> E[Open /proc/pid/cmdline]
    E --> F{file opened?}
    F -- No --> I[return QString::number pid]
    F -- Yes --> G[readLine and build cmd]
    G --> H{cmd is empty?}
    H -- No --> J[return cmd]
    H -- Yes --> I[return QString::number pid]
Loading

File-Level Changes

Change Details Files
Improve Linux process name resolution by preferring /proc/{pid}/exe with a safer /proc/{pid}/cmdline fallback and non-empty validation.
  • Add QFileInfo include to support filesystem-related operations if needed.
  • Change getProcessNameByPid() to resolve the /proc/{pid}/exe symlink first and return it when available.
  • On failure or empty exe path, open /proc/{pid}/cmdline and build the command string from NUL-separated arguments.
  • Ensure the command string is non-empty before returning; otherwise fall back to returning the PID as a string.
dconfig-center/dde-dconfig-daemon/dconfig_global.h
Fix DBus app ID resolution and caching so it updates per DBus service and only uses the test app ID for non-DBus calls.
  • Modify getAppid() to first check if the call originates from DBus and, if so, derive the service from the incoming message.
  • Introduce m_lastService to track the last DBus service used for app name resolution.
  • When the DBus service changes, update m_lastService and refresh m_appName using getProcessNameByPid(servicePid(service)).
  • Return m_appName for DBus calls and a hardcoded "testappid" only for non-DBus calls.
  • Add m_lastService as a new member field to DSGConfigConn and remove the previous m_appName.isEmpty() cache guard.
dconfig-center/dde-dconfig-daemon/dconfigconn.cpp
dconfig-center/dde-dconfig-daemon/dconfigconn.h

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In getProcessNameByPid(), returning QFile::symLinkTarget("/proc/%1/exe") will give the full executable path rather than just the process name; if the intent is to keep the previous behavior (a short name), consider wrapping it with QFileInfo(exePath).fileName().
  • The new m_lastService cache in getAppid() only invalidates when the service string changes; if a DBus service can respawn with a new PID but reuse the same service name, you may still end up with a stale m_appName and should consider keying the cache on PID (or service+PID) instead.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In getProcessNameByPid(), returning QFile::symLinkTarget("/proc/%1/exe") will give the full executable path rather than just the process name; if the intent is to keep the previous behavior (a short name), consider wrapping it with QFileInfo(exePath).fileName().
- The new m_lastService cache in getAppid() only invalidates when the service string changes; if a DBus service can respawn with a new PID but reuse the same service name, you may still end up with a stale m_appName and should consider keying the cache on PID (or service+PID) instead.

## Individual Comments

### Comment 1
<location path="dconfig-center/dde-dconfig-daemon/dconfigconn.cpp" line_range="244-245" />
<code_context>
 QString DSGConfigConn::getAppid() const
 {
-    if (m_appName.isEmpty()) {
-        if (calledFromDBus()) {
-            const QString &service = message().service();
+    if (calledFromDBus()) {
+        const QString &service = message().service();
+        if (m_lastService != service) {
+            const_cast<DSGConfigConn *>(this)->m_lastService = service;
             const_cast<DSGConfigConn *>(this)->m_appName = getProcessNameByPid(connection().interface()->servicePid(service));
</code_context>
<issue_to_address>
**issue (bug_risk):** Caching only on service name changes may miss updates when the PID behind a well-known service changes.

Because m_appName is updated only when the DBus service string changes, a well-known service that gets re-bound to a different process can end up with a new PID but the same service name. In that case, m_appName would still refer to the old process. If this value is used for logging, auditing, or access control, the stale mapping could be misleading.

To avoid this, consider also caching the last PID (e.g., m_lastPid) and refreshing m_appName when either the service name or its PID changes, so restarts behind a stable service name are handled correctly.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread dconfig-center/dde-dconfig-daemon/dconfigconn.cpp
@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

★ 总体评分:85分

■ 【总体评价】

代码修复了多客户端复用连接时appid缓存串号的严重逻辑缺陷,并优化了进程名获取方式,但存在const_cast滥用和返回值语义变更的代码质量问题。
逻辑正确性显著提升但因代码质量问题扣15分

■ 【详细分析】

  • 1.语法逻辑(基本正确)✓

dconfigconn.cpp 中的 getAppid() 修复了原逻辑中 m_appName 一旦赋值不再更新的缺陷,通过新增 m_lastService 判断调用方变化,逻辑正确。dconfig_global.h 中的 getProcessNameByPid 优先使用 /proc/{pid}/exe 符号链接,失败回退到 cmdline,逻辑闭环。但 getProcessNameByPid 的返回值由原来的完整命令行变更为可执行文件绝对路径,可能影响下游依赖原返回值格式的逻辑。
潜在问题:getProcessNameByPid 返回值语义变更可能导致下游匹配失败;getAppid() 中使用 const_cast 修改成员变量虽然能编译,但破坏了常量正确性。
建议:如果下游需要纯进程名,应在 getProcessNameByPid 中对 exePath 使用 QFileInfo(exePath).fileName() 提取文件名;将 m_appNamem_lastService 声明为 mutable 以替代 const_cast

  • 2.代码质量(一般)✕

dconfigconn.cppgetAppid() 函数内多次使用 const_cast<DSGConfigConn *>(this) 来修改成员变量,这是一种反模式,降低了代码可维护性。dconfigconn.h 中删除了文件末尾的空行,虽然不影响编译,但不符合常规的文件结尾规范。
潜在问题:const_cast 掩盖了设计意图,使得 const 成员函数实际上修改了对象状态,容易引发误解。
建议:在 dconfigconn.h 中将 m_appNamem_lastService 声明为 mutable QString,然后在 getAppid() 中直接赋值,移除 const_cast

  • 3.代码性能(良好)✓

getAppid() 中仅在 m_lastService 与当前 service 不一致时才调用 getProcessNameByPid 进行系统调用,避免了每次 DBus 调用都读取 /proc 文件系统,缓存策略合理。getProcessNameByPidQFile::symLinkTarget 的系统调用开销也低于读取并解析文件内容。
潜在问题:无
建议:无需额外优化。

  • 4.代码安全(存在0个安全漏洞)✓

漏洞对比统计:新增漏洞 0 个,减少漏洞 0 个,持平 0 个
本次修改修复了原有的 appid 缓存串号问题,避免了多客户端复用连接时权限校验错乱的风险,提升了安全性。未引入新的注入、溢出等安全漏洞。输入源 pid 来自 DBus 守护进程,不可直接控制。

  • 建议:无需额外修复。

■ 【改进建议代码示例】

// dconfigconn.h
    QString m_appName;
    QString m_lastService;
    // 建议修改为:
    mutable QString m_appName;
    mutable QString m_lastService;
};

// dconfigconn.cpp
QString DSGConfigConn::getAppid() const
{
    if (calledFromDBus()) {
        const QString &service = message().service();
        if (m_lastService != service) {
            m_lastService = service;
            m_appName = getProcessNameByPid(connection().interface()->servicePid(service));
        }
        return m_appName;
    }
    return QString("testappid");
}

// dconfig_global.h
inline QString getProcessNameByPid(const uint pid)
{
#ifdef Q_OS_LINUX
    // Prefer /proc/{pid}/exe symlink for process name.
    // May fail due to permission (daemon runs as deepin-daemon, target process
    // may belong to another user). Fallback to /proc/{pid}/cmdline in that case.
    const QString exePath = QFile::symLinkTarget(QString("/proc/%1/exe").arg(pid));
    if (!exePath.isEmpty()) {
        // 建议提取纯文件名以保持一致性,或根据下游需求决定是否保留路径
        return QFileInfo(exePath).fileName();
    }

    // Fallback: /proc/{pid}/cmdline is world-readable (0444)
    const QString cmdlinePath = QString("/proc/%1/cmdline").arg(pid);
    QFile file(cmdlinePath);
    if (file.open(QIODevice::ReadOnly)) {
        const QByteArray &name = file.readLine();
        const QString cmd = name.split('\0').join(" ").trimmed();
        if (!cmd.isEmpty())
            return cmd;
    }
#endif // Q_OS_LINUX
    return QString::number(pid);
}

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, BLumia

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

@18202781743
18202781743 merged commit 8b01fc8 into linuxdeepin:master Jul 14, 2026
23 checks passed
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.

3 participants