flyinghead / flycast

Flycast is a multiplatform Sega Dreamcast, Naomi, Naomi 2 and Atomiswave emulator
GNU General Public License v2.0
1.51k stars 176 forks source link

Ill-formed 'bl' instruction #1148

Closed Canar closed 1 year ago

Canar commented 1 year ago

Platform / OS / Hardware:

Armbian, rk322x-box variant. rk3229 SoC. ARMv7l / Cortex A7 CPU, Mali 400, 2GB RAM. Dolamee D5 is the brand. Specific build can be found here: https://forum.armbian.com/topic/12656-csc-armbian-for-rk322x-tv-boxes/

Github hash: 0070f9abad69c67ea47603c516f4e33490aeae2f

Description of the Issue

Runs after building with the setting USE_GLES2:BOOL=ON in CMakeCache, everything else default. (Execution fails without this flag set with the following error rend/gui.cpp:3123 E[COMMON]: Fatal error : Cannot initialize the graphics API, but this is not a bug I think anyone should care much about unless you're really insistent that the build never produce bad output; kinda expected on a weird platform that I see no other build reports for...)

Upon attempting execution of BIOS ROM, Crazy Taxi, or Sonic Adventure images, execution fails with the following error:

Ill-formed 'bl' instruction.
in /home/user/flycast/core/deps/vixl/aarch32/assembler-aarch32.h, line 6148
Aborted

Logs Gathered

This is the typical output from such a failed run.

00:00:452 sdl/sdl.cpp:601 N[RENDERER]: Monitor refresh rate: 60 Hz (1024 x 768)
00:00:477 rend/gui.cpp:294 N[RENDERER]: Screen DPI is 96, size 640 x 480. Scaling by 1.00
00:00:663 rend/gles/gles.cpp:562 N[RENDERER]: OpenGL ES version 2.0
00:12:584 hw/mem/addrspace.cpp:431 N[VMEM]: Info: nvmem is enabled
00:12:735 hw/mem/addrspace.cpp:462 N[VMEM]: BASE 0x84d90000 RAM(16 MB) 0x90d90000 VRAM64(8 MB) 0x88d90000 ARAM(2 MB) 0xa4d90000
Ill-formed 'bl' instruction.
in /home/user/flycast/core/deps/vixl/aarch32/assembler-aarch32.h, line 6148
Aborted

Additionally, but far less relevant: My attempts to log this error by running

$ ./flycast |& tee flycast.log

cause this error message to be omitted from output, but the software still runs with the same failure mode.

flyinghead commented 1 year ago

Could you debug flycast and get a stack trace for this crash? Use handle SIGSEGV nostop noprintbefore running to ignore (expected) seg faults.

Canar commented 1 year ago

To be clear, this is not a crash. It exits with the "Aborted" message and error code 134. The macro VIXL_ABORT_WITH_MSG is called. I see no segfault error. But when I break at the mentioned line, I get the following backtrace on a debug build:

#0  vixl::aarch32::Assembler::UnimplementedDelegate (this=0x1bdfe48 <aica::arm::ass>, type=vixl::aarch32::kBl) at /home/user/flycast/core/deps/vixl/aarch32/assembler-aarch32.h:6148
#1  0x0059c966 in vixl::aarch32::Assembler::Delegate (this=0x1bdfe48 <aica::arm::ass>, type=vixl::aarch32::kBl) at /home/user/flycast/core/deps/vixl/aarch32/assembler-aarch32.h:752
#2  0x016d0254 in vixl::aarch32::Assembler::bl (this=0x1bdfe48 <aica::arm::ass>, cond=..., location=0x74dbc2bc) at /home/user/flycast/core/deps/vixl/aarch32/assembler-aarch32.cc:3510
#3  0x0059f33e in vixl::aarch32::MacroAssembler::Bl (this=0x1bdfe48 <aica::arm::ass>, cond=..., label=0x74dbc2bc) at /home/user/flycast/core/deps/vixl/aarch32/macro-assembler-aarch32.h:1443
#4  0x0059f3a8 in vixl::aarch32::MacroAssembler::Bl (this=0x1bdfe48 <aica::arm::ass>, label=0x74dbc2bc) at /home/user/flycast/core/deps/vixl/aarch32/macro-assembler-aarch32.h:1446
#5  0x006121d8 in aica::arm::call (code=0x5abe69 <aica::arm::CPUFiq()>, saveFlags=false) at /home/user/flycast/core/hw/arm7/arm7_rec_arm32.cpp:292
#6  0x00612f8e in aica::arm::arm7backend_flush () at /home/user/flycast/core/hw/arm7/arm7_rec_arm32.cpp:506
#7  0x00a219ae in aica::arm::recompiler::flush () at /home/user/flycast/core/hw/arm7/arm7_rec.cpp:671
#8  0x00a21ade in aica::arm::recompiler::init () at /home/user/flycast/core/hw/arm7/arm7_rec.cpp:695
#9  0x005ab466 in aica::arm::init () at /home/user/flycast/core/hw/arm7/arm7.cpp:98
#10 0x0058bcfc in aica::init () at /home/user/flycast/core/hw/aica/aica.cpp:281
#11 0x00489d1e in Emulator::init (this=0x1bc62f8 <emu>) at /home/user/flycast/core/emulator.cpp:473
#12 0x00489f1c in Emulator::loadGame (this=0x1bc62f8 <emu>, path=0x30a1498 "", progress=0x2b25d78 <gameLoader>) at /home/user/flycast/core/emulator.cpp:518
#13 0x01671030 in BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}::operator()() const (__closure=0x30a148c)
    at /home/user/flycast/core/rend/gui_util.h:80
#14 0x0167be02 in std::__invoke_impl<void, BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}>(std::__invoke_other, BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}&&) (__f=...) at /usr/include/c++/12/bits/invoke.h:61
#15 0x0167bdca in std::__invoke<BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}>(BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}&&) (__fn=...) at /usr/include/c++/12/bits/invoke.h:96
#16 0x0167bd72 in std::thread::_Invoker<std::tuple<BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}> >::_M_invoke<0u>(std::_Index_tuple<0u>) (this=0x30a148c) at /usr/include/c++/12/bits/std_thread.h:252
#17 0x0167bd48 in std::thread::_Invoker<std::tuple<BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}> >::operator()() (
    this=0x30a148c) at /usr/include/c++/12/bits/std_thread.h:259
