The debugger can be used to run a bind program against a particular device. It outputs a trace of the bind program's execution, describing why the driver would or would not bind to the device.
You can run the debugger in the following ways:
Note: The debugger can only be used with bind programs written in the bind language described in this page.
You can run the debugger with the --debug
option in the bind compiler.
fx bindc debug \ --include src/devices/bind/fuchsia.usb/fuchsia.usb.bind \ --debug tools/bindc/examples/gizmo.dev \ tools/bindc/examples/gizmo.bind
The bind program source and the library sources are in the formats described in the bind rules and bind libraries sections, respectively. The --debug
option takes a file containing a specification of the device to run the bind program against.
Note: The --debug
and --output
options are mutually exclusive, so the C header file will not be generated when running the compiler in debug mode.
The debugger takes a file specifying the device to run the bind program against. This specification is simply a list of key-value pairs describing the properties of the device.
This example device specification can be found at //tools/bindc/examples/gizmo.dev.
fuchsia.BIND_PROTOCOL = fuchsia.usb.BIND_PROTOCOL.INTERFACE fuchsia.BIND_USB_VID = fuchsia.usb.BIND_USB_VID.REALTEK fuchsia.BIND_USB_CLASS = fuchsia.usb.BIND_USB_CLASS.VIDEO fuchsia.BIND_USB_SUBCLASS = fuchsia.usb.BIND_USB_SUBCLASS.VIDEO_CONTROL
device-specification = ( property )* ; property = compound-identifier , "=" , value ; compound-identifier = IDENTIFIER ( "." , IDENTIFIER )* ; value = compound-identifier | STRING-LITERAL | NUMERIC-LITERAL | "true" | "false" ;
An identifier matches the regex [a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])?
.
A string literal matches the regex ”[^”]*”
, and a numeric literal matches the regex [0-9]+
or 0x[0-9A-F]+
.
The bind compiler will ignore (treat as whitespace) any line prefixed by //
, and any multiple lines delimited by /*
and */
.
The debugger is run using its package URL. For example:
fx run fuchsia-pkg://fuchsia.com/bind_debugger#meta/bind_debugger.cmx \ /system/driver/bt-hci-intel.so \ class/bt-transport/000
The command takes the path of the driver to debug and the path of the device to debug it against.
There are two ways to specify the device:
class/bt-transport/000
.sys/pci/00:14.0/xhci/usb-bus/003/003/ifc-000/bt_transport_usb
.Both of the paths are relative to /dev/.
The topological path can be determined from the ouptut of dm dump
. For example, tracing the path to the node [bt_transport_usb]
in the output below gives the topological path sys/pci/00:14.0/xhci/usb-bus/003/003/ifc-000/bt_transport_usb
.
[root] <root> pid=3456 [null] pid=3456 /boot/driver/builtin.so [zero] pid=3456 /boot/driver/builtin.so [misc] <misc> pid=3525 [demo-fifo] pid=3525 /boot/driver/demo-fifo.so [ktrace] pid=3525 /boot/driver/ktrace.so [sys] <sys> pid=3369 /boot/driver/platform-bus.so [pci] pid=3369 /boot/driver/platform-bus-x86.so [00:00.0] pid=3369 /boot/driver/bus-pci.so [00:14.0] pid=3369 /boot/driver/bus-pci.so <00:14.0> pid=4384 /boot/driver/bus-pci.proxy.so [xhci] pid=4384 /boot/driver/xhci.so [xdc] pid=4384 /boot/driver/xhci.so [usb-bus] pid=4384 /boot/driver/usb-bus.so [001] pid=4384 /boot/driver/usb-bus.so [001] pid=4384 /boot/driver/usb-composite.so [ifc-000] pid=4384 /boot/driver/usb-composite.so [usb-hid] pid=4384 /boot/driver/usb-hid.so [hid-device-000] pid=4384 /boot/driver/hid.so [002] pid=4384 /boot/driver/usb-bus.so [002] pid=4384 /boot/driver/usb-composite.so [ifc-000] pid=4384 /boot/driver/usb-composite.so [usb-hid] pid=4384 /boot/driver/usb-hid.so [hid-device-000] pid=4384 /boot/driver/hid.so [003] pid=4384 /boot/driver/usb-bus.so [003] pid=4384 /boot/driver/usb-composite.so [ifc-000] pid=4384 /boot/driver/usb-composite.so [bt_transport_usb] pid=4384 /boot/driver/bt-transport-usb.so [bt_hci_intel] pid=4384 /system/driver/bt-hci-intel.so [bt_host] pid=4384 /system/driver/bt-host.so
The output of the debugger is a trace of the bind program's execution. The trace contains information about whether each statement in the bind program succeeded, and why or why not. For example, if a condition statement failed because the device did not have the required value, the debugger will output what the actual value of the device was (or the fact that the device had no value for that property). The trace also includes information about which branches were taken in if statements.
The output of the debugger when running the host tool command above is:
Line 4: Condition statement succeeded: fuchsia.BIND_PROTOCOL == fuchsia.usb.BIND_PROTOCOL.INTERFACE; Line 6: If statement condition failed: fuchsia.BIND_USB_VID == fuchsia.usb.BIND_USB_VID.INTEL Actual value of `fuchsia.BIND_USB_VID` was `fuchsia.usb.BIND_USB_VID.REALTEK` [0xbda]. Line 9: If statement condition succeeded: fuchsia.BIND_USB_VID == fuchsia.usb.BIND_USB_VID.REALTEK Line 11: Accept statement succeeded. Value of `fuchsia.BIND_USB_CLASS` was `fuchsia.usb.BIND_USB_CLASS.VIDEO` [0xe]. Driver binds to device.
If you run the debugger on the Fuchsia target device, you will see similar output information. However, information such as identifiers and source code snippets may be missing, since the system only stores the bind program bytecode, not the source code.
The trace shows the outcome of each statement that was reached while executing the bind program:
The debugger outputs that the driver would successfully bind to a device with these properties.