Developing for the dbx plug-in framework

dbx provides a plug-in framework for developers who want to add new dbx subcommands and event handlers.

Any dbx user can create a plug-in that enhances dbx with application or library specific commands to aid in debugging.
Note:
  1. Because the default dbx command is a 64-bit process, all plug-ins need to be compiled to 64-bit to be used with the dbx command. In order to load 32-bit plug-ins, use the 32-bit version of the dbx command, which is the dbx32 command.
  2. Care should be taken not to confuse dbx callback routines and plug-in interface routines.
  3. dbx callback routines are the set of services offered by dbx to the plug-in. The plug-in is given access to these routines through a set of function pointers.
  4. plug-in interface routines are the set of methods dbx requires to be implemented by the plug-in.

File format

Each plug-in must be a shared object file.

Naming

To correctly redirect subcommand input, dbx requires each plug-in to have a unique name.

The file name of the plug-in communicates this unique name to dbx. Upon initialization, dbx searches a set of predefined and user-specified directories for files whose base name matches the regular expression:
^libdbx_.+\.so$
The following table shows examples of file names that are valid and not valid for dbx plug-ins. The corresponding unique name is shown for all valid examples:
File Name Valid Unique Name
libdbx_sample.so Yes sample
libdbx_xyz.so Yes xyz
libdbx_my_app.so Yes my_app
libdbx.so No  
libdbx_.so No  
libdbx_sample.so.plugin No  
plugin_libdbx_sample.so No  

Location

dbx allows the user to specify a list of directories to search using the DBX_PLUGIN_PATH environment variable. Each directory in the list should be separated by a colon. In the following example, the colon separates two directories.
$ export dbx_PLUGIN_PATH=$HOME/dbx_plugins:/mnt/share/dbx_plugins
Upon initialization, dbx searches for plug-ins. dbx also searches the directory of the executable file (if known). This directory is searched after the user-defined directories are searched.
Note: When you use dbx to attach to a process, the full path to the executable file cannot be determined.

Loading

A plug-in can be loaded in one of the following ways:
  • A plug-in can be automatically loaded and initialized by placing it in a directory that is searched by dbx. This occurs at dbx initialization time.
  • A plug-in can be manually loaded and initialized by specifying its location to the pluginload dbx subcommand. This can occur at any time during the dbx session.
After a successful automatic or manual plug-in load, a message similar to the following is displayed:
(dbx) pluginload /home/user/dbx_plugins/libdbx_sample.so
 plug-in "/home/user/dbx_plugins/libdbx_sample.so"  loaded
Any plug-in whose unique name is identical to that of a currently active plug-in is discarded and a warning message similar to the following is displayed.
(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.

Unloading

Any plug-in, regardless of how it was loaded, can be manually unloaded by specifying its name to the pluginunload dbx subcommand. After a plug-in is successfully unloaded, a message similar to the following is displayed.
(dbx) pluginunload sample 
plug-in "/home/user/dbx_plugins/libdbx_sample.so" unloaded.

Version Control

If changes are made to the plug-in framework that would otherwise break the compatibility of the existing plug-ins with earlier versions, a new version identifier is created. This process is true for any significant changes or additions done to the Plug-in Interface or Plug-in dbx callback routine.

To minimize the need for frequent plug-in version changes, some Plug-in dbx callback routines require an additional parameter that represents the size of the buffer. This practice is used for buffer parameters that are based on system structures whose size is not controlled by dbx. This allows the size of the system structures to change without requiring updates to the plug-in version.

Currently, the only version identifier is DBX_PLUGIN_VERSION_1.

Header File

dbx Plug-in developers can find function prototypes, data structure definitions and macro definitions in the following header file:
/usr/include/sys/dbx_plugin.h

Plug-in interface

Refer to the dbx_plugin.h header file for prototypes and definitions for the Plug-in Interface routines.

Each plug-in must implement and export all of the following routines:
  • 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)

This routine should return the dbx Plug-in version identifier corresponding to the version to which the plug-in conforms. Currently, the only version identifier is DBX_PLUGIN_VERSION_1.

int dbx_plugin_session_init(dbx_plugin_session_t session, constdbx_plugin_service_t *servicep)

This routine should perform any initialization needed for the plug-in to function properly before returning control back to dbx. This includes setting up any aliases for plug-in subcommands, if desired.

