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:

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:

Reporting the vdev status

The VDEV_CTRL_STATUS callback is invoked when a SIGUSR2 signal is sent to a qvm process instance. If you want your vdev to output information about its status, you can use this callback and the qvm_report() function. The following snippet is from the ser8250 vdev's vd8250_control() function:

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 Definitions in vdev-core.h 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.

Note: For a full description of vdev_logf() and the other logging functions (which support logging at the QVM level), see the QNX Hypervisor Virtual Device Developer's API Reference.
Suppose in our vdev code we want to report that we've entered a particular function and started processing its arguments. We could then use the following call:
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 “OK” return 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.h entry 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.