Debugging a vdev
You can use the same techniques to debug a vdev as you use to debug other code in QNX Neutrino.
A vdev is a shared library (*.so file) loaded at runtime by the qvm process instances (VMs) whose guests require the vdev.
Since a vdev is loaded into a qvm process instance, you can attach to that process to investigate. For example, you can:
- put breakpoints in your vdev
- run the qvm process instance in debug mode
- load symbols in the qvm process instance
Since your vdev necessarily interacts with a guest, you may also need to do some debugging
of the guest driver (see the User's Guide
Monitoring and
Troubleshooting
chapter). If your vdev is in a VM (qvm
process instance) that hosts a Linux guest, you may need to debug the relevant Linux OS
module.
For information about debugging problems with vdev option parsing, see Parsing the vdev options
in the chapter The
Basics: vdev trace
.
For more information about debugging in a QNX Neutrino system, see:
- the QNX Neutrino Programmer's Guide:
Compiling and Debugging
- the QNX Neutrino Utilities Reference: gdb
- the QNX Momentics IDE User's Guide:
Debugging Applications
Reporting the vdev status
The VDEV_CTRL_STATUS callback is invoked when a SIGUSR1 or SIGUSR2 signal is sent to a qvm process instance. If you want your vdev to output information about its status, use this callback and the qvm_report() function. If the first signal (SIGUSR1) was sent, the qvm_report() function outputs INFO messages only. If it was the second signal (SIGUSR2), qvm_report() dumps the VM memory and registers to a file, and the dump information also includes INFO messages.
case VDEV_CTRL_STATUS:
qvm_report("dlr=0x%x lcr=0x%x ier=0x%x mcr=0x%x", \
state->s_dlr, state->s_lcr, state->s_ier, state->s_mcr);
break;For more information, see A guest-host hardware device intermediary (vdev ser8250)
in the
Advanced Topics
chapter, and qvm_report() in the Virtual Device Developer's API
Reference.
Logging
You can perform message logging for a given vdev. The QNX hypervisor provides an API that can be used by any vdev, including one that you write, to log messages consisting of formatted strings.
When configuring the qvm process, you can use the logger option to control which message types (severity levels) are logged and where they are output (e.g., stderr, stdout), for all vdevs. This mapping of message severity levels to output destinations is defined in the VM configuration file (*.qvmconf). For more information, see the logger entry in the User's Guide.
You can override the logging for a given vdev, however, by using the log option in the vdev's own configuration. For details on doing so, see the log option entry in the User's Guide.
Here, we give an example of using the vdev_logf() API function. This function is declared in sys/outpipe.h, so you must include this header file in any source files that use it.
void particular_function(vdev_t vdp) {
...
vdev_logf(QVM_OUTI_QVM, vdp, "%s: OPTIONS_START", __func__);
...
}
Here, we use a macro, QVM_OUTI_QVM, to define the value for the first
argument. This macro constructs a message attribute that indicates a type (severity level)
of information, an internal source (because a vdev is reporting the message), and an
OKreturn code (because there's no error). For a list of all
QVM_OUT* macros that generate attributes for different
message types, sources, and return codes, see the Definitions in outpipe.hentry in the Virtual Device Developer's API Reference.
For the second argument, we use the vdev_t pointer passed into our function that's doing the message reporting. The third argument defines a formatted string with one placeholder for another string value, while the last argument provides the current function name for that other string.