This routine should create a plug-in session that associates the given session identifier with the application program or core file. To identify the process or core file, the session identifier is used by dbx in Plug-in Interface calls and by the plug-in for plugin dbx callback routine requests. This routine also accepts the callback routine structure.

This routine should return zero for successful initialization. If initialization is not successful, dbx unloads and discards the plug-in.

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

This routine should accept input from the dbx user in the form of arguments provided to the plugin subcommand. The syntax of the plugin subcommand is as follows:

plugin Name [arg0 arg1 arg2 ... argn]

This allows the dbx user to provide any input to any single plug-in. The plug-in has full control over what it accepts as input.

The plugin subcommand passes the command specified by the arg* parameters to the plug-in specified by the Name parameter. (For example, the plug-in name could be libdbx_Name.so) Using this routine, dbx passes arg0 through argn to the plug-in. argv[0] corresponds to arg0, argv[1] to arg1, and so on.

In most circumstances, arg0 would represent the name of a subcommand defined by the plug-in and arg1 through argn would represent additional flags or arguments. However, this is not a requirement.

Developers are encouraged to implement a help subcommand which displays usage information for the plug-in.

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

In response to application program events, this routine should perform any internal processing required by the plug-in. The routine is invoked once by dbx upon the occurrence of each event. The following table describes the event types for which a plug-in is notified:
ID (event) Associated data (event_infop) Cause
DBX_PLUGIN_EVENT_RESTART None The dbx user executed the run subcommand.
DBX_PLUGIN_EVENT _EXIT Exit code The application program ended through the exit routine.
DBX_PLUGIN_EVENT _TERM Terminating signal number The application program terminated because of an unhandled signal.
DBX_PLUGIN_EVENT _LOAD dbx_plugin_modinfo_t structure of loaded module A module was loaded into the application program.
DBX_PLUGIN_EVENT _UNLOAD dbx_plugin_modinfo_t structure of unloaded module A module was unloaded from the application program.
DBX_PLUGIN_EVENT_BP None The application program has stopped because of a user or internal dbx breakpoint or data watchpoint.
DBX_PLUGIN_EVENT_SIGNAL Signal number The application program stopped because of a signal delivery.
DBX_PLUGIN_EVENT_SWTHRD Handle of current pthread The dbx user executed the thread current<handle> subcommand resulting in a change in the current pthread.

The DBX_PLUGIN_EVENT_BP and DBX_PLUGIN_EVENT_SIGNAL events imply that the application program was started but has stopped. These events are meant to signify that any cached data that the plug-in possesses might no longer be valid. Upon notification of these events, it is more efficient for plug-ins to simply invalidate any cached data rather than refreshing the data. A complete refresh of cached data should only occur when the data is needed. This is especially relevant because some signals might be ignored by dbx and some breakpoints might be internal breakpoints. If the user has no opportunity to run subcommands before the application program starts again, repeatedly refreshing data wastes resources.

void dbx_plugin_session_destroy(dbx_plugin_session_t session)

This routine should perform any final cleanup and memory management tasks required by the plug-in.

dbx callback routines

The following are the dbx callback routines provided for each plug-in through the dbx_plugin_session_init routine.

The dbx session callback routine allows you to get characteristics of the dbx session. dbx fills in the flagsp parameter.

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

The dbx session callback routine parameters are:

Parameter
Description
session
Session identifier.
flagsp
Session characteristics in any combination of:
  • DBX_PLUGIN_SESSION_64BIT

    If set, the session represents a 64-bit application program. Otherwise, the session represents a 32-bit application program.

  • DBX_PLUGIN_SESSION_CORE

    If set, the session represents a core file. Otherwise, the session represents a live process.

The dbx session callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_POINTER flagsp is NULL

process

The dbx process callback routine allows you to get information on the process being debugged. dbx populates the infop parameter.

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

The dbx process callback routine parameters are:

Parameter
Description
session
Session identifier
infop
Allocated dbx_plugin_procinfo_t structure
procinfo_size
Size of dbx_plugin_procinfo_t structure
The dbx process callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_POINTER infop is NULL
  • DBX_PLUGIN_BAD_ARG procinfo_size is not valid
  • DBX_PLUGIN_UNAVAILABLE process not active or info not in core

