flyinghead / flycast

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

Ill-formed 'bl' instruction #1148

Closed Canar closed 11 months ago

Canar commented 11 months 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 11 months 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 11 months 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 11 months 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 11 months ago

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