Convey is an inter-process communication tool with capabilities to communicate through a named pipe, a serial port or a TCP connection. Notable features include the communication with Hyper-V virtual machines through an emulated COM port. Simplicity from the use point is the most point of focus for this tool.
Convey is distributed under the BSD 2-clause license.
- Get onto the VC++ shell
- nmake /nologo
- Get onto the VC++ shell
- nmake /nologo CXX="c:\Program Files\LLVM\bin\clang-cl.exe" LD="c:\Program Files\LLVM\bin\lld-link.exe"
The physical COM port usage is a simple as invoking the tool with the COM port name.
- Invoke
convey.exe COM<num> - For the port with number >= 10, use
\.\COM<num>
There's no difference whether it's a native COM port or a USB-to-COM convertor. As long as the COM port appears under the device manager, it is usable.
Hypervisors like Hyper-V provide a functionality to emulate a serial port in the VM, while exposing it as a named pipe to the host Windows machine. Using convey, it is possible to connect to a virtual machine's virtual serial port from the host system using the exposed named pipe.
Assign a named pipe that will be passed as a COM1 into a VM.
Set-VMComPort -VMName <vm name> -Number 1 -Path \\.\pipe\<pipe name>
View configured COM ports on a VM.
Get-VMComPort -VMName <vm name>
Add console=ttyS0,115200 console=tty0 to the kernel parameters. Note, that ttyS0 is what is usually
available on a typical setup. Depending on the hardware and system configuration, this device name can
be different.
Configure autologin for ttyS0 or another terminal device you've chosen.
- Start the VM.
- Start an elevated cmd window and invoke
convey.exe \\.\pipe\<pipe name>.
- Before starting the VM, invoke convey with the
--pollargument. - Start the VM.
Besides named pipes and COM ports, convey can also communicate over a TCP connection.
- Invoke
convey.exe tcp:<host>:<port>to connect to a TCP server. - Invoke
convey.exe tcp-listen:<port>to accept a single incoming connection.
The --poll and --reconnect options work here too. --poll keeps retrying the connection on startup, --reconnect re-establishes it after a drop.
This targets a Windows guest whose serial port is available on TCP, as done by QEMU, cloud-hypervisor and others. The bridge mode lets WinDbg reach such a serial-over-TCP target through a named pipe, without any third-party virtual COM driver. Convey creates the pipe server and pumps raw bytes between it and the TCP endpoint.
- On host, start the bridge with
convey.exe --bridge --pipe-server \\.\pipe\kd0 tcp:<host>:<port>. - Attach WinDbg with
windbg -k com:pipe,port=\\.\pipe\kd0,resets=0,reconnect.
The bridge carries raw bytes only, so there's no console, no CRLF trimming and no xterm handling. It reconnects on its own, which lets it survive target resets.
Convey can log the session to a file, for example to keep a boot or panic log that would otherwise scroll away. --log captures the full session; the received stream already includes what you type on an echoing console, but a non-echoing target (or a one-way stream) needs the sent stream too.
--log <file>logs the full session into one file, each block marked>(sent) or<(received).--log-recv <file>logs only the received stream (target to host).--log-send <file>logs only the sent stream (host to target).--log-appendappends to the log files instead of overwriting them.
The log options may be combined to write several files at once (for example a marked session plus a raw received dump), but each must name a different file. --log-append applies to all of them. For example, convey.exe --log session.log \\.\pipe\<pipe name>. The logs stay open across --reconnect so they are not truncated on every reconnect.
- Download the unstripped vmlinux to your local machine, or
- Download the vmlinux and the debug symbols.
- Download the kernel sources corresponding to the given kernel build.
Invoke WSL on an elevated console and run
socat PTY,link=/tmp/my-vm-pty,raw,echo=0 SYSTEM:"while true; do ./convey.exe //./pipe/<pipe name>; sleep 0.1; done"
Add nokaslr to the kernel command line.
See also a more detailed documentation on the (kgdb)[https://www.kernel.org/doc/html/v4.17/dev-tools/kgdb.html] page.
Inside the VM, execute the commands below:
echo ttyS0 > /sys/module/kgdboc/parameters/kgdbocecho g > /proc/sysrq-trigger
Add a suitable configuration to the kernel command line, for example kgdboc=ttyS0,115200 kgdbwait.
Run another WSL shell and invoke
$ gdb ./vmlinux
(gdb) set serial baud 115200
(gdb) target remote /tmp/my-vm-pty
Here you are. This doesn't need an elevated console.
stty -F /dev/ttyS0 -echo
Use stty to set the desired columns and rows number, for example
stty columns 235 rows 62
(gdb) set substitute-path /sources/were/compiled/here /put/sources/here
To add multiple folders to be searched by GDB, use
(gdb) set dir /path/to/base/dir
Alternatively, unpack kernel sources under /usr/src/kernel or where ever else the kernel was built.
Forgot to bring kernel into the debugging mode?
Add nokaslr to the kernel parameters.
If the lockdown= option is on the kernel cmdline, it has to be removed.
Some distribution might also allow to disable lockdown at runtime. In a VM, Alt+SysRq+x can be sent by:
$ echo 1 > /proc/sys/kernel/sysrq
$ echo x > /proc/sysrq-trigger
- https://www.kernel.org/doc/html/latest/admin-guide/serial-console.html
- https://www.kernel.org/doc/html/v4.17/dev-tools/kgdb.html
- https://www.elinux.org/Debugging_The_Linux_Kernel_Using_Gdb
- http://man7.org/linux/man-pages/man1/stty.1.html
- https://linux.die.net/man/1/socat
- https://stackoverflow.com/questions/14584504/problems-to-connect-gdb-over-an-serial-port-to-an-kgdb-build-kernel
- https://unix.stackexchange.com/questions/125183/how-to-find-which-serial-port-is-in-use
- https://sourceware.org/gdb/onlinedocs/gdb/Source-Path.html
- Check VMWare and VirtualBox.
- Check other things like Windows VM or any other possible counter part exposing named pipes.
Add console options for more flexibility.- Implement sending/receiving a file.
- ...