fds

The dbx fds callback routine allows you to get information on file descriptors for the process. You can either:
  • Call iteratively to get information separately on each file descriptor. Or,
  • Call once to get the total number of file descriptors and call once again to get information on all file descriptors simultaneously.

If the plug-in passes a non-NULL infop buffer, dbx populates the buffer with the number of entries requested in *countp, starting with the file descriptor referenced by *indexp.

If the plug-in passes a *countp that is greater than the number of remaining entries, dbx retrieves all remaining entries. dbx updates countp to reflect the actual number of entries retrieved and indexp to reflect the next module index. If the last file descriptor was retrieved, indexp is set to -1. If the plug-in passes a NULL infop buffer, indexp and countp are still updated — just as if infop were non-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)

The dbx fds callback routine parameters are:

Parameter
Description
session
Session identifier
infop
Allocated array of dbx_plugin_fdinfo_t structures or NULL
fdinfo_size
Size of a single dbx_plugin_fdinfo_t structure
indexp
Starting/next file descriptor (where zero corresponds to the first file descriptor)
countp
number of file descriptors
The dbx fds callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_POINTER indexp is NULL or countp is NULL
  • DBX_PLUGIN_BAD_ARG fdinfo_size is not valid or * countp == 0
  • DBX_PLUGIN_UNAVAILABLE process not active or info not in core

modules

The dbx modules callback routine allows you to get information on loaded modules for the process. You can either:
  • Call iteratively to get information separately on each module. Or,
  • Call once to get the total number of modules and call once again to get information on all modules simultaneously.

If the plug-in passes a non-NULL infop buffer, dbx populates the buffer with the number of entries requested in *countp, starting with the module referenced by *indexp.

If the plug-in passes a *countp that is greater than the number of remaining entries, dbx retrieves all remaining entries. dbx updates countp to reflect the actual number of entries retrieved and updates indexp to reflect the next module index. If the last module was retrieved, indexp is set to -1. If the plug-in passes a NULL infop buffer, indexp and countp are still updated — just as if infop were not NULL.
Note: This routine allocates memory to hold the file name and member character strings. The caller must free this memory when it is no longer needed.
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)

The dbx modules callback routine parameters are:

Parameter
Description
session
Session identifier
infop
Allocated array of dbx_plugin_modinfo_t structures or NULL
modinfo_size
Size of a single dbx_plugin_modinfo_t structure
indexp
Starting/next module (where zero corresponds to the first module)
countp
Number of modules
The dbx modules callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_POINTER indexp is NULL or countp is NULL
  • DBX_PLUGIN_BAD_ARG modinfo_size is not valid or *countp == 0

regions

The dbx regions callback routine allows you to get information on memory regions for the process.

Retrieved regions can include:
  • Main thread stack region (DBX_PLUGIN_REGION_STACK)
  • User data region (DBX_PLUGIN_REGION_DATA)
  • Process private data region (DBX_PLUGIN_REGION_SDATA)
  • Memory mapped region (DBX_PLUGIN_REGION_MMAP)
  • Shared memory region (DBX_PLUGIN_REGION_SHM)
You can either:
  • Call iteratively to get information separately on one region. Or,
  • Call once to get the total number of regions and call once again to get information on all regions simultaneously.

If the plug-in passes a non-NULL infop buffer, dbx populates the buffer with the number of entries requested in *countp, starting with the region referenced by *indexp.

If the plug-in passes a *countp that is greater than the number of remaining entries, dbx retrieves all remaining entries. dbx updates countp to reflect the actual number of entries retrieved and indexp to reflect the next region index.

If the last region was retrieved, indexp is set to -1. If the plug-in passes a NULL infop buffer, indexp and countp are still updated — just as if infop were non-NULL.
Note: Currently, this routine is only implemented for sessions representing core files. Sufficient information is not available to dbx for sessions representing live processes. Calls for such sessions return 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)

The dbx regions callback routine parameters are:

Parameter
Description
session
Session identifier
infop
Allocated array of dbx_plugin_region_t structures or NULL
reginfo_size
Size of a single dbx_plugin_reginfo_t structure
indexp
Starting/next region (where zero corresponds to the first region)
countp
Number of regions
The dbx regions callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_POINTER indexp is NULL or countp is NULL
  • DBX_PLUGIN_BAD_ARG reginfo_size is not valid or *countp == 0
  • DBX_PLUGIN_UNAVAILABLE session represents a live processes and regions not accessible

