Asynchronous I/O

Asynchronous I/O is a method of performing I/O in which the application issues requests to the kernel (e.g. to write some data into a file) and at some point later the application receives an event from the kernel to indicate the result of the request.

The user/kernel interface of asynchronous I/O creates significant complexities for the Undo engine since it needs to keep track of all the currently active operations.

Warning

Asynchronous I/O support is under development and therefore there are likely to be issues. Please report any issues via our support channel and we’ll try to get these fixed as soon as possible.

Asynchronous I/O Preload Library

Undo’s asynchronous I/O preload library is a shared library that can be linked into a program at run-time via LD_PRELOAD and thereby keep track of its asynchronous I/O contexts and operations.

The preload library effectively intercepts asynchronous I/O system calls and holds information and performs adjustments as necessary for the Undo Engine so that it can safely record asynchronous I/O operations.

If you plan to perform asynchronous I/O operations then you will need to use the preload library.

Warning

The preload library doesn’t support raw asynchronous I/O system calls (i.e. performed with native assembly instructions). It is however supported to use the C library syscall() function to perform asynchronous I/O system calls.

Starting asynchronous I/O programs under UndoDB

To debug an asynchronous I/O program, start it under UndoDB the same as any other program:

$ udb <args>
[...]
(udb)

UndoDB will inspect the executable and automatically load the asynchronous I/O preload library if required. Asynchronous I/O is only enabled automatically when UndoDB detects that libaio.so is in use or that the asynchronous I/O preload library is being used. If your executable does not include libaio.so, because it uses the system calls directly or dynamically loads the library, asynchronous I/O can be forced on or off with the --undodb-enable-async-io parameter, and the options yes and no.

If asynchronous I/O is detected when it has been disabled, debugging can continue, but the following warning will be shown:

$ udb --undodb-async-io no <args>
[...]
udb: Asynchronous I/O disabled by user, but debuggee environment or debuggee libraries
            suggest it may be needed. Continuing.
(udb)

Attaching to programs using asynchronous I/O

UndoDB needs the asynchronous I/O preload library to correctly track and modify asynchronous I/O contexts. Without it, UndoDB will be able to attach to the program but will not be able to correctly record or replay any asynchronous I/O operation.

$ udb <args>
[...]
(udb) attach <pid>
udb: UndoDB has detected that libaio.so is in use. To debug Asynchronous I/O calls,
     UndoDB's preload library: "libundodb_aio_preload_<architecture>.so" must
     be added to the LD_PRELOAD environment variable of the debuggee.
(udb) continue
[...]
Program received signal SIGTRAP, Trace/breakpoint trap.
udb: error: Forward execution cannot continue from here.
     because: Unsupported system call
     because: Asynchronous I/O (in this case, the "io_setup" system call) not
    supported.
(udb)

The solution to this issue is to run the program with Undo’s asynchronous I/O preload library. Here’s an example on 64-bit x86:

$ LD_PRELOAD=libundodb_aio_preload_x64.so <program> <args> &
$ udb <program>
(udb) attach <pid>
(udb) continue
udb: The program has exited, but is still being debugged.
udb: (You may use undodb commands to go backwards.)
(udb)

Asynchronous I/O in Live Recorder

Currently, Live Recorder does not support the checks or parameters used by UndoDB to enable or disable asynchronous I/O. To record a program that uses asynchronous I/O operations with Live Recorder, the user must provide the preload library manually by specifying it in the environment and enable asynchronous I/O in Live Record with UNDODB_async_io_catch=0. For example, to record a 64-bit x86 program that used asynchronous I/O, use:

$ UNDODB_async_io_catch=0 LD_PRELOAD=libundodb_aio_preload_x64.so live-record <args>

Attaching to a program with Live Recorder is a similar to attaching to the program in UndoDB:

$ LD_PRELOAD=libundodb_aio_preload_x64.so <program> <args> &
$ UNDODB_async_io_catch=0 live-record --pid <args>
[...]
$ udb --undodb-load <recording>
(udb) continue
[...]
Program received signal SIGSTOP, Stopped (signal).
udb: Have switched to record mode.
udb: End of recording reached.
udb: (You may use undodb commands to go backwards.)
(udb)

Supported Architectures

The correct preload library depends on the architecture for which your debuggee application was compiled, as follows:

OS Debuggee architecture Preload library
Linux x86 64-bit libundodb_aio_preload_x64.so
Linux x86 32-bit libundodb_aio_preload_x32.so
Linux ARMv7 AArch32 Hard-float libundodb_aio_preload_armhf.so
Linux ARMv7 AArch32 Soft-float libundodb_aio_preload_arm.so
Linux ARMv8 AArch32 libundodb_aio_preload_armhf.so
Linux ARMv8 AArch64 * libundodb_aio_preload_arm64.so
Android x86 64-bit Not supported
Android x86 32-bit Not supported
Android ARMv7 AArch32 Not supported
Android ARMv8 AArch32 Not supported
Android ARMv8 AArch64 * Not supported

UndoDB automatically chooses one of these libraries from it’s undolr/ directory based on the architecture of the program being debugged. When attaching, this library is used to check if the debuggee uses the asynchronous I/O preload library. You can override UndoDB’s default library location by using --undodb-async-io-preload-path <path>.

Buffers with incorrect permissions

As part of its operation the preload library accesses asynchronous I/O buffers. If your program provides asynchronous I/O buffers with incorrect permissions (e.g. providing a PROT_NONE buffer) then you would normally receive an error from the kernel (generally EFAULT). However since the preload library accesses the asynchronous I/O buffers directly it is likely to experience a SIGSEGV in these cases. If you experience a crash from the preload library it may therefore indicate the buffer permissions are incorrect.