针对 dbx 插件框架进行开发
dbx 为想要添加新 dbx 子命令和事件处理程序的开发者提供了插件框架。
- 由于缺省的 dbx 命令是 64 位进程,因此所有的插件都需要编译为 64 位才能与 dbx 命令一起使用。 要装入 32 位插件,请使用 dbx 命令的 32 位版本,即 dbx32 命令。
- 应注意不要混淆 dbx callback routines 和 plug-in interface routines。
- dbx callback routines 是 dbx 向插件提供的一组服务。 插件有权通过一组函数指针访问这些例程。
- plug-in interface routines 是 dbx 需要由插件实现的方法集。
文件格式
每个插件都必须是共享对象文件。
命名
要正确地重定向子命令输入,dbx 要求每个插件都具有一个唯一名称。
^libdbx_.+\.so$| 文件名 | 有效 | 唯一名称 |
|---|---|---|
| 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 |
位置
$ export dbx_PLUGIN_PATH=$HOME/dbx_plugins:/mnt/share/dbx_plugins正在加载
- 可通过将插件置于 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.卸装
(dbx) pluginunload sample
plug-in "/home/user/dbx_plugins/libdbx_sample.so" unloaded.版本控制
如果更改了插件框架,导致现有插件与较早版本的兼容性被破坏,那么将创建一个新的版本标识。 此过程适用于对 Plug-in Interface 或 Plug-in dbx callback routine进行的任何重大更改或添加。
为了最大限度减少频繁更改插件版本的需求,某些 Plug-in dbx callback routines 需要表示缓冲区大小的附加参数。 将此做法用于基于大小不受 dbx 控制的系统结构的缓冲区参数。 这就允许在不更新插件版本的情况下更改系统结构的大小。
当前,唯一的版本标识为 DBX_PLUGIN_VERSION_1。
头文件
/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.so)dbx 使用此例程将 arg0 通过 argn 传递给插件。 argv [0] 对应于 arg0, argv [1] 到 arg1,依此类推。
在大多数情况下,arg0 将代表插件定义的子命令的名称,而 arg1 至 argn 将代表附加标记或参数。 然而,这不是必需的。
建议开发者实现 help 子命令,该子命令显示插件的使用情况信息。
void dbx_plugin_session_event (dbx_plugin_session_t session , int event , dbx_plugin_event_info_t * event_infop)
| 标识(事件) | 关联数据 (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_PLUGIN_SESSION_64BIT
- 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_PLUGIN_SUCCESS
- DBX_PLUGIN_BAD_SESSION session 无效
- DBX_PLUGIN_BAD_POINTER infop 为 NULL
- DBX_PLUGIN_BAD_ARG procinfo_size 无效
- DBX_PLUGIN_UNAVAILABLE 进程不活动或 info 不在核心中
fds
- 反复调用以分别获取有关每个文件描述符的信息。 或者,
- 调用一次以获取文件描述符的总数,并再次调用一次以同时获取有关所有文件描述符的信息。
如果插件传送非空的 infop 缓冲区,那么 dbx 使用 *countp 中请求的条目数从 *indexp 引用的文件描述符开始填充缓冲区。
如果插件传送的 *countp 大于剩余条目数,那么 dbx 将检索所有剩余的条目。 dbx 更新 countp 以反映检索的实际条目数, indexp 以反映下一个模块索引。 如果检索到最后一个文件描述符,那么将 indexp 设为 -1。 如果插件传递了 NULL infop 缓冲区,那么仍然更新 indexp 和 countp - 就好像 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_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 不在核心中
模块
- 反复调用以分别获取有关每个模块的信息。 或者,
- 调用一次以获取模块的总数,并再次调用一次以同时获取有关所有模块的信息。
如果插件传送非空的 infop 缓冲区,那么 dbx 使用 *countp 中请求的条目数从 *indexp 引用的模块开始填充缓冲区。
-1。 如果插件传递了 NULL infop 缓冲区,那么仍然更新 indexp 和 countp - 就好像 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_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 以反映下一个区域索引。
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_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 以反映检索到的条目的实际数量。
如果插件传递了 NULL infop 缓冲区,那么更新 indexp 和 countp - 就好像 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_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 缓冲区,那么仍然更新 indexp 和 countp - 就好像 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_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_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_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_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_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_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_PLUGIN_SUCCESS
- DBX_PLUGIN_BAD_SESSION session 无效
- DBX_PLUGIN_BAD_POINTER buffer 为 NULL
- DBX_PLUGIN_UNAVAILABLE 无法写到 addr
locate_symbol
dbx locate_symbol 回调例程允许您将符号名称转换为地址。
插件必须初始化符号参数数组中每个条目的 name 和 mod 字段。 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 结构的已分配数组,其中 name 和 mod 字段已初始化
- syminfo_size
- dbx_plugin_sym_t 结构的大小
- 计数
- 要查找的符号的数目
- 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_PLUGIN_SUCCESS
- DBX_PLUGIN_BAD_SESSION session 无效
- DBX_PLUGIN_BAD_ARG syminfo_size 无效
- DBX_PLUGIN_BAD_POINTER symbols 为 NULL
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_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 允许插件创建新的别名。
alias 和 expansion 参数应该描述新的别名。 语法与为别名 dbx 子命令定义的语法相同。
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_PLUGIN_SUCCESS
- DBX_PLUGIN_BAD_SESSION session 无效
- DBX_PLUGIN_BAD_ARG alias 无效
- DBX_PLUGIN_BAD_POINTER alias 为 NULL 或扩展名为 NULL
- DBX_PLUGIN_UNAVAILABLE 已存在具有相同名称的别名
示例
- 以下示例定义 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 - 要编译示例插件,请输入:
cc -q64 -o libdbx_example.so example.c -bM:Sre -bE:example.exp -bnoentry