针对 dbx 插件框架进行开发

dbx 为想要添加新 dbx 子命令和事件处理程序的开发者提供了插件框架。

任何 dbx 用户都可创建带有特定于应用程序或特定于库的命令的插件,插件增强了 dbx,从而帮助调试。
注意:
  1. 由于缺省的 dbx 命令是 64 位进程,因此所有的插件都需要编译为 64 位才能与 dbx 命令一起使用。 要装入 32 位插件,请使用 dbx 命令的 32 位版本,即 dbx32 命令。
  2. 应注意不要混淆 dbx callback routinesplug-in interface routines
  3. dbx callback routinesdbx 向插件提供的一组服务。 插件有权通过一组函数指针访问这些例程。
  4. plug-in interface routinesdbx 需要由插件实现的方法集。

文件格式

每个插件都必须是共享对象文件。

命名

要正确地重定向子命令输入,dbx 要求每个插件都具有一个唯一名称

插件的文件名将此唯一名称传达到 dbx。 初始化时,dbx 搜索一组预定义和用户指定的目录以获得其基本名与正则表达式相符的文件。
^libdbx_.+\.so$
下表显示了一些文件名示例,其中这些文件名有效但对于 dbx 插件无效。 针对所有的有效示例显示相应的唯一名称
文件名 有效 唯一名称
libdbx_sample.so sample
libdbx_xyz.so xyz
libdbx_my_app.so my_app
libdbx.so False  
libdbx_.so False  
libdbx_sample.so.plugin False  
plugin_libdbx_sample.so False  

位置

dbx 允许用户使用 DBX_PLUGIN_PATH 环境变量指定要搜索的目录列表。 该列表中的每个目录都应用冒号隔开。 在以下示例中,冒号分隔两个目录。
$ export dbx_PLUGIN_PATH=$HOME/dbx_plugins:/mnt/share/dbx_plugins
初始化时,dbx 搜索插件。 dbx 还会搜索可执行文件(如已知)的目录。 搜索完用户定义的目录后搜索该目录。
注: 使用 dbx 连接到进程时,无法确定可执行文件的完整路径。

正在加载

可以以下方式之一装入插件:
  • 可通过将插件置于 dbx 搜索的目录中来自动装入并初始化该插件。 这在 dbx 初始化时发生。
  • 可以通过在 pluginload dbx 子命令中指定插件的位置来手动装入和初始化插件。 这在 dbx 会话期间可随时发生。
成功自动化或手工装入插件后,显示与以下内容类似的消息:
(dbx) pluginload /home/user/dbx_plugins/libdbx_sample.so
 plug-in "/home/user/dbx_plugins/libdbx_sample.so"  loaded
唯一名称与当前活动插件的唯一名称相同的任何插件都将被废弃,并且显示与以下内容相似的消息。
(dbx) pluginload /mnt/share/dbx_plugins/libdbx_sample.so

could not load plug-in 
"/mnt/share/dbx_plugins/libdbx_sample.so":
plug-in "/home/user/dbx_plugins/libdbx_sample.so" already loaded.

卸装

可以通过在 pluginunload dbx 子命令中指定插件的名称来手动卸载任何插件,而无论其装入方式如何。 成功卸装插件后,显示与以下内容类似的消息。
(dbx) pluginunload sample 
plug-in "/home/user/dbx_plugins/libdbx_sample.so" unloaded.

版本控制

如果更改了插件框架,导致现有插件与较早版本的兼容性被破坏,那么将创建一个新的版本标识。 此过程适用于对 Plug-in InterfacePlug-in dbx callback routine进行的任何重大更改或添加。

为了最大限度减少频繁更改插件版本的需求,某些 Plug-in dbx callback routines 需要表示缓冲区大小的附加参数。 将此做法用于基于大小不受 dbx 控制的系统结构的缓冲区参数。 这就允许在不更新插件版本的情况下更改系统结构的大小。

当前,唯一的版本标识为 DBX_PLUGIN_VERSION_1。

头文件

dbx 插件开发者可在以下头文件中找到函数原型、数据结构定义以及宏定义:
/usr/include/sys/dbx_plugin.h

插件接口

请参阅 dbx_plugin.h 头文件以了解 Plug-in Interface 例程的原型和定义。

