# Dbus相关工具及笔记 记录一些Dbus相关工具和调试时常用命令 ## 调试工具 ### D-feet/D-spy 用来检查D-bus接口的运行程序和调用接口的方法。可以显示service提供的所有对象、信号和方法,还可以通过它实现方法调用。在联网环境下直接命令行安装即可,优先推荐使用,图形化界面工具,想看哪里点哪里,简单易用。 ### qdbus 当在非联网环境下且系统中有qt组件时(deepin、麒麟等),大概率安装了该工具。 ```bash :~$ qdbus --system :1.0 org.freedesktop.timesync1 :1.1 org.freedesktop.resolve1 :1.10 org.freedesktop.login1 :1.11 org.freedesktop.Accounts ... ``` 操作比较简单想查看哪个接口直接在命令行后面加就行,不需要再添加其他参数: ```bash ~$ qdbus --system org.freedesktop.Accounts / /org /org/freedesktop /org/freedesktop/Accounts /org/freedesktop/Accounts/User1000 ~$ qdbus --system org.freedesktop.Accounts /org/freedesktop/Accounts method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface_name, QString property_name) method QVariantMap org.freedesktop.DBus.Properties.GetAll(QString interface_name) ... method QList org.freedesktop.Accounts.ListCachedUsers() method void org.freedesktop.Accounts.UncacheUser(QString name) signal void org.freedesktop.Accounts.UserAdded(QDBusObjectPath user) signal void org.freedesktop.Accounts.UserDeleted(QDBusObjectPath user) ... ~$ qdbus --literal --system org.freedesktop.Accounts /org/freedesktop/Accounts org.freedesktop.Accounts.ListCachedUsers [Argument: ao {[ObjectPath: /org/freedesktop/Accounts/User1000]}] ``` 该工具的不足之处在于只能列出当前正在运行的程序所提供的D-bus接口。 可以对比d-feet,d-feet接口栏中:正常字体的接口名称下面会显示 `activatable:yes,pid:XXX,cmd:XXXX`,这种是正在运行的;还有一种接口名称以斜体显示,名称下面只有 `activatable:yes`,这种是没有运行,但点击后d-feet会尝试激活该接口,若成功则可进一步查看该接口详细信息,若失败则会返回报错信息,最常见的是没有调用权限。 ### busctl Linux默认安装的D-bus命令行调试工具,和qdbus相比要添加更加精准的参数才会返回正确的结果否则报错,但可以查看没有正在运行程序的D-bus接口。用如下命令查看当前系统总线的接口: ```bash ~$ busctl --system ``` 使用tree参数可以列出目标接口的路径: ```bash ~$ busctl --system tree org.freedesktop.Accounts └─/org └─/org/freedesktop └─/org/freedesktop/Accounts └─/org/freedesktop/Accounts/User1000 ``` introspect参数可以查看对应路径下的内容: ```bash ~$ busctl --system introspect org.freedesktop.Accounts /org/freedesktop/Accounts NAME TYPE SIGNATURE RESULT/VALUE FLAGS org.freedesktop.Accounts interface - - - .CacheUser method s o - .CreateUser method ssi o - .DeleteUser method xb - - .FindUserById method x o - .FindUserByName method s o - .ListCachedUsers method - ao - .UncacheUser method s - - .AutomaticLoginUsers property ao 0 emits-change .DaemonVersion property s "0.6.55" emits-change .HasMultipleUsers property b false emits-change .HasNoUsers property b false emits-change .UserAdded signal o - - .UserDeleted signal o - - org.freedesktop.DBus.Introspectable interface - - - .Introspect method - s - org.freedesktop.DBus.Peer interface - - - .GetMachineId method - s - .Ping method - - - org.freedesktop.DBus.Properties interface - - - .Get method ss v - .GetAll method s a{sv} - .Set method ssv - - .PropertiesChanged signal sa{sv}as - - ``` 服务名称和路径是必选参数,接口是可选参数,加入接口名称则会显示当前接口下的方法、信号等: ```bash ~$ busctl --system introspect org.freedesktop.Accounts /org/freedesktop/Accounts org.freedesktop.Accounts NAME TYPE SIGNATURE RESULT/VALUE FLAGS .CacheUser method s o - .CreateUser method ssi o - .DeleteUser method xb - - .FindUserById method x o - .FindUserByName method s o - .ListCachedUsers method - ao - .UncacheUser method s - - .AutomaticLoginUsers property ao 0 emits-change .DaemonVersion property s "0.6.55" emits-change .HasMultipleUsers property b false emits-change .HasNoUsers property b false emits-change .UserAdded signal o - - .UserDeleted signal o - - ``` 调用接口使用call参数: ```bash ~$ busctl --system call org.freedesktop.Accounts /org/freedesktop/Accounts org.freedesktop.Accounts ListCachedUsers ao 1 "/org/freedesktop/Accounts/User1000" ``` > 老版本busctl 不能正确显示带有“重载”方法的服务详情会报错:"Duplicate method" > > 类似这种不能正常显示: > > ``` > .sendMessage method sass - - > .sendMessage method sasas - - > ``` > > 参考:https://github.com/AsamK/signal-cli/issues/219 > > 相关补丁:https://github.com/systemd/systemd/commit/f2f7785d7a47ffa48ac929648794e1288509ddd8 ### dbus-send 有D-bus服务就一定会有的调试工具,缺点是参数错误后没有有效的回显提示。这里不做详细阐述,列几个常用的命令。 查看当前系统的system bus: ```bash dbus-send --system --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListActivatableNames ``` 查看目标服务所提供的方法(method): ```bash dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.Accounts /org/freedesktop/Accounts org.freedesktop.DBus.Introspectable.Introspect method return time=1732266454.142110 sender=:1.11 -> destination=:1.5127 serial=243 reply_serial=2 string " " ``` ### python 使用python的dbus库调用D-bus方法如下: ```python import dbus bus=dbus.SystemBus() xattr=bus.get_object('org.freedesktop.Accounts','/org/freedesktop/Accounts') iface=dbus.Interface(xattr,dbus_interface='org.freedesktop.Accounts') prop=iface.ListCachedUsers() print(prop) ``` python的dbus库有D-bus的一般都会默认安装 ## 调试技巧 - 调试polkit时显示dbug信息: 修改`/lib/systemd/system/polkitd.service`文件中的`ExecStart`参数: ```bash ExecStart=/bin/sh -c 'G_MESSAGES_DEBUG=all /usr/lib/policykit-1/polkitd > /tmp/polkitd.log 2>&1' ``` 主要是这个`G_MESSAGES_DEBUG=all`环境变量 参考:https://forum.xfce.org/viewtopic.php?id=11190 - polkit相关 https://documentation.suse.com/sles/12-SP5/html/SLES-all/cha-security-policykit.html