Compile the static file system test tool [FIO] and run it in QEMU

Compiling static file system testing tools can test your file system in QEMU environment without worrying about machine crash 🤭, For how to build a kernel development environment, please refer to the front article of the blogger: Running with VSCode + QEMU can visualize the Debug NOVA file system.

Today is the static compilation of FIO file system testing magic weapon

1. FIO static compilation

Replace the path in the following command with the installation path you want to find the compiled binary file. For example, I set it to my home / FIO static Directory: / home / FIO static

git clone && cd fio

./configure --build-static --prefix=path

make && make install

After running the above command, the installation is successful. The generated binary file is located in path/bin, which is: / home / FIO static / bin for bloggers. Run the following command to verify whether the installation is successful

path/bin/fio -verison

If the installation is successful, the version number of FIO is displayed.
Finally, verify that it is a static binary file:

ldd path/bin/fio

The output should be something like the file is a non dynamic executable file. OK, now transplant the FIO binary file to initramfs.

2. Possible problems in QEMU operation

After completing the transplantation, the blogger starts QEMU and runs FIO. The errors are as follows:

[   11.340497] traps: fio[1107] trap invalid opcode ip:401520 sp:7ffd92667930 error:0 in fio[400000+1ff000]

After encountering this problem, reconfigure FIO and add the option of canceling optimization.

git clone && cd fio

./configure --build-static --disable-optimizations --prefix=path

make && make install

Restart QEMU and run FIO.

3*. Troubleshooting of problems

reference resources Process crash caused by [x86][linux]AVX512 instruction.

First, Dump the compiled binary FIO to see which instruction crashed:

objdump -D /home/fio-static/bin/fio

Observe opcode ip:401520, i.e. crash at 401520 instruction. Locate:

0000000000401510 <prio_tree_init>:
  401510:	b8 01 00 00 00       	mov    $0x1,%eax
  401515:	b9 01 00 00 00       	mov    $0x1,%ecx
  40151a:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)
  401520:	c4 e2 f9 f7 d1       	shlx   %rax,%rcx,%rdx
  401525:	48 ff ca             	dec    %rdx
  401528:	48 89 14 c5 38 25 8e 	mov    %rdx,0x8e2538(,%rax,8)
  40152f:	00 
  401530:	48 ff c0             	inc    %rax
  401533:	48 83 f8 40          	cmp    $0x40,%rax
  401537:	75 e7                	jne    401520 <prio_tree_init+0x10>
  401539:	48 c7 05 f4 11 4e 00 	movq   $0xffffffffffffffff,0x4e11f4(%rip)        # 8e2738 <index_bits_to_maxindex+0x1f8>
  401540:	ff ff ff ff 
  401544:	c3                   	retq   
  401545:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  40154c:	00 00 00 
  40154f:	90                   	nop

401520 is the shlx instruction, which means that the execution instruction shlx crashed. What should this code correspond to? Open the FIO source code warehouse and use VSCode to search prio globally_ tree_ Init, find the following code:

static void fio_init prio_tree_init(void)
	unsigned int i;
	for (i = 0; i < FIO_ARRAY_SIZE(index_bits_to_maxindex) - 1; i++) {
		index_bits_to_maxindex[i] = (1UL << (i + 1)) - 1;
	index_bits_to_maxindex[FIO_ARRAY_SIZE(index_bits_to_maxindex) - 1] = ~0UL;

When I look at it, it's just a compilation. The corresponding operation must be a shift operation. QEMU is also an x86 architecture, so the shift operation is not supported. It must be caused by some optimization options during GCC compilation. So I thought of using -- Disable optimizations to remove the optimization options during FIO compilation and observe the prio of objdump again_ tree_ Init compilation result:

000000000040f4e1 <prio_tree_init>:
  40f4e1:	55                   	push   %rbp
  40f4e2:	48 89 e5             	mov    %rsp,%rbp
  40f4e5:	48 83 ec 10          	sub    $0x10,%rsp
  40f4e9:	be 40 00 00 00       	mov    $0x40,%esi
  40f4ee:	bf 08 ba 56 00       	mov    $0x56ba08,%edi
  40f4f3:	b8 00 00 00 00       	mov    $0x0,%eax
  40f4f8:	e8 43 d8 0a 00       	callq  4bcd40 <_IO_printf>
  40f4fd:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)
  40f504:	eb 3a                	jmp    40f540 <prio_tree_init+0x5f>
  40f506:	8b 45 fc             	mov    -0x4(%rbp),%eax
  40f509:	89 c6                	mov    %eax,%esi
  40f50b:	bf 2b ba 56 00       	mov    $0x56ba2b,%edi
  40f510:	b8 00 00 00 00       	mov    $0x0,%eax
  40f515:	e8 26 d8 0a 00       	callq  4bcd40 <_IO_printf>
  40f51a:	8b 45 fc             	mov    -0x4(%rbp),%eax
  40f51d:	83 c0 01             	add    $0x1,%eax
  40f520:	ba 01 00 00 00       	mov    $0x1,%edx
  40f525:	89 c1                	mov    %eax,%ecx
  40f527:	48 d3 e2             	shl    %cl,%rdx
  40f52a:	48 89 d0             	mov    %rdx,%rax
  40f52d:	48 8d 50 ff          	lea    -0x1(%rax),%rdx
  40f531:	8b 45 fc             	mov    -0x4(%rbp),%eax
  40f534:	48 89 14 c5 c0 09 8e 	mov    %rdx,0x8e09c0(,%rax,8)
  40f53b:	00 
  40f53c:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)
  40f540:	83 7d fc 3e          	cmpl   $0x3e,-0x4(%rbp)
  40f544:	76 c0                	jbe    40f506 <prio_tree_init+0x25>

It can be seen that shlx no longer exists. It is indeed a compiler optimization problem. Start QEMU immediately and run FIO. It's successful. Then, from now on, you can test the FIO of the file system in the simulation environment.

OK, take off 🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫🛫

Keywords: Linux Operating System debug qemu

Added by jambroo on Mon, 21 Feb 2022 08:45:04 +0200