threads

The dbx threads callback routine allows you to get information on the kernel threads in the process.

You can either:
  • Call iteratively to get information separately on one thread. Or,
  • Call once to get the total number of threads and call once again to get information on all threads simultaneously.

If the plug-in passes a non-NULL infop buffer, dbx populates the buffer with the number of entries requested in *countp, starting with the thread referenced by *indexp.

If the plug-in passes a *countp that is greater than or equal to the number of remaining entries, dbx retrieves all remaining entries and updates countp to reflect the actual number of entries retrieved.

If the last entry was retrieved, and countp is less than its passed value, indexp is set to -1. Otherwise, indexp is updated to reflect the thread id for the next request.
Note: If the value of countp passed is equal to the number of available entries, countp remains the same, but indexp is not set to -1.

If the plug-in passes a NULL infop buffer, indexp and countp are updated — just as if infop were non-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)

The dbx threads callback routine parameters are:

Parameter
Description
session
Session identifier
infop
Allocated array of dbx_plugin_thrdinfo_t structures or NULL
thrdinfo_size
Size of a single dbx_plugin_thrdinfo_t structure
indexp
Starting/next thread id (where, on input, zero corresponds to the first thread)
countp
Number of threads
The dbx threads callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_POINTER indexp is NULL or countp is NULL
  • DBX_PLUGIN_BAD_ID *indexp is not a valid id
  • DBX_PLUGIN_BAD_ARG thrdinfo_size is not valid or *countp ==0
  • DBX_PLUGIN_UNAVAILABLE process not active or entries not in core

pthreads

The dbx pthreads callback routine allows you to get information on pthreads in the process, including any kernel thread associations.

You can either:
  • Call iteratively to get information separately on one pthread. Or,
  • Call once to get the total number of pthreads and call once again to get information on all pthreads simultaneously.

If the plug-in passes a non-NULL infop buffer, dbx populates the buffer with the number of entries requested in *countp, starting with the pthread referenced by *indexp.

If the plug-in passes a *countp that is greater than the number of remaining entries, dbx retrieves all remaining entries. dbx updates countp to reflect the actual number of entries retrieved and indexp to reflect the pthread handle for the next request.

If the last entry was retrieved, indexp is set to -1. If the plug-in passes a NULL infop buffer, indexp and countp are still updated — just as if infop were non-NULL.

If the first pthread is requested and countp is updated to zero, the process is not pthreaded.

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)

The dbx pthreads callback routine parameters are:

Parameter
Description
session
Session identifier
infop
Allocated array of dbx_plugin_pthinfo_t structures or NULL
pthrdinfo_size
Size of a single dbx_plugin_pthrdinfo_t structure
indexp
Starting/next pthread handle (where, on input, zero corresponds to the first pthread and DBX_PLUGIN_PTHREAD_CURRENT corresponds to the current pthread in dbx)
countp
Number of pthreads
The dbx pthreads callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_POINTER indexp is NULL or countp is NULL
  • DBX_PLUGIN_BAD_ARG pthrdinfo_size is not valid or *countp == 0

get_thread_context

The dbx get_thread_context callback routine allows you to read a kernel thread's general purpose, special purpose, and floating point registers. dbx populates the contextp parameter.

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)

The dbx get_thread_context callback routine parameters are:

Parameter
Description
session
Session identifier
reg_flags
Logical OR of at least one of DBX_PLUGIN_REG_GPRS, DBX_PLUGIN_REG_SPRS, DBX_PLUGIN_REG_FPRS, DBX_PLUGIN_REG_EXT
id
Kernel thread tid (tid64_t)
contextp
Allocated dbx_plugin_context_t structure
context_size
Size of dbx_plugin_context_t structure. If the DBX_PLUGIN_REG_EXT register flag is used, then the size of the dbx_plugin_extctx_t structure should be used. The dbx_plugin_extctx_t structure is an extended version of dbx_plugin_context_t structure.
The dbx get_thread_context callback routine return codes are:
  • DBX_PLUGIN_SUCCESS.
  • DBX_PLUGIN_BAD_SESSION session is not valid.
  • DBX_PLUGIN_BAD_ID id is not valid.
  • DBX_PLUGIN_BAD_ARG reg_flags is not valid or context_size is not valid.
  • DBX_PLUGIN_BAD_POINTER contextp is NULL
  • DBX_PLUGIN_UNAVAILABLE process is not active or thread is in kernel mode and registers are not accessible.