每个插件必须实现并导出以下所有例程:
  • int dbx_plugin_version(void)
  • int dbx_plugin_session_init(dbx_plugin_session_t session, constdbx_plugin_service_t *servicep)
  • void dbx_plugin_session_command(dbx_plugin_session_t session, int argc, char *const argv[])
  • void dbx_plugin_session_event(dbx_plugin_session_t session, int event, dbx_plugin_event_info_t *event_infop)

int dbx_plugin_version (void)

此例程应该返回对应于插件所符合的版本的 dbx 插件版本标识。 当前,唯一的版本标识为 DBX_PLUGIN_VERSION_1

int dbx_plugin_session_init (dbx_plugin_session_t session , dbx_plugin_service_t * servicep)

此例程应该在将控制权返回给 dbx 之前执行插件为正常运作所需的任何初始化。 如果需要,这包括为插件子命令设置任何别名。

此例程应该创建将给定会话标识与应用程序或核心文件相关联的插件会话。 为了标识进程或核心文件,会话标识由 Plug-in Interface 调用中的 dbx 以及 plugin dbx 回调例程 请求的插件使用。 此例程也接受回调例程结构。

此例程应该返回 0 以表示初始化成功。 如果初始化不成功,dbx 卸装并废弃插件。

void dbx_plugin_session_command (dbx_plugin_session_t session , int argc , char * const argv [])

此例程应接受来自 dbx 用户的输入,格式为提供给 plugin 子命令的自变量。 plugin 子命令的语法如下所示:

plugin Name [arg0 arg1 arg2 ... argn]

这允许 dbx 用户向任何单个插件提供任何输入。 插件对作为输入而接受的参数均有完全控制权。