#18 0x0167bc36 in std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}> >, void>::operator()() const (this=0x74dbca30) at /usr/include/c++/12/future:1410
#19 0x0167bb92 in std::__invoke_impl<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}> >, void>&>(std::__invoke_other, std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}> >, void>&) (__f=...) at /usr/include/c++/12/bits/invoke.h:61
#20 0x0167ba38 in std::__invoke_r<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>, std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>,
std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}> >, void>&>(std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}> >, void>&) (__fn=...) at /usr/include/c++/12/bits/invoke.h:116
#21 0x0167b8fc in std::_Function_handler<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> (), std::__future_base::_Task_setter<std::unique_ptr<std::__future_base::_Result<void>, std::__future_base::_Result_base::_Deleter>, std::thread::_Invoker<std::tuple<BackgroundGameLoader::load(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::{lambda()#1}> >, void> >::_M_invoke(std::_Any_data const&) (__functor=...) at /usr/include/c++/12/bits/std_function.h:291
#22 0x0048f126 in std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>::operator()() const (this=0x74dbca30)
    at /usr/include/c++/12/bits/std_function.h:591
#23 0x0048e08c in std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*) (this=0x30a146c,
    __f=0x74dbca30, __did_set=0x74dbc9df) at /usr/include/c++/12/future:572
#24 0x004947d0 in std::__invoke_impl<void, void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(std::__invoke_memfun_deref, void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (
    __f=@0x74dbc9e0: (void (std::__future_base::_State_baseV2::*)(std::__future_base::_State_baseV2 * const, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()> *, bool *)) 0x48e075 <std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>,
    __t=@0x74dbc9f0: 0x30a146c) at /usr/include/c++/12/bits/invoke.h:74
#25 0x00491f68 in std::__invoke<void (std::__future_base::_State_baseV2::*)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*>(void (std::__future_base::_State_baseV2::*&&)(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*), std::__future_base::_State_baseV2*&&, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*&&, bool*&&) (
    __fn=@0x74dbc9e0: (void (std::__future_base::_State_baseV2::*)(std::__future_base::_State_baseV2 * const, std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter>()> *, bool *)) 0x48e075 <std::__future_base::_State_baseV2::_M_do_set(std::function<std::unique_ptr<std::__future_base::_Result_base, std::__future_base::_Result_base::_Deleter> ()>*, bool*)>)
    at /usr/include/c++/12/bits/invoke.h:96
Canar commented 1 year ago

I tried updating vixl to the most recent Linaro git version to see if that was relevant. Everything worked as before, save that VIXL_CODE_BUFFER_MMAP define needs to be set (probably when HAVE_MMAP is set, but that wasn't quite adequate). Did not improve my circumstance.

flyinghead commented 1 year ago

Thanks for the stack trace. It's a flycast error so upgrading vixl won't help. I just pushed a fix.