set_thread_context

The dbx set_thread_context callback routine allows you to write to a kernel thread's general purpose, special purpose and floating point registers.

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)

The dbx set_thread_context callback routine parameters are:

Parameter
Description
session
Session identifier
reg_flags
Logical OR of at least one of DBX_PLUGIN_REG_GPRS, DBX_PLUGIN_REG_SPRS, DBX_PLUGIN_REG_FPRS, DBX_PLUGIN_REG_EXT
id
Kernel thread tid (tid64_t)
contextp
Allocated dbx_plugin_context_t structure
context_size
Size of dbx_plugin_context_t structure. If the DBX_PLUGIN_REG_EXT register flag is used, then the size of the dbx_plugin_extctx_t structure should be used. The dbx_plugin_extctx_t structure is an extended version of dbx_plugin_context_t structure.
The dbx set_thread_context callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_ID id is not valid
  • DBX_PLUGIN_BAD_ARG reg_flags is not valid or context_size is not valid
  • DBX_PLUGIN_BAD_POINTER contextp is NULL
  • DBX_PLUGIN_UNAVAILABLE process is not active or thread is in kernel mode and registers are not accessible

get_pthread_context

The dbx get_pthread_context callback routine allows you to read a pthread's general purpose, special purpose and floating point registers. dbx populates the contextp parameter.

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)

The dbx get_pthread_context callback routine parameters are:

Parameter
Description
session
Session identifier
reg_flags
logical OR of at least one of DBX_PLUGIN_REG_GPRS, DBX_PLUGIN_REG_SPRS, DBX_PLUGIN_REG_FPRS, DBX_PLUGIN_REG_EXT
id
pthread handle (pthdb_pthread_t)
contextp
Allocated dbx_plugin_context_t structure
context_size
size of dbx_plugin_context_t structure. If the DBX_PLUGIN_REG_EXT register flag is used, then the size of the dbx_plugin_extctx_t structure should be used. The dbx_plugin_extctx_t structure is an extended version of dbx_plugin_context_t structure.
The dbx get_pthread_context callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_ID id is not valid.
  • DBX_PLUGIN_BAD_ARG reg_flags is not valid or context_size is not valid
  • DBX_PLUGIN_BAD_POINTER contextp is NULL
  • DBX_PLUGIN_UNAVAILABLE process is not active or thread is in kernel mode and registers are not accessible

set_pthread_context

The dbx set_pthread_context callback routine allows you to write to a pthread's general purpose, special purpose and floating point registers.

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)

The dbx set_pthread_context callback routine parameters are:

Parameter
Description
session
Session identifier
reg_flags
Logical OR of at least one of DBX_PLUGIN_REG_GPRS, DBX_PLUGIN_REG_SPRS, DBX_PLUGIN_REG_FPRS, DBX_PLUGIN_REG_EXT
id
Pthread handle (pthdb_pthread_t)
contextp
Allocated dbx_plugin_context_t structure
context_size
Size of dbx_plugin_context_t structure. If the DBX_PLUGIN_REG_EXT register flag is used, then the size of the dbx_plugin_extctx_t structure should be used. The dbx_plugin_extctx_t structure is an extended version of dbx_plugin_context_t structure.
The dbx set_pthread_context callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_ID id is not valid
  • DBX_PLUGIN_BAD_ARG reg_flags is not valid or context_size is not valid
  • DBX_PLUGIN_BAD_POINTER contextp is NULL
  • DBX_PLUGIN_UNAVAILABLE process is not active or kernel thread associated with pthread is in kernel mode and registers are not accessible

read_memory

The dbx read_memory callback routine allows you to read from the process's address space. dbx populates the buffer parameter.

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

The dbx read_memory callback routine parameters are:

Parameter
Description
session
Session identifier
addr
Address to read from
buffer
Allocated buffer to hold memory contents
len
Number of bytes to read
The dbx read_memory callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_POINTER buffer is NULL
  • DBX_PLUGIN_UNAVAILABLE unable to read from addr

