baremetal: get exit status working with on_exit :-)

This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-05-08 00:00:01 +00:00
parent 18ca0b3c9c
commit 406ee82cf3
16 changed files with 79 additions and 34 deletions

View File

@@ -11916,7 +11916,7 @@ svc 0x00123456
and we can see from the docs that `0x18` stands for the `SYS_EXIT` command.
This is also how we implement the `exit(0)` system call in C for QEMU for link:baremetal/exit.c[] through the Newlib via the function `_exit` at link:baremetal/lib/kwargs['c'][].
This is also how we implement the `exit(0)` system call in C for QEMU for link:baremetal/exit0.c[] through the Newlib via the function `_exit` at link:baremetal/lib/kwargs['c'][].
Other magic operations we can do with semihosting besides exiting the on the host include:
@@ -11990,7 +11990,7 @@ sudo apt-get install gcc-arm-none-eabi qemu-system-arm
However, there are as usual limitations to using prebuilts:
* certain examples fail to build with the Ubuntu packaged toolchain. E.g.: link:baremetal/exit.c[] fails with:
* certain examples fail to build with the Ubuntu packaged toolchain. E.g.: link:baremetal/exit0.c[] fails with:
+
....
/usr/lib/gcc/arm-none-eabi/6.3.1/../../../arm-none-eabi/lib/libg.a(lib_a-fini.o): In function `__libc_fini_array':
@@ -14001,20 +14001,42 @@ For other arch / emulator combinations, we know how to do it:
* gem5: <<m5-fail>> works on all archs
* user mode: QEMU forwards exit status, gem5 we do some log parsing: <<gem5-syscall-emulation-exit-status>>
For this reason, we just parse the terminal output for a magic failure string to check if tests failed.
Since we can't do it for QEMU arm, the only reliable solution is to just parse the guest serial output for a magic failure string to check if tests failed.
In order to cover all archs, our run scripts parse the serial output looking for a line line containing only exactly the magic regular expression:
Our run scripts parse the serial output looking for a line line containing only exactly the magic regular expression:
....
lkmc_exit_status_(\d+)
....
and then exit with the given regular expression.
and then exit with the given regular expression, e.g.:
....
./run --arch aarch64 baremetal
....
This magic output string is notably generated by:
* the `exit()` baremetal function when `status != 1`. This is in turn called by failed assertions for example from `lkmc_assert_fail`, which is used by <<baremetal-tests>>
* link:rootfs_overlay/lkmc/test_fail.sh[], which is used by <<test-userland-in-full-system>>
* the `exit()` baremetal function when `status != 1`.
+
Unfortunately the only way we found to set this up was with `on_exit`: link:https://github.com/cirosantilli/linux-kernel-module-cheat/issues/59[].
+
Trying to patch `_exit` directly fails since at that point some de-initialization has already happened which prevents the print.
+
So setup this `on_exit` automatically from all our <<baremetal-bootloaders>>, so it just works automatically for the examples that use the bootloaders: https://stackoverflow.com/questions/44097610/pass-parameter-to-atexit/49659697#49659697
+
The following examples end up testing that our setup is working:
+
* link:baremetal/lkmc_assert_fail.c[]
* link:baremetal/return1.c[]
* link:baremetal/return2.c[]
* link:baremetal/exit0.c[]
* link:baremetal/exit1.c[]
* link:baremetal/arch/arm/return1.S[]
* link:baremetal/arch/aarch64/return1.S[]
Beware that on Linux kernel simulations, you cannot even echo that string from userland, since userland stdout shows up on the serial.
==== Non-automated tests