编译静态文件系统测试工具【FIO】并在QEMU中运行

编译静态文件系统测试工具【FIO】并在QEMU中运行

  • 1. FIO静态编译
  • 2. 在QEMU中运行可能存在的问题
  • 3*. 问题的排查

编译静态的文件系统测试工具就可以在QEMU环境中测试自己的文件系统而不必担心机器崩溃啦,关于如何搭建内核开发环境可参考博主的前置文章:用VSCode + QEMU跑起来能够可视化Debug的NOVA文件系统。

今天介绍的是FIO文件系统测试法宝的静态编译

1. FIO静态编译

将下面命令中的path替换为你想要的安装路径,用于找寻编译出来的二进制文件。例如,我将其设为我的home/fio-static目录:/home/fio-static

git clone https://github.com/axboe/fio.git && cd fio

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

make && make install

运行完上述命令,安装就成功了。生成的二进制文件位于path/bin,对博主来说就是:/home/fio-static/bin,运行下述命令,验证是否安装成功

path/bin/fio -verison

如果安装成功,则显示FIO的版本号。
最后,验证其为静态二进制文件:

ldd path/bin/fio

输出应该是类似该文件为非动态可执行文件之类的东西,OK,现在把FIO二进制文件移植到initramfs中去即可。

2. 在QEMU中运行可能存在的问题

博主在完成移植后,启动QEMU,运行FIO,报错如下:

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

遇到这个问题后,重新配置FIO,加入取消优化的选项。

git clone https://github.com/axboe/fio.git && cd fio

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

make && make install

重新拷贝启动QEMU,运行FIO,即可。

3*. 问题的排查

参考[x86][linux]AVX512指令引起的进程crash。

首先将编译出来的二进制FIO给Dump出来,看看在哪条指令处崩溃了:

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

观察opcode ip:401520,即在401520指令处崩溃,定位:

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 
  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处是shlx指令,那么意味着执行指令shlx崩溃了。这段代码应该对应什么呢?打开FIO源码仓库,利用VSCode全局搜索prio_tree_init,找到如下代码:

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;
}

我这一看啊,就个汇编对应的肯定是移位操作。QEMU也是用的x86架构,不至于移位操作不支持吧,那肯定是GCC编译时一些优化选项在作怪,于是想到利用--disable-optimizations移除FIO编译时的优化选项,再次观察objdumpprio_tree_init编译结果:

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>

可以看到,shlx已经不存在了,果然是编译器优化的问题。立马启动QEMU运行FIO,成功了。那么,从现在开始就可以在模拟环境中进行文件系统的FIO测试了。

OK,起飞

你可能感兴趣的:(操作系统,测试工具,qemu,linux,file,system,DEBUG)