InfiniTimeOrg / InfiniSim

Simulator for InfiniTime user interface without needing a PineTime
GNU General Public License v3.0
163 stars 65 forks source link

Linking main executable with lvgl(?) failed on Mac (M1) #127

Open GottemHams opened 10 months ago

GottemHams commented 10 months ago

I've been trying to get the simulator working on my Mac (M1), but it keeps failing when linking the main infinisim executable to what I assume is the lvgl library:

[100%] Linking CXX executable infinisim
Undefined symbols for architecture arm64:
  "__lv_anim_ll", referenced from:
      __lv_anim_core_init in libsim-base.a(lv_anim.c.o)
      _anim_task in libsim-base.a(lv_anim.c.o)
      _anim_mark_list_change in libsim-base.a(lv_anim.c.o)
      _lv_anim_start in libsim-base.a(lv_anim.c.o)
      _lv_anim_del in libsim-base.a(lv_anim.c.o)
      _lv_anim_del_all in libsim-base.a(lv_anim.c.o)
      _lv_anim_get in libsim-base.a(lv_anim.c.o)
      ...
  "__lv_disp_ll", referenced from:
      _lv_init in libsim-base.a(lv_obj.c.o)
      _lv_obj_get_disp in libsim-base.a(lv_obj.c.o)
      _lv_disp_drv_register in libsim-base.a(lv_hal_disp.c.o)
      _lv_disp_remove in libsim-base.a(lv_hal_disp.c.o)
      _lv_disp_get_next in libsim-base.a(lv_hal_disp.c.o)
  "__lv_draw_mask_list", referenced from:
      _lv_draw_mask_add in libsim-base.a(lv_draw_mask.c.o)
      _lv_draw_mask_apply in libsim-base.a(lv_draw_mask.c.o)
      _lv_draw_mask_remove_id in libsim-base.a(lv_draw_mask.c.o)
      _lv_draw_mask_remove_custom in libsim-base.a(lv_draw_mask.c.o)
      _lv_draw_mask_get_cnt in libsim-base.a(lv_draw_mask.c.o)
  "__lv_drv_ll", referenced from:
      __lv_fs_init in libsim-base.a(lv_fs.c.o)
      _lv_fs_get_drv in libsim-base.a(lv_fs.c.o)
      _lv_fs_drv_register in libsim-base.a(lv_fs.c.o)
      _lv_fs_get_letters in libsim-base.a(lv_fs.c.o)
  "__lv_font_decompr_buf", referenced from:
      _lv_font_get_bitmap_fmt_txt in libsim-base.a(lv_font_fmt_txt.c.o)
      __lv_font_clean_up_fmt_txt in libsim-base.a(lv_font_fmt_txt.c.o)
  "__lv_img_cache_array", referenced from:
      __lv_img_cache_open in libsim-base.a(lv_img_cache.c.o)
      _lv_img_cache_set_size in libsim-base.a(lv_img_cache.c.o)
      _lv_img_cache_invalidate_src in libsim-base.a(lv_img_cache.c.o)
  "__lv_img_defoder_ll", referenced from:
      __lv_img_decoder_init in libsim-base.a(lv_img_decoder.c.o)
      _lv_img_decoder_create in libsim-base.a(lv_img_decoder.c.o)
      _lv_img_decoder_get_info in libsim-base.a(lv_img_decoder.c.o)
      _lv_img_decoder_open in libsim-base.a(lv_img_decoder.c.o)
      _lv_img_decoder_delete in libsim-base.a(lv_img_decoder.c.o)
  "__lv_indev_ll", referenced from:
      _lv_init in libsim-base.a(lv_obj.c.o)
      _lv_indev_drv_register in libsim-base.a(lv_hal_indev.c.o)
      _lv_indev_get_next in libsim-base.a(lv_hal_indev.c.o)
  "__lv_mem_buf", referenced from:
      __lv_mem_buf_get in libsim-base.a(lv_mem.c.o)
      __lv_mem_buf_release in libsim-base.a(lv_mem.c.o)
      __lv_mem_buf_free_all in libsim-base.a(lv_mem.c.o)
     (maybe you meant: __lv_mem_buf_free_all, __lv_mem_buf_release , __lv_mem_buf_get )
  "__lv_obj_style_trans_ll", referenced from:
      _lv_init in libsim-base.a(lv_obj.c.o)
      _trans_del in libsim-base.a(lv_obj.c.o)
      _trans_create in libsim-base.a(lv_obj.c.o)
      _trans_anim_ready_cb in libsim-base.a(lv_obj.c.o)
      _lv_obj_finish_transitions in libsim-base.a(lv_obj.c.o)
  "__lv_task_act", referenced from:
      _lv_task_handler in libsim-base.a(lv_task.c.o)
      _lv_task_del in libsim-base.a(lv_task.c.o)
  "__lv_task_ll", referenced from:
      __lv_task_core_init in libsim-base.a(lv_task.c.o)
      _lv_task_handler in libsim-base.a(lv_task.c.o)
      _lv_task_create in libsim-base.a(lv_task.c.o)
      _lv_task_del in libsim-base.a(lv_task.c.o)
      _lv_task_set_prio in libsim-base.a(lv_task.c.o)
      _lv_task_get_next in libsim-base.a(lv_task.c.o)
  "__lv_theme_empty_styles", referenced from:
      _lv_theme_empty_init in libsim-base.a(lv_theme_empty.c.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [infinisim] Error 1
make[1]: *** [CMakeFiles/infinisim.dir/all] Error 2
make: *** [all] Error 2

In the readme it says:

-DInfiniTime_DIR=InfiniTime: a full path to an existing InfiniTime repository checked out. Inside that directory the src/libs/lvgl submodule must be checked out as well. The default value points to the InfiniTime submodule in this repository.

I verified that the submodule is indeed checked out. Also, I can build the main firmware itself without problems. For the simulator's dependencies I just ran npm install from the repo root, since there's a package.json. For building I simply used the given instructions:

cmake -S . -B build
cmake --build build -j4
NeroBurner commented 10 months ago

I just tried to compile with clang++. That works on Linux. So just that isn't the issue. Sorry got no idea why that happens and I have no Mac to test it out. The sim should be happy when SDL2 is found (which it should be as you're clearly at the build step already.

You could try to compile https://github.com/lvgl/lv_port_pc_eclipse/tree/dev-7.0 as this is the simulator InfiniSim is based on. Be sure to use the dev-7.0 branch, as InfiniTime uses lvgl v7 (instead of the current v8)

GottemHams commented 10 months ago

v7.0 of that repo doesn't even compile right from the very beginning, something about keyboard_handler being undefined. The master branch compiles without issue though, and I can also run it properly (like scrolling etc actually works).

I decided to add -- VERBOSE=1 to the cmake --build command. Also, the used compiler is /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++, for which --version says:

Apple clang version 13.1.6 (clang-1316.0.21.2.5)
Target: arm64-apple-darwin21.6.0
Thread model: posix

Anyways, I noticed in the verbose output that all the lv_* stuff is compiled into libsim-base.a, which is in fact included in the eventual c++ command for compiling the main infinisim executable. But somehow it's still unable to detect the symbols. So then I added the whole bunch of files like CMakeFiles/sim-base.dir/InfiniTime/src/libs/lvgl/src/lv_core/lv_disp.c.o as inputs to the failing c++ command and ran it manually. It now compiles successfully.

For in the meantime I've scripted around the build process to compile a small dummy file for all those lvgl-related files (to pass the initial compiler check) and include them in CFLAGS/CXXFLAGS. Very dirty hack, but for now it works. Or well, sort of, once I also apply the patches mentioned in https://github.com/InfiniTimeOrg/InfiniSim/issues/25. At least then the simulator finally starts with the InfiniTime interface and keyboard commands do work, but not the mouse. The display in general seems to never update. I think the version of lvgl that's used by v7.0 of the simulator's base is simply too old to work properly on newer macOS. ;_;

GottemHams commented 10 months ago

Alright so I looked into the differences between the latest version of lv_port_pc_eclipse and what InfiniSim uses. In the main loop it simply calls lv_timer_handler() and usleep()'s for 1 millisecond instead of 20 or possibly 30. Then for lv_drivers, the monitor.c that's present for InfiniSim actually doesn't seem to be in use any longer. Instead, the relevant code seems to have been moved to sdl_gpu.c where it uses lv_timer_create() instead of lv_task_create(). I dunno if it means anything in this specific case but they do imply different things. Timers are basically hardware interrupt-based callbacks that run within the thread that created them, while threads run autonomously and they also have their own stack memory. If these are timers by that definition then it does make sense the crash doesn't happen anymore (runs on the main thread).

So anyways, time to compile the simulator with debug information (-g) and check the backtrace:

* thread #8: tid = 0x2bad1e, 0x000000018ecfed98 libsystem_kernel.dylib`__pthread_kill + 8, name = 'displayapp', stop reason = signal SIGABRT
(lldb) bt
...
    frame #15: 0x00000001000f8e64 infinisim`sdl_event_handler(t=0x00006000017263c8) at monitor.c:233:11
    frame #16: 0x0000000100035258 infinisim`lv_task_exec(task=0x00006000017263c8) at lv_task.c:386:27
    frame #17: 0x0000000100034ff4 infinisim`lv_task_handler at lv_task.c:134:20
    frame #18: 0x00000001000e0144 infinisim`Pinetime::Applications::DisplayApp::Refresh(this=0x0000000100161ab8) at DisplayApp.cpp:195:22
    frame #19: 0x00000001000e005c infinisim`Pinetime::Applications::DisplayApp::Process(instance=0x0000000100161ab8) at DisplayApp.cpp:129:10
    frame #20: 0x00000001000fe350 infinisim`sdl_function_wrapper(instance=0x0000000100162b30) at task.cpp:61:3
...

The truncated parts are just calls to libsdl etc, not much we can do about that regardless so I didn't include it.

Updating the simulator to work with the latest versions of its base components is probably still the best solution, but I wanted to get this working on a much shorter term. Here's a full diff against the current version of InfiniSim's repo (including submodules, yeah this is very dirty):

Submodule InfiniTime contains modified content
diff --git a/InfiniTime/src/components/datetime/DateTimeController.cpp b/InfiniTime/src/components/datetime/DateTimeController.cpp
index 9e9fb6e4..3cd761e2 100644
--- a/InfiniTime/src/components/datetime/DateTimeController.cpp
+++ b/InfiniTime/src/components/datetime/DateTimeController.cpp
@@ -69,7 +69,7 @@ void DateTime::UpdateTime(uint32_t systickCounter) {
   currentDateTime += std::chrono::seconds(correctedDelta);
   uptime += std::chrono::seconds(correctedDelta);

-  std::time_t currentTime = std::chrono::system_clock::to_time_t(currentDateTime);
+  std::time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::time_point_cast<std::chrono::system_clock::duration>(currentDateTime));
   localTime = *std::localtime(&currentTime);

   auto minute = Minutes();
Submodule lv_drivers contains modified content
diff --git a/lv_drivers/display/monitor.c b/lv_drivers/display/monitor.c
index 53534f4..84e1ef1 100644
--- a/lv_drivers/display/monitor.c
+++ b/lv_drivers/display/monitor.c
@@ -67,6 +67,7 @@ static void monitor_sdl_refr(lv_task_t * t);
 /***********************
  *   GLOBAL PROTOTYPES
  ***********************/
+void sdl_event_handler_mainthread(void);

 /**********************
  *  STATIC VARIABLES
@@ -95,7 +96,6 @@ static volatile bool sdl_quit_qry = false;
 void monitor_init(void)
 {
     monitor_sdl_init();
-    lv_task_create(sdl_event_handler, 10, LV_TASK_PRIO_HIGH, NULL);
 }

 /**
@@ -214,6 +214,14 @@ void monitor_flush2(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t
 }
 #endif

+/**
+ * Meant for calling sdl_event_handler() from other threads (can only be used from the main thread though)
+ */
+void sdl_event_handler_mainthread(void)
+{
+    sdl_event_handler(NULL);
+}
+
 /**********************
  *   STATIC FUNCTIONS
  **********************/
@@ -226,7 +234,8 @@ void monitor_flush2(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t

 static void sdl_event_handler(lv_task_t * t)
 {
-    (void)t;
+    if(t)
+        (void)t;

     /*Refresh handling*/
     SDL_Event event;
diff --git a/main.cpp b/main.cpp
index 8070db7..59c7cb4 100644
--- a/main.cpp
+++ b/main.cpp
@@ -93,6 +93,7 @@ typedef struct {
 #endif
 }monitor_t;
 extern monitor_t monitor;
+extern void sdl_event_handler_mainthread(void);
 }

 void saveScreenshot()
@@ -1030,11 +1031,17 @@ int main(int argc, char **argv)
   // initialize the core of our Simulator
   Framework fw(fw_status_window_visible, 240,240);

+  //uint8_t sdl_tick = 0;
   while(1) {
       fw.handle_keys(); // key event polling
       fw.handle_touch_and_button();
       fw.refresh();
-      usleep(LV_DISP_DEF_REFR_PERIOD * 1000);
+      usleep(1000);
+      //sdl_tick++;
+      //if(sdl_tick >= 10) {
+          sdl_event_handler_mainthread();
+      //    sdl_tick = 0;
+      //}
   }

   return 0;

So basically, remove the separate thread that was originally causing the crash and run its code directly on the main thread. The UI now actually responds to everything. I originally added the sdl_tick to simulate the 10 ms interval from lv_task_create(), but that actually makes the UI feel sluggish. Apparently I execute the click and drag faster than those 10 ms, because if I drag more slowly it does respond properly (I also noticed you can't move the cursor outside the program's window or it won't respond either).

Here's a screenshot showing a different OS name, I figured that was the easiest thing to edit for verification.

If we were to do a quick comparison against lv_port_pc_eclipse, then we "should" call lv_task_handler() just before the usleep() as well. But it's actually already handled through fw.refresh(), which calls refresh_screen() where finally lv_task_handler() may be called.

Now, there are a few lingering minor issues but at least I can simulate the firmware.

  1. When quitting the simulator (via the standard macOS red circle thingy or even Ctrl+C/SIGINT from the shell), this happens:
    
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x328)
    frame #0: 0x00000001000fdd64 infinisim`std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<void*, unsigned long>, void*>*> std::__1::__hash_table<std::__1::__hash_value_type<void*, unsigned long>, std::__1::__unordered_map_hasher<void*, std::__1::__hash_value_type<void*, unsigned long>, std::__1::hash<void*>, std::__1::equal_to<void*>, true>, std::__1::__unordered_map_equal<void*, std::__1::__hash_value_type<void*, unsigned long>, std::__1::equal_to<void*>, std::__1::hash<void*>, true>, std::__1::allocator<std::__1::__hash_value_type<void*, unsigned long> > >::find<void*>(this=0x0000000100160a10, __k=0x000000016fdf45d8) at __hash_table:2394:31
    2391     if (__bc != 0)
    2392     {
    2393         size_t __chash = __constrain_hash(__hash, __bc);
    -> 2394         __next_pointer __nd = __bucket_list_[__chash];
    2395         if (__nd != nullptr)
    2396         {
    2397             for (__nd = __nd->__next_; __nd != nullptr &&
    thread #7, name = 'displayapp', stop reason = EXC_BAD_ACCESS (code=1, address=0x8)
    frame #0: 0x00000001000e0904 infinisim`Pinetime::Applications::Screens::Screen::IsRunning(this=0x0000000000000000) const at Screen.h:25:18
    22           static void RefreshTaskCallback(lv_task_t* task);
    23   
    24           bool IsRunning() const {
    -> 25             return running;
    26           }
    27   
    28           /** @return false if the button hasn't been handled by the app, true if it has been handled */
    Target 0: (infinisim) stopped.
    (lldb) bt
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x3f0)
    * frame #0: 0x00000001000fdd5c infinisim`std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<void*, unsigned long>, void*>*> std::__1::__hash_table<std::__1::__hash_value_type<void*, unsigned long>, std::__1::__unordered_map_hasher<void*, std::__1::__hash_value_type<void*, unsigned long>, std::__1::hash<void*>, std::__1::equal_to<void*>, true>, std::__1::__unordered_map_equal<void*, std::__1::__hash_value_type<void*, unsigned long>, std::__1::equal_to<void*>, std::__1::hash<void*>, true>, std::__1::allocator<std::__1::__hash_value_type<void*, unsigned long> > >::find<void*>(this=0x0000000100160a10, __k=0x000000016fdf45f8) at __hash_table:2394:31
    frame #1: 0x00000001000fdc80 infinisim`unsigned long std::__1::__hash_table<std::__1::__hash_value_type<void*, unsigned long>, std::__1::__unordered_map_hasher<void*, std::__1::__hash_value_type<void*, unsigned long>, std::__1::hash<void*>, std::__1::equal_to<void*>, true>, std::__1::__unordered_map_equal<void*, std::__1::__hash_value_type<void*, unsigned long>, std::__1::equal_to<void*>, std::__1::hash<void*>, true>, std::__1::allocator<std::__1::__hash_value_type<void*, unsigned long> > >::__erase_unique<void*>(this=0x0000000100160a10, __k=0x000000016fdf45f8) at __hash_table:2533:20
    frame #2: 0x00000001000f9ce8 infinisim`std::__1::unordered_map<void*, unsigned long, std::__1::hash<void*>, std::__1::equal_to<void*>, std::__1::allocator<std::__1::pair<void* const, unsigned long> > >::erase(this=0x0000000100160a10 size=63, __k=0x000000016fdf45f8) at unordered_map:1272:59
    frame #3: 0x00000001000f9cb4 infinisim`::vPortFree(pv=0x0000600000005480) at FreeRTOS.cpp:35:19
    frame #4: 0x0000000100032a70 infinisim`lv_mem_free(data=0x0000600000005488) at lv_mem.c:261:5
    frame #5: 0x00000001000156e0 infinisim`_lv_style_list_reset(list=0x00006000031004d0) at lv_style.c:295:29
    frame #6: 0x000000010000acd0 infinisim`lv_obj_clean_style_list(obj=0x0000600003100488, part='\0') at lv_obj.c:1237:5
    frame #7: 0x00000001000080e8 infinisim`lv_obj_signal(obj=0x0000600003100488, sign='\0', param=0x0000000000000000) at lv_obj.c:4033:9
    frame #8: 0x00000001000526fc infinisim`lv_label_signal(label=0x0000600003100488, sign='\0', param=0x0000000000000000) at lv_label.c:1395:11
    frame #9: 0x0000000100008c94 infinisim`obj_del_core(obj=0x0000600003100488) at lv_obj.c:3815:5
    frame #10: 0x0000000100008a20 infinisim`lv_obj_del(obj=0x0000600003100488) at lv_obj.c:485:5
    frame #11: 0x0000000100008dc4 infinisim`lv_obj_clean(obj=0x0000600003010008) at lv_obj.c:532:9
    frame #12: 0x0000000100099528 infinisim`Pinetime::Applications::Screens::SystemInfo::~SystemInfo(this=0x0000000100d05b80) at SystemInfo.cpp:71:3
    frame #13: 0x00000001000995dc infinisim`Pinetime::Applications::Screens::SystemInfo::~SystemInfo(this=0x0000000100d05b80) at SystemInfo.cpp:70:27
    frame #14: 0x0000000100099608 infinisim`Pinetime::Applications::Screens::SystemInfo::~SystemInfo(this=0x0000000100d05b80) at SystemInfo.cpp:70:27
    frame #15: 0x000000010006e354 infinisim`std::__1::default_delete<Pinetime::Applications::Screens::Screen>::operator(this=0x0000000100162ba8, __ptr=0x0000000100d05b80)(Pinetime::Applications::Screens::Screen*) const at unique_ptr.h:57:5
    frame #16: 0x000000010006e2c8 infinisim`std::__1::unique_ptr<Pinetime::Applications::Screens::Screen, std::__1::default_delete<Pinetime::Applications::Screens::Screen> >::reset(this=0x0000000100162ba8, __p=0x0000000000000000) at unique_ptr.h:318:7
    frame #17: 0x000000010006e258 infinisim`std::__1::unique_ptr<Pinetime::Applications::Screens::Screen, std::__1::default_delete<Pinetime::Applications::Screens::Screen> >::~unique_ptr(this=0x0000000100162ba8) at unique_ptr.h:272:19
    frame #18: 0x000000010006e1fc infinisim`std::__1::unique_ptr<Pinetime::Applications::Screens::Screen, std::__1::default_delete<Pinetime::Applications::Screens::Screen> >::~unique_ptr(this=0x0000000100162ba8) at unique_ptr.h:272:17
    frame #19: 0x000000010006e1b0 infinisim`Pinetime::Applications::DisplayApp::~DisplayApp(this=0x0000000100161ab8) at DisplayApp.h:48:11
    frame #20: 0x000000010006c4d0 infinisim`Pinetime::Applications::DisplayApp::~DisplayApp(this=0x0000000100161ab8) at DisplayApp.h:48:11
    frame #21: 0x000000018ec1fdd0 libsystem_c.dylib`__cxa_finalize_ranges + 464
    frame #22: 0x000000018ec1fb74 libsystem_c.dylib`exit + 44
    frame #23: 0x00000001000f91a8 infinisim`sdl_event_handler(t=0x0000000000000000) at monitor.c:274:9
    frame #24: 0x00000001000f90d4 infinisim`sdl_event_handler_mainthread at monitor.c:222:5
    frame #25: 0x000000010006c788 infinisim`main(argc=1, argv=0x000000016fdf4ce8) at main.cpp:1042:11
    frame #26: 0x000000010049d08c dyld`start + 520

As you can see at the very bottom, the cause is the `exit()` call here:
```c
if(sdl_quit_qry) {
    monitor_sdl_clean_up();
    exit(0);
}

It looks like a use-after-free somehow (IsRunning(this=0x0000000000000000)). I tried various things, including moving it to the top of the function and calling lv_task_del() for all registered tasks just before exiting, but nothing changes. For now I just added a very dirty system('killall -9 infinisim'); sleep(3); above the exit(0); so that I can at least exit the program without macOS complaining Application quit unexpectedly (it's a popup, so quite annoying). :DDDDD

  1. Rarely, I may get an additional crash immediately at startup:
    2023-10-30 20:02:37.730857+0100 infinisim[55130:3911023] -[AGXG13XFamilyCommandBuffer blitCommandEncoderCommon:], line 258: error 'A command encoder is already encoding to this command buffer'
    -[AGXG13XFamilyCommandBuffer blitCommandEncoderCommon:]:258: failed assertion `A command encoder is already encoding to this command buffer'
    Process 55130 stopped
    * thread #8, name = 'displayapp', stop reason = hit program assert
    frame #4: 0x000000019772add8 Metal`MTLReportFailure.cold.1 + 56
    Metal`bool MTLGetEnvCase<MTLErrorModeType>(char const*, MTLErrorModeType&, std::__1::vector<std::__1::pair<char const*, MTLErrorModeType>, std::__1::allocator<std::__1::pair<char const*, MTLErrorModeType> > > const&) (.cold.1):
    ->  0x19772add8 <+0>:  pacibsp 
    0x19772addc <+4>:  sub    sp, sp, #0x40
    0x19772ade0 <+8>:  stp    x22, x21, [sp, #0x10]
    0x19772ade4 <+12>: stp    x20, x19, [sp, #0x20]
    Target 0: (infinisim) stopped.
    (lldb) bt
    * thread #1, queue = 'com.apple.main-thread', stop reason = hit program assert
    frame #0: 0x000000018ecfed98 libsystem_kernel.dylib`__pthread_kill + 8
    frame #1: 0x000000018ed33ee0 libsystem_pthread.dylib`pthread_kill + 288
    frame #2: 0x000000018ec6e340 libsystem_c.dylib`abort + 168
    frame #3: 0x000000018ec6d754 libsystem_c.dylib`__assert_rtn + 272
    * frame #4: 0x000000019772add8 Metal`MTLReportFailure.cold.1 + 56
    frame #5: 0x0000000197714790 Metal`MTLReportFailure + 480
    frame #6: 0x00000001d5944a34 AGXMetalG13X`___lldb_unnamed_symbol956$$AGXMetalG13X + 620
    frame #7: 0x000000010087e8ac libSDL2-2.0.0.dylib`METAL_UpdateTextureInternal + 460
    frame #8: 0x000000010087c70c libSDL2-2.0.0.dylib`METAL_UpdateTexture + 120
    frame #9: 0x000000010080031c libSDL2-2.0.0.dylib`SDL_UpdateTexture_REAL + 568
    frame #10: 0x0000000100862d4c libSDL2-2.0.0.dylib`SDL_UpdateWindowTexture + 116
    frame #11: 0x0000000100860498 libSDL2-2.0.0.dylib`SDL_UpdateWindowSurface_REAL + 108
    frame #12: 0x00000001008053c0 libSDL2-2.0.0.dylib`SDL_RenderPresent_REAL + 104
    frame #13: 0x00000001000f92ac infinisim`window_update(m=0x0000000100163248) at monitor.c:397:5
    frame #14: 0x00000001000f915c infinisim`sdl_event_handler(t=0x0000000000000000) at monitor.c:262:21
    frame #15: 0x00000001000f90b4 infinisim`sdl_event_handler_mainthread at monitor.c:224:5
    frame #16: 0x000000010006c768 infinisim`main(argc=1, argv=0x000000016fdf4ce8) at main.cpp:1042:11
    frame #17: 0x000000010049d08c dyld`start + 520

My guess is something is (now) causing it to update the display multiple times simultaneously with something else. This may have something to do with restarting the program too fast, or even the fact that I'm running it through lldb. It does seem to be related to Apple's Metal. I'll just ignore this for the time being.

NeroBurner commented 10 months ago

Awesome work! Please open a PR to update the simulator files/submodules as you've mentioned. Then it is easier for me to check on the Linux side if everything still works, and you'll get the attribution for the fix ;)

GottemHams commented 10 months ago

Some changes are in third-party libs tho (like https://github.com/lvgl/lv_drivers), how would we go about that? :> Afaik you can't patch them from the parent project.

Also I'll be going away for a week, leaving very early tomorrow. So whatever needs to be done, will happen after a week. =]