write_memory

The dbx write_memory callback routine allows you to write to the process's address space.

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

The dbx write_memory callback routine parameters are:

Parameter
Description
session
Session identifier
addr
Address to write to
buffer
Allocated and initialized buffer
len
Number of bytes to write
The dbx write_memory callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_POINTER buffer is NULL
  • DBX_PLUGIN_UNAVAILABLE unable to write to addr

locate_symbol

The dbx locate_symbol callback routine allows you to convert symbol names to addresses.

The plug-in must initialize the name and mod fields of each entry in the symbols parameter array. The name field specifies the name of the symbol to be located. The mod field specifies the module index of the module in which the lookup should occur. A mod field initialized to -1 denotes that all modules should be searched.

dbx populates the addr field. Any unknown symbols have an address of zero. If the symbol is located and all modules searched, dbx updates the mod field with the actual module index of the symbol.

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

The dbx locate_symbol callback routine parameters are:

Parameter
Description
session
Session identifier
symbols
Allocated array of dbx_plugin_sym_t structures with the name and mod fields initialized
syminfo_size
Size of dbx_plugin_sym_t structure
count
Number of symbols to locate
The dbx locate_symbol callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_ARG syminfo_size is not valid
  • DBX_PLUGIN_BAD_POINTER symbols is NULL

what_function

The dbx what_function callback routine allows you to convert text addresses to symbols.

The plug-in must initialize the addr field of each entry in the symbols parameter array. The addr field specifies an instruction address within the function to be identified.

dbx populates the name field. Any unknown text address has a name of NULL. dbx populates the mod field with the actual module index of the text address.

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

The dbx what_function callback routine parameters are:

Parameter
Description
session
Session identifier
symbols
Allocated array of dbx_plugin_sym_t structures with the addr field(s) initialized with text address(es)
syminfo_size
Size of dbx_plugin_sym_t structure
count
Number of addresses to convert
The dbx what_function callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_ARG syminfo_size is not valid
  • DBX_PLUGIN_BAD_POINTER symbols is NULL

print

The dbx print callback routine allows you to display informational output or error output.

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

The dbx print callback routine parameters are:

Parameter
Description
session
session identifier
print_mode
Either DBX_PLUGIN_PRINT_MODE_OUT or DBX_PLUGIN_PRINT_MODE_ERR
message
Character string for dbx to display
The dbx print callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_ARG print_mode is not valid
  • DBX_PLUGIN_BAD_POINTER message is NULL

alias

The dbx alias callback routine allows you to create an alias for a plug-in subcommand.

The syntax of the plugin dbx subcommand requires the dbx user to type a prefix of plugin Name for each plug-in subcommand invocation. To provide a way to shorten such invocations, dbx allows plug-ins to create new aliases.

The alias and expansion parameters should provide a description of the new alias. The syntax is the same as the syntax defined for the alias dbx subcommand.

The following are example invocations of the dbx alias callback routine:
alias("intprt", "plugin xyz interpret");
alias("intprt2(addr, count, format)", "addr / count format; plugin xyz interpret addr");
Note: If you try to create an alias that has the same name as an existing alias, the request is denied and a warning message is displayed. Plug-in developers are encouraged to carry out alias creation in a way that allows users to correct alias conflicts. One way to accomplish this is by reading alias definitions from a configuration file that is packaged with the plug-in.
typedef int (*dbx_plugin_alias_service_t)(dbx_plugin_session_t session,
                                          const char *alias,
                                          const char *expansion)

The dbx alias callback routine parameters are:

Parameter
Description
session
Session identifier
alias
Character string representing the alias name and optional parameter
expansion
Character string representing the alias expansion
The dbx alias callback routine return codes are:
  • DBX_PLUGIN_SUCCESS
  • DBX_PLUGIN_BAD_SESSION session is not valid
  • DBX_PLUGIN_BAD_ARG alias is not valid
  • DBX_PLUGIN_BAD_POINTER alias is NULL or expansion is NULL
  • DBX_PLUGIN_UNAVAILABLE an alias with an identical name already exists

Example

  1. The following example defines a help subcommand and a hello subcommand:
    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. To compile the example plug-in, type:
    cc -q64 -o libdbx_example.so example.c -bM:Sre -bE:example.exp -bnoentry