plugin 子命令将 arg* 参数指定的命令传递到 Name 参数指定的插件。 (例如,插件名可以为 libdbx_Name.sodbx 使用此例程将 arg0 通过 argn 传递给插件。 argv [0] 对应于 arg0argv [1]arg1,依此类推。

在大多数情况下,arg0 将代表插件定义的子命令的名称,而 arg1argn 将代表附加标记或参数。 然而,这不是必需的。

建议开发者实现 help 子命令,该子命令显示插件的使用情况信息。

void dbx_plugin_session_event (dbx_plugin_session_t session , int event , dbx_plugin_event_info_t * event_infop)

为了响应应用程序事件,此例程应该执行插件所需的任何内部处理。 dbx 在每次事件发生时调用例程一次。 下表描述了通知插件的事件类型:
标识(事件) 关联数据 (event_infop) 原因
DBX_PLUGIN_EVENT_RESTART dbx 用户执行了 run 子命令。
DBX_PLUGIN_EVENT _EXIT 退出代码 应用程序通过出口例程结束。
DBX_PLUGIN_EVENT _TERM 正在终止信号号码 由于信号未处理导致应用程序终止。
DBX_PLUGIN_EVENT _LOAD 装入模块的 dbx_plugin_modinfo_t 结构 模块被装入应用程序中。
DBX_PLUGIN_EVENT _UNLOAD 卸装模块的 dbx_plugin_modinfo_t 结构 从应用程序卸装模块。
DBX_PLUGIN_EVENT_BP 由于用户或内部 dbx 断点或数据观察点,导致应用程序停止。
DBX_PLUGIN_EVENT_SIGNAL 信号号码 由于信号传递,导致应用程序停止。
DBX_PLUGIN_EVENT_SWTHRD 当前 pthread 的句柄 dbx 用户执行了 thread current<handle> 子命令,导致当前 pthread 发生更改。

DBX_PLUGIN_EVENT_BP 和 DBX_PLUGIN_EVENT_SIGNAL 事件暗示应用程序启动了但已经停止。 这些事件用来表示插件具有的任何高速缓存的数据可能不再有效。 通知这些事件时,插件仅需使任何高速缓存的数据无效,这比刷新数据更为有效。 只有需要数据时,才应对高速缓存的数据进行全面刷新。 这特别相关,因为 dbx 可能会忽略某些信号,并且某些断点可能是内部断点。 如果用户在应用程序再次启动前没有机会运行子命令,那么反复刷新数据只会浪费资源。

void dbx_plugin_session_destroy(dbx_plugin_session_t session)

此例程应该执行插件所需的任何最终清除和内存管理任务。

dbx 回调例程

以下是通过 dbx_plugin_session_init 例程为每个插件提供的 dbx 回调例程

dbx session 回调例程允许您获取 dbx 会话的特征。 dbx 填写 flagsp 参数。

typedef int (*dbx_plugin_session_service_t)(dbx_plugin_session_t session,
                                            dbx_plugin_session_flags_t *flagsp).

dbx session 回调例程参数为:

参数
描述
会话
会话标识。
标志
以以下内容任意组合的会话特征:
  • DBX_PLUGIN_SESSION_64BIT

    如果设置了,那么会话代表 64 位应用程序。 否则,会话代表 32 位应用程序。

  • DBX_PLUGIN_SESSION_CORE

    如果设置了,那么会话代表核心文件。 否则,会话代表活动进程。

dbx session 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION 会话无效
  • DBX_PLUGIN_BAD_POINTER flagsp 为 NULL

进程 (process)

dbx process 回调例程允许您获取有关正在调试的进程的信息。 dbx 填充 infop 参数。

typedef int (*dbx_plugin_process_service_t)(dbx_plugin_session_t session,
                                            dbx _plugin_procinfo_t *infop,
                                            size_t procinfo_size) 

dbx process 回调例程参数为:

参数
描述
会话
会话标识
信息
已分配的 dbx_plugin_procinfo_t 结构
procinfo_size
dbx_plugin_procinfo_t 结构的大小
dbx process 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_POINTER infop 为 NULL
  • DBX_PLUGIN_BAD_ARG procinfo_size 无效
  • DBX_PLUGIN_UNAVAILABLE 进程不活动或 info 不在核心中

fds

dbx fds 回调例程允许您获取有关进程的文件描述符的信息。 您可执行以下操作:
  • 反复调用以分别获取有关每个文件描述符的信息。 或者,
  • 调用一次以获取文件描述符的总数,并再次调用一次以同时获取有关所有文件描述符的信息。

如果插件传送非空的 infop 缓冲区,那么 dbx 使用 *countp 中请求的条目数从 *indexp 引用的文件描述符开始填充缓冲区。

如果插件传送的 *countp 大于剩余条目数,那么 dbx 将检索所有剩余的条目。 dbx 更新 countp 以反映检索的实际条目数, indexp 以反映下一个模块索引。 如果检索到最后一个文件描述符,那么将 indexp 设为 -1。 如果插件传递了 NULL infop 缓冲区,那么仍然更新 indexpcountp - 就好像 infop 不为 NULL。

typedef int (*dbx_plugin_fds_service_t)(dbx_plugin_session_t session,
                                        dbx_plugin_fdinfo_t *infop,
                                        size_t fdinfo_size,
                                        unsigned int *indexp,
                                        unsigned int *countp)

dbx fds 回调例程参数为:

参数
描述
会话
会话标识
信息
dbx_plugin_fdinfo_t 结构的已分配数组或 NULL
fdinfo_size
单个 dbx_plugin_fdinfo_t 结构的大小
索引
启动/下一个文件描述符(其中,0 对应于第一个文件描述符)
计数
文件描述符的数目
dbx fds 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_POINTER indexp 为 NULL,或 countp 为 NULL
  • DBX_PLUGIN_BAD_ARG fdinfo_size 无效或 * countp == 0
  • DBX_PLUGIN_UNAVAILABLE 进程不活动或 info 不在核心中

模块

dbx modules 回调例程允许您获取有关进程的已装入模块的信息。 您可执行以下操作:
  • 反复调用以分别获取有关每个模块的信息。 或者,
  • 调用一次以获取模块的总数,并再次调用一次以同时获取有关所有模块的信息。

如果插件传送非空的 infop 缓冲区,那么 dbx 使用 *countp 中请求的条目数从 *indexp 引用的模块开始填充缓冲区。

如果插件传送的 *countp 大于剩余条目数,那么 dbx 将检索所有剩余的条目。 dbx 更新 countp 以反映检索到的条目的实际数目,并且更新 indexp 以反映下一个模块索引。 如果检索到最后一个模块,那么将 indexp 设为 -1。 如果插件传递了 NULL infop 缓冲区,那么仍然更新 indexpcountp - 就好像 infop 不为 NULL。
注: 此例程分配内存以保存文件名和成员字符串。 当不再需要此内存时,调用程序必须将它释放。
typedef int (*dbx_plugin_modules_service_t)(dbx_plugin_session_t session,
                                            dbx_plugin_modinfo_t *infop,
                                            size_t modinfo_size,
                                            unsigned int *indexp,
                                            unsigned int *countp)

dbx modules 回调例程参数为:

参数
描述
会话
会话标识
信息
dbx_plugin_modinfo_t 结构的已分配数组或 NULL
modinfo_size
单个 dbx_plugin_modinfo_t 结构的大小
索引
启动/下一个模块(其中,0 对应于第一个模块)
计数
模块数
dbx modules 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_POINTER indexp 为 NULL,或 countp 为 NULL
  • DBX_PLUGIN_BAD_ARG modinfo_size 无效或 *countp == 0

区域

dbx regions 回调例程允许您获取有关进程的内存区域的信息。

检索的区域可包括:
  • 主线程堆栈区域 (DBX_PLUGIN_REGION_STACK)
  • 用户数据区域 (DBX_PLUGIN_REGION_DATA)
  • 进程专用数据区域 (DBX_PLUGIN_REGION_SDATA)
  • 内存映射区域 (DBX_PLUGIN_REGION_MMAP)
  • 共享内存区域 (DBX_PLUGIN_REGION_SHM)
您可执行以下操作:
  • 反复调用以分别获取有关某一个区域的信息。 或者,
  • 调用一次以获取区域的总数,并再次调用一次以同时获取有关所有区域的信息。

如果插件传送非空的 infop 缓冲区,那么 dbx 使用 *countp 中请求的条目数从 *indexp 引用的区域开始填充缓冲区。

如果插件传送的 *countp 大于剩余条目数,那么 dbx 将检索所有剩余的条目。 dbx 更新 countp 以反映检索到的条目的实际数目,并且更新 indexp 以反映下一个区域索引。

如果检索到最后一个区域,那么将 indexp 设为 -1。 如果插件传递了 NULL infop 缓冲区,那么仍然更新 indexpcountp - 就好像 infop 不为 NULL。
注: 目前,仅对表示核心文件的会话实施此例程。 对于代表活动进程的会话,没有向 dbx 提供足够的信息。 此类会话的调用返回 DBX_PLUGIN_UNAVAILABLE。
typedef int (*dbx_plugin_regions_service_t)(dbx_plugin_session_t session,
                                            dbx_plugin_reginfo_t *infop,
                                            size_t reginfo_size,
                                            unsigned int *indexp,
                                            unsigned int *countp)

dbx regions 回调例程参数为:

参数
描述
会话
会话标识
信息
dbx_plugin_region_t 结构的已分配数组或 NULL
reginfo_size
单个 dbx_plugin_reginfo_t 结构的大小
索引
启动/下一个区域(其中,0 对应于第一个区域)
计数
区域数
dbx regions 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_POINTER indexp 为 NULL,或 countp 为 NULL
  • DBX_PLUGIN_BAD_ARG reginfo_size 无效或 *countp == 0
  • DBX_PLUGIN_UNAVAILABLE 会话表示不可访问活动进程和区域

线程

dbx threads 回调例程允许您获取有关进程中内核线程的信息。

您可执行以下操作:
  • 反复调用以分别获取有关某一个线程的信息。 或者,
  • 调用一次以获取线程的总数,并再次调用一次以同时获取有关所有线程的信息。

如果插件传送非空的 infop 缓冲区,那么 dbx 使用 *countp 中请求的条目数从 *indexp 引用的线程开始填充缓冲区。

如果插件传送大于或者等于剩余条目数的 *countp,那么 dbx 将检索所有剩余的条目并且更新 countp 以反映检索到的条目的实际数量。

如果检索到最后一个条目,并且 countp 小于其传递值,那么将 indexp 设为 -1。 否则,更新 indexp 以反映下一个请求的线程标识。
注意:如果传入的countp值等于可用条目数,则countp保持不变,但indexp不会设置为-1。

如果插件传递了 NULL infop 缓冲区,那么更新 indexpcountp - 就好像 infop 不为 NULL。

typedef int (*dbx_plugin_threads_service_t)(dbx_plugin_session_t session,
                                            dbx _plugin_thrdinfo_t *infop,
                                            size_t thrdinfo_size,
                                            tid64_t *indexp,
                                            unsigned int *countp)

dbx threads 回调例程参数为:

参数
描述
会话
会话标识
信息
dbx_plugin_thrdinfo_t 结构的已分配数组或 NULL
thrdinfo_size
单个 dbx_plugin_thrdinfo_t 结构的大小
索引
启动/下一个线程标识(其中,输入时,0 对应于第一个线程)
计数
线程数
dbx threads 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_POINTER indexp 为 NULL,或 countp 为 NULL
  • DBX_PLUGIN_BAD_ID *indexp 是无效的标识
  • DBX_PLUGIN_BAD_ARG thrdinfo_size 无效或 *countp ==0
  • DBX_PLUGIN_UNAVAILABLE 进程不活动或条目不在核心中

pthread

dbx pthreads 回调例程允许您获取有关进程中的 pthread 的信息,包括任何内核线程关联。

您可执行以下操作:
  • 反复调用以分别获取有关某一个 pthread 的信息。 或者,
  • 调用一次以获取 pthread 的总数,并再次调用一次以同时获取有关所有 pthread 的信息。

如果插件传送非空的 infop 缓冲区,那么 dbx 使用 *countp 中请求的条目数从 *indexp 引用的 pthread 开始填充缓冲区。

如果插件传送的 *countp 大于剩余条目数,那么 dbx 将检索所有剩余的条目。 dbx 更新 countp 以反映检索到的条目的实际数目,并且更新 indexp 以反映下一个请求的 pthread 句柄。

如果检索到最后一个条目,那么将 indexp 设为 -1。 如果插件传递了 NULL infop 缓冲区,那么仍然更新 indexpcountp - 就好像 infop 不为 NULL。

如果请求了第一个 pthread 并且将 countp 更新为 0,那么不对进程进行 pthread 操作。

typedef int (*dbx_plugin_pthreads_service_t)(dbx_plugin_session_t session,
                                             dbx_plugin_pthinfo_t *infop,
                                             size_t pthrdinfo_size,
                                             pthdb_pthread_t *indexp,
                                             unsigned int *countp)

dbx pthreads 回调例程参数为:

参数
描述
会话
会话标识
信息
dbx_plugin_pthinfo_t 结构的已分配数组或 NULL
pthrdinfo_size
单个 dbx_plugin_pthrdinfo_t 结构的大小
索引
启动/下一个 pthread 句柄(其中,输入时,0 对应于第一个 pthread,而DBX_PLUGIN_PTHREAD_CURRENT 对应于 dbx 中的当前 pthread)
计数
pthread 数
dbx pthreads 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_POINTER indexp 为 NULL,或 countp 为 NULL
  • DBX_PLUGIN_BAD_ARG pthrdinfo_size 无效或 *countp == 0

get_thread_context

dbx get_thread_context 回调例程允许您读取内核线程的一般用途,特殊用途和浮点寄存器。 dbx 填充 contextp 参数。

typedef int (*dbx_plugin_reg_service_t)(dbx_plugin_session_t session,
                                        uint64_t reg_flags,
                                        uint64_t id,
                                        dbx_plugin_context_t *contextp,
                                        size_t context_size)

dbx get_thread_context 回调例程参数为:

参数
描述
会话
会话标识
reg_flags
至少为 DBX_PLUGIN_REG_GPRS、DBX_PLUGIN_REG_SPRS、DBX_PLUGIN_REG_FPRS 和 DBX_PLUGIN_REG_EXT 中的一个的逻辑 OR
标识
内核线程 tid (tid64_t)
上下文
已分配的 dbx_plugin_context_t 结构
上下文大小
dbx_plugin_context_t 结构的大小。 如果使用了 DBX_PLUGIN_REG_EXT 寄存器标记,那么应使用 dbx_plugin_extctx_t 结构的大小。 dbx_plugin_extctx_t 结构是 dbx_plugin_context_t 结构的扩展版本。
dbx get_thread_context 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS。
  • DBX_PLUGIN_BAD_SESSION session 无效。
  • DBX_PLUGIN_BAD_ID id 无效。
  • DBX_PLUGIN_BAD_ARG reg_flags 无效,或 context_size 无效。
  • DBX_PLUGIN_BAD_POINTER contextp 为 NULL
  • DBX_PLUGIN_UNAVAILABLE 进程不活动或线程处于内核方式,并且寄存器不可访问。

set_thread_context

dbx set_thread_context 回调例程允许您写入内核线程的通用,特殊用途和浮点寄存器。

typedef int (*dbx_plugin_reg_service_t) (dbx_plugin_session_t session,
                    uint64_t reg_flags,
                                  uint64_t id,
                                  dbx_plugin_context_t *contextp,
                                  size_t context_size)

dbx set_thread_context 回调例程参数为:

参数
描述
会话
会话标识
reg_flags
至少为 DBX_PLUGIN_REG_GPRS、DBX_PLUGIN_REG_SPRS、DBX_PLUGIN_REG_FPRS 和 DBX_PLUGIN_REG_EXT 中的一个的逻辑 OR
标识
内核线程 tid (tid64_t)
上下文
已分配的 dbx_plugin_context_t 结构
上下文大小
dbx_plugin_context_t 结构的大小。 如果使用了 DBX_PLUGIN_REG_EXT 寄存器标记,那么应使用 dbx_plugin_extctx_t 结构的大小。 dbx_plugin_extctx_t 结构是 dbx_plugin_context_t 结构的扩展版本。
dbx set_thread_context 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_ID id 无效
  • DBX_PLUGIN_BAD_ARG reg_flags 无效,或 context_size 无效
  • DBX_PLUGIN_BAD_POINTER contextp 为 NULL
  • DBX_PLUGIN_UNAVAILABLE 进程不活动或线程处于内核方式,并且寄存器不可访问

get_pthread_context

dbx get_pthread_context 回调例程允许您读取 pthread 的通用,特殊用途和浮点寄存器。 dbx 填充 contextp 参数。

typedef int (*dbx_plugin_reg_service_t)(dbx_plugin_session_t session,
                                        uint64_t reg_flags,
                                        uint64_t id,
                                        dbx_plugin_context_t *contextp,
                                        size_t context_size)

dbx get_pthread_context 回调例程参数为:

参数
描述
会话
会话标识
reg_flags
至少为 DBX_PLUGIN_REG_GPRS、DBX_PLUGIN_REG_SPRS、DBX_PLUGIN_REG_FPRS 和 DBX_PLUGIN_REG_EXT 中的一个的逻辑 OR
标识
pthread 句柄 (pthdb_pthread_t)
上下文
已分配的 dbx_plugin_context_t 结构
上下文大小
dbx_plugin_context_t 结构的大小。 如果使用了 DBX_PLUGIN_REG_EXT 寄存器标记,那么应使用 dbx_plugin_extctx_t 结构的大小。 dbx_plugin_extctx_t 结构是 dbx_plugin_context_t 结构的扩展版本。
dbx get_pthread_context 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_ID id 无效。
  • DBX_PLUGIN_BAD_ARG reg_flags 无效,或 context_size 无效
  • DBX_PLUGIN_BAD_POINTER contextp 为 NULL
  • DBX_PLUGIN_UNAVAILABLE 进程不活动或线程处于内核方式,并且寄存器不可访问

set_pthread_context

dbx set_pthread_context 回调例程允许您写入 pthread 的通用,特殊用途和浮点寄存器。

typedef int (*dbx_plugin_reg_service_t)(dbx_plugin_session_t session,
                                        uint64_t reg_flags,
                                        uint64_t id,
                                        dbx_plugin_context_t *contextp,
                                        size_t context_size)

dbx set_pthread_context 回调例程参数为:

参数
描述
会话
会话标识
reg_flags
至少为 DBX_PLUGIN_REG_GPRS、DBX_PLUGIN_REG_SPRS、DBX_PLUGIN_REG_FPRS 和 DBX_PLUGIN_REG_EXT 中的一个的逻辑 OR
标识
Pthread 句柄 (pthdb_pthread_t)
上下文
已分配的 dbx_plugin_context_t 结构
上下文大小
dbx_plugin_context_t 结构的大小。 如果使用了 DBX_PLUGIN_REG_EXT 寄存器标记,那么应使用 dbx_plugin_extctx_t 结构的大小。 dbx_plugin_extctx_t 结构是 dbx_plugin_context_t 结构的扩展版本。
dbx set_pthread_context 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_ID id 无效
  • DBX_PLUGIN_BAD_ARG reg_flags 无效,或 context_size 无效
  • DBX_PLUGIN_BAD_POINTER contextp 为 NULL
  • DBX_PLUGIN_UNAVAILABLE 进程不活动,或与 pthread 相关联的内核线程处于内核方式,并且寄存器不可访问

read_memory

dbx read_memory 回调例程允许您从进程的地址空间中进行读取。 dbx 填充缓冲区参数。

typedef int (*dbx_plugin_mem_service_t)(dbx_plugin_session_t session,
                                        uint64_t addr,
                                        void *buffer,
                                        size_t len)

dbx read_memory 回调例程参数为:

参数
描述
会话
会话标识
地址
要读取的地址
缓冲区
保存内存内容的已分配缓冲区
LEN
要读取的字节数
dbx read_memory 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_POINTER buffer 为 NULL
  • DBX_PLUGIN_UNAVAILABLE 无法从 addr 读取

write_memory

dbx write_memory 回调例程允许您写入进程的地址空间。

typedef int (*dbx_plugin_mem_service_t)(dbx_plugin_session_t session,
                                        uint64_t addr,
                                        void *buffer,
                                        size_t len)

dbx write_memory 回调例程参数为:

参数
描述
会话
会话标识
地址
要写到该处的地址
缓冲区
已分配并初始化的缓冲区
LEN
要写入的字节的数目
dbx write_memory 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_POINTER buffer 为 NULL
  • DBX_PLUGIN_UNAVAILABLE 无法写到 addr

locate_symbol

dbx locate_symbol 回调例程允许您将符号名称转换为地址。

插件必须初始化符号参数数组中每个条目的 namemod 字段。 name 字段指定将要查找的符号的名称。 mod 字段指定在其中发生查找行为的模块的模块索引。 初始化为 -1 的 mod 字段指示应该搜索所有模块。

dbx 填充 addr 字段。 任何未知符号的地址均为 0。 如果找到该符号且搜索到所有模块,那么 dbx 用符号的实际模块索引更新 mod 字段。

typedef int (*dbx_plugin_sym_service_t)(dbx_plugin_session_t session,
                                        dbx_plugin_sym_t *symbols,
                                        size_t syminfo_size,
                                        unsigned int count)

dbx locate_symbol 回调例程参数为:

参数
描述
会话
会话标识
符号
dbx_plugin_sym_t 结构的已分配数组,其中 namemod 字段已初始化
syminfo_size
dbx_plugin_sym_t 结构的大小
计数
要查找的符号的数目
dbx locate_symbol 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_ARG syminfo_size 无效
  • DBX_PLUGIN_BAD_POINTER symbols 为 NULL

what_function

dbx what_function 回调例程允许您将文本地址转换为符号。

插件必须初始化符号参数数组中每个条目的 addr 字段。 addr 字段指定将要标识的函数内的指令地址。

dbx 填充 name 字段。 任何未知文本地址的名称均为 NULL。 dbx 用文本地址的实际模块索引填充 mod 字段。

typedef int (*dbx_plugin_sym_service_t)(dbx_plugin_session_t session,
                                        dbx_plugin_sym_t *symbols,
                                        size_t syminfo_size,
                                        unsigned int count)

dbx what_function 回调例程参数为:

参数
描述
会话
会话标识
符号
dbx_plugin_sym_t 结构的已分配数组,其 addr 字段已通过使用文本地址初始化
syminfo_size
dbx_plugin_sym_t 结构的大小
计数
要转换的地址的数目
dbx what_function 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_ARG syminfo_size 无效
  • DBX_PLUGIN_BAD_POINTER symbols 为 NULL

PRINT

dbx print 回调例程允许您显示参考输出或错误输出。

typedef int (*dbx_plugin_print_service_t)(dbx_plugin_session_t session,
                                          int print_mode,
                                          char *message)

dbx print 回调例程参数为:

参数
描述
会话
会话标识
打印方式
DBX_PLUGIN_PRINT_MODE_OUT 或 DBX_PLUGIN_PRINT_MODE_ERR
消息
要显示的 dbx 的字符串
dbx print 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_ARG print_mode 无效
  • DBX_PLUGIN_BAD_POINTER message 为 NULL

alias

dbx alias 回调例程允许您为插件子命令创建别名。

plugin dbx 子命令的语法要求 dbx 用户为每个插件子命令调用输入前缀 plugin Name 。 为提供缩短此类调用的方法,dbx 允许插件创建新的别名。

aliasexpansion 参数应该描述新的别名。 语法与为别名 dbx 子命令定义的语法相同。

以下是 dbx alias 回调例程的示例调用:
alias("intprt", "plugin xyz interpret");
alias("intprt2(addr, count, format)", "addr / count format; plugin xyz interpret addr");
注: 如果尝试创建与现有别名同名的别名,那么请求将被拒绝并显示一条警告消息。 鼓励插件开发者以允许用户更正别名冲突的方式实行别名创建。 实现此目的的一种方法就是从与插件一起封装的配置文件读取别名定义。
typedef int (*dbx_plugin_alias_service_t)(dbx_plugin_session_t session,
                                          const char *alias,
                                          const char *expansion)

dbx alias 回调例程参数为:

参数
描述
会话
会话标识
别名
代表别名和可选参数的字符串
扩展
代表别名扩展名的字符串
dbx alias 回调例程返回码为:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session 无效
  • DBX_PLUGIN_BAD_ARG alias 无效
  • DBX_PLUGIN_BAD_POINTER alias 为 NULL 或扩展名为 NULL
  • DBX_PLUGIN_UNAVAILABLE 已存在具有相同名称的别名

示例

  1. 以下示例定义 help 子命令和 hello 子命令:
    example.c: 
    
    #include <sys/dbx_plugin.h>
    
    dbx_plugin_session_t sid;
    dbx_plugin_services_t dbx;
    
    static void usage(void);
    static void hello_cmd(void);
    
    int
    dbx_plugin_version(void) {
        return DBX_PLUGIN_VERSION_1;
    }
    
    int dbx_plugin_session_init(dbx_plugin_session_t session,
                                const dbx_plugin_services_t *servicep) {
        /* record session identifier */
        sid= session;
    
        /* record dbx service */
        memcpy(&dbx, servicep, sizeof(dbx_plugin_services_t));
    
        (*(dbx.alias))(sid, "hello", "plugin example hello");
        (*(dbx.alias))(sid, "help", "plugin example help");
    
        return 0;
    
    }
    
    void
    dbx_plugin_session_command(dbx_plugin_session_t session,
                               int argc,
                               char *const argv[]) {
        if (argc == 0 || (argc == 1 && strcmp(argv[0], "help") == 0)) {
    
    	usage();
    	return;
        }
        if (argc == 1 && strcmp(argv[0], "hello") == 0) {
    	hello_cmd();
    	return;
        }
        (*(dbx.print))(sid,DBX_PLUGIN_PRINT_MODE_ERR,
    		   "unrecognized command\n");
    
    }
    
    void
    dbx_plugin_session_event(dbx_plugin_session_t session,
                             int event,
                             dbx_plugin_event_info_t *event_infop) {
        /* ignore event notifications */
    }
    
    void
    dbx_plugin_session_destroy(dbx_plugin_session_t session){
        /* no clean up to perform */
    }
    
    static
    void
    usage(void) {
        (*(dbx.print))(sid,DBX_PLUGIN_PRINT_MODE_OUT,
                           "Subcommands for Plug-in \"example\":\n\n" \
                           "   help  - displays this output\n" \
                           "   hello - displays a greeting\n" \
    		   "\n");
    }
    
    static
    void
    hello_cmd(void) {
        (*(dbx.print))(sid,DBX_PLUGIN_PRINT_MODE_OUT,
    		   "Hello dbx World!\n");
    
    }
    example.exp:
    
    dbx_plugin_version
    dbx_plugin_session_init
    dbx_plugin_session_command
    dbx_plugin_session_event
    dbx_plugin_session_destroy
  2. 要编译示例插件,请输入:
    cc -q64 -o libdbx_example.so example.c -bM:Sre -bE:example.exp -bnoentry