flutter-tizen / engine

The Flutter engine
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
6 stars 19 forks source link

Separate debug info files from unstripped binaries #228

Closed swift-kim closed 2 years ago

swift-kim commented 2 years ago

Currently it's not possible to do source line-level debugging of the engine and embedder binaries (even with so.unstripped binaries) because the compiler strips out all debugging information (-g0) by default:

Extracting debug info files from unstripped binaries (and publishing them along with engine releases) will make it convenient to debug the engine and embedder via gdb and gdbserver.

(before)

(gdb) bt
#0  0xb4d67ea5 in system_info_get_platform_string () from target:/lib/libcapi-system-info.so.0
#1  0xb737e077 in (anonymous namespace)::NativePlugin::HandleMethodCall (this=0x803374a0, method_call=..., result=...) at src/native_plugin_plugin.cc:48
#2  0xb737df1d in (anonymous namespace)::NativePlugin::RegisterWithRegistrar(flutter::PluginRegistrar*)::{lambda(auto:1 const&, auto:2)#1}::operator()<flutter::MethodCall<flutter::EncodableValue>, std::unique_ptr<flutter::MethodResult<flutter::MethodCall>, std::default_delete<flutter::MethodResult> > >(flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::MethodCall>, std::default_delete<flutter::MethodResult> >) const (this=0x8036f450, call=..., result=...) at src/native_plugin_plugin.cc:29
#3  0xb737dce6 in std::_Function_handler<void (flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >), (anonymous namespace)::NativePlugin::RegisterWithRegistrar(flutter::PluginRegistrar*)::{lambda(auto:1 const&, auto:2)#1}>::_M_invoke(std::_Any_data const&, flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >&&) (__functor=..., __args=..., __args=...) at /home/swift/tizen-studio/tools/smart-build-interface/../i586-linux-gnueabi-gcc-9.2/lib/gcc/i586-tizen-linux-gnueabi/9.2.0/../../../../i586-tizen-linux-gnueabi/include/c++/9.2.0/bits/std_function.h:300
#4  0xb7380425 in std::function<void (flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >)>::operator()(flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >) const (this=0x8036f450, __args=..., __args=...) at /home/swift/tizen-studio/tools/smart-build-interface/../i586-linux-gnueabi-gcc-9.2/lib/gcc/i586-tizen-linux-gnueabi/9.2.0/../../../../i586-tizen-linux-gnueabi/include/c++/9.2.0/bits/std_function.h:690
#5  0xb737fffd in flutter::MethodChannel<flutter::EncodableValue>::SetMethodCallHandler(std::function<void (flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >)>) const::{lambda(unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>)#1}::operator()(unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>) const (this=0x8036f450, message=0xa0b65d30 "\a\022getPlatformVersion", message_size=21, reply=...) at /home/swift/Git/flutter-tizen/flutter/bin/cache/artifacts/engine/tizen-common/cpp_client_wrapper/include/flutter/method_channel.h:119
#6  0xb737fa49 in std::_Function_handler<void (unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>), flutter::MethodChannel<flutter::EncodableValue>::SetMethodCallHandler(std::function<void (flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >)>) const::{lambda(unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>)#1}>::_M_invoke(std::_Any_data const&, unsigned char const*&&, unsigned int&&, std::function<void (unsigned char const*, unsigned int)>&&) (__functor=..., __args=..., __args=..., __args=...) at /home/swift/tizen-studio/tools/smart-build-interface/../i586-linux-gnueabi-gcc-9.2/lib/gcc/i586-tizen-linux-gnueabi/9.2.0/../../../../i586-tizen-linux-gnueabi/include/c++/9.2.0/bits/std_function.h:300
#7  0xb733d109 in std::function<void (unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>)>::operator()(unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>) const (this=0x803398c8, __args=..., __args=..., __args=...) at /home/swift/tizen-studio/tools/smart-build-interface/../i586-linux-gnueabi-gcc-9.2/lib/gcc/i586-tizen-linux-gnueabi/9.2.0/../../../../i586-tizen-linux-gnueabi/include/c++/9.2.0/bits/std_function.h:690
#8  0xb733b107 in flutter::(anonymous namespace)::ForwardToHandler (messenger=0x8032cec0, message=0xbf8a6b40, user_data=0x803398c8) at cpp_client_wrapper/core_implementations.cc:58
#9  0xb74f0c6a in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_tizen_mobile.so
#10 0xb74d73c8 in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_tizen_mobile.so
#11 0xb53f800b in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_engine.so
#12 0xb5406300 in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_engine.so
#13 0xb5a3b502 in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_engine.so
#14 0xb5403f7c in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_engine.so
#15 0xb54055ff in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_engine.so
#16 0xb53faf64 in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_engine.so
#17 0xb53ed952 in FlutterEngineRunTask () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_engine.so
#18 0xb74d7b0e in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_tizen_mobile.so
#19 0xb74db989 in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_tizen_mobile.so
#20 0xb74db15c in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_tizen_mobile.so
#21 0xb74db9d1 in ?? () from target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_tizen_mobile.so
#22 0xb53123e8 in ?? () from target:/lib/libecore.so.1
#23 0xb531308b in ?? () from target:/lib/libecore.so.1
#24 0xb52d790b in ?? () from target:/lib/libecore.so.1
#25 0xb52d7ffb in ?? () from target:/lib/libecore.so.1
#26 0xb52dd3d6 in ?? () from target:/lib/libecore.so.1
#27 0xb52dc2d4 in efl_loop_begin () from target:/lib/libecore.so.1
#28 0xb52d6388 in ecore_main_loop_begin () from target:/lib/libecore.so.1
#29 0xb3a33d9a in elm_run () from target:/lib/libelementary.so.1
#30 0xb4d620f7 in ?? () from target:/lib/libappcore-efl.so.1
#31 0xb4da33b2 in appcore_base_init () from target:/lib/libappcore-common.so.1
#32 0xb37c37d6 in appcore_ui_base_init () from target:/lib/libappcore-ui.so.1
#33 0xb4d62724 in appcore_efl_base_init () from target:/lib/libappcore-efl.so.1
#34 0xb74ab59d in ?? () from target:/lib/libcapi-appfw-application.so.0
#35 0xb74ab8a1 in ui_app_main () from target:/lib/libcapi-appfw-application.so.0
#36 0x8001fd2c in FlutterApp::Run (this=0xbf8a8728, argc=29, argv=0xbf8a8824) at flutter_app.cc:162
#37 0x8001dec4 in main (argc=29, argv=0xbf8a8824) at src/runner.cc:17

(after)

(gdb) bt
#0  0xb4da6ea5 in system_info_get_platform_string () from target:/lib/libcapi-system-info.so.0
#1  0xb73bd077 in (anonymous namespace)::NativePlugin::HandleMethodCall (this=0x80277380, method_call=..., result=...) at src/native_plugin_plugin.cc:48
#2  0xb73bcf1d in (anonymous namespace)::NativePlugin::RegisterWithRegistrar(flutter::PluginRegistrar*)::{lambda(auto:1 const&, auto:2)#1}::operator()<flutter::MethodCall<flutter::EncodableValue>, std::unique_ptr<flutter::MethodResult<flutter::MethodCall>, std::default_delete<flutter::MethodResult> > >(flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::MethodCall>, std::default_delete<flutter::MethodResult> >) const (this=0x802b0440, call=..., result=...) at src/native_plugin_plugin.cc:29
#3  0xb73bcce6 in std::_Function_handler<void (flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >), (anonymous namespace)::NativePlugin::RegisterWithRegistrar(flutter::PluginRegistrar*)::{lambda(auto:1 const&, auto:2)#1}>::_M_invoke(std::_Any_data const&, flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >&&) (__functor=..., __args=..., __args=...) at /home/swift/tizen-studio/tools/smart-build-interface/../i586-linux-gnueabi-gcc-9.2/lib/gcc/i586-tizen-linux-gnueabi/9.2.0/../../../../i586-tizen-linux-gnueabi/include/c++/9.2.0/bits/std_function.h:300
#4  0xb73bf425 in std::function<void (flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >)>::operator()(flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >) const (this=0x802b0440, __args=..., __args=...) at /home/swift/tizen-studio/tools/smart-build-interface/../i586-linux-gnueabi-gcc-9.2/lib/gcc/i586-tizen-linux-gnueabi/9.2.0/../../../../i586-tizen-linux-gnueabi/include/c++/9.2.0/bits/std_function.h:690
#5  0xb73beffd in flutter::MethodChannel<flutter::EncodableValue>::SetMethodCallHandler(std::function<void (flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >)>) const::{lambda(unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>)#1}::operator()(unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>) const (this=0x802b0440, message=0xabeaebc0 "\a\022getPlatformVersion", message_size=21, reply=...) at /home/swift/Git/flutter-tizen/flutter/bin/cache/artifacts/engine/tizen-common/cpp_client_wrapper/include/flutter/method_channel.h:119
#6  0xb73bea49 in std::_Function_handler<void (unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>), flutter::MethodChannel<flutter::EncodableValue>::SetMethodCallHandler(std::function<void (flutter::MethodCall<flutter::EncodableValue> const&, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>, std::default_delete<flutter::MethodResult<flutter::EncodableValue> > >)>) const::{lambda(unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>)#1}>::_M_invoke(std::_Any_data const&, unsigned char const*&&, unsigned int&&, std::function<void (unsigned char const*, unsigned int)>&&) (__functor=..., __args=..., __args=..., __args=...) at /home/swift/tizen-studio/tools/smart-build-interface/../i586-linux-gnueabi-gcc-9.2/lib/gcc/i586-tizen-linux-gnueabi/9.2.0/../../../../i586-tizen-linux-gnueabi/include/c++/9.2.0/bits/std_function.h:300
#7  0xb737c109 in std::function<void (unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>)>::operator()(unsigned char const*, unsigned int, std::function<void (unsigned char const*, unsigned int)>) const (this=0x8027a8b8, __args=..., __args=..., __args=...) at /home/swift/tizen-studio/tools/smart-build-interface/../i586-linux-gnueabi-gcc-9.2/lib/gcc/i586-tizen-linux-gnueabi/9.2.0/../../../../i586-tizen-linux-gnueabi/include/c++/9.2.0/bits/std_function.h:690
#8  0xb737a107 in flutter::(anonymous namespace)::ForwardToHandler (messenger=0x8026deb0, message=0xbfadad50, user_data=0x8027a8b8) at cpp_client_wrapper/core_implementations.cc:58
#9  0xb752fc6a in HandleMessage () at ../../flutter/shell/platform/common/incoming_message_dispatcher.cc:36
#10 0xb75163c8 in operator() () at ../../flutter/shell/platform/tizen/flutter_tizen_engine.cc:214
#11 __invoke () at ../../flutter/shell/platform/tizen/flutter_tizen_engine.cc:205
#12 0xb543700b in operator() () at ../../flutter/shell/platform/embedder/embedder.cc:1112
#13 __invoke<(lambda at ../../flutter/shell/platform/embedder/embedder.cc:1101:9) &, std::__1::unique_ptr<flutter::PlatformMessage, std::__1::default_delete<flutter::PlatformMessage> > > () at ../../third_party/libcxx/include/type_traits:3530
#14 __call<(lambda at ../../flutter/shell/platform/embedder/embedder.cc:1101:9) &, std::__1::unique_ptr<flutter::PlatformMessage, std::__1::default_delete<flutter::PlatformMessage> > > () at ../../third_party/libcxx/include/__functional_base:348
#15 operator() () at ../../third_party/libcxx/include/functional:1533
#16 operator() () at ../../third_party/libcxx/include/functional:1707
#17 0xb5445300 in operator() () at ../../third_party/libcxx/include/functional:1860
#18 operator() () at ../../third_party/libcxx/include/functional:2419
#19 HandlePlatformMessage () at ../../flutter/shell/platform/embedder/platform_view_embedder.cc:80
#20 0xb5a7a502 in operator() () at ../../flutter/shell/common/shell.cc:1203
#21 operator()<> () at ../../flutter/fml/make_copyable.h:24
#22 __invoke<fml::internal::CopyableLambda<(lambda at ../../flutter/shell/common/shell.cc:1200:27)> &> () at ../../third_party/libcxx/include/type_traits:3530
#23 __call<fml::internal::CopyableLambda<(lambda at ../../flutter/shell/common/shell.cc:1200:27)> &> () at ../../third_party/libcxx/include/__functional_base:348
#24 operator() () at ../../third_party/libcxx/include/functional:1533
#25 operator() () at ../../third_party/libcxx/include/functional:1707
#26 0xb5442f7c in operator() () at ../../third_party/libcxx/include/functional:1860
#27 operator() () at ../../third_party/libcxx/include/functional:2419
#28 PostTask () at ../../flutter/shell/platform/embedder/embedder_task_runner.cc:77
#29 0xb54445ff in PostTask () at ../../flutter/shell/platform/embedder/embedder_thread_host.cc:270
#30 0xb5439f64 in flutter::EmbedderEngine::RunTask(FlutterTask const*) () at ../../flutter/shell/platform/embedder/embedder_engine.cc:260
#31 0xb542c952 in FlutterEngineRunTask () at ../../flutter/shell/platform/embedder/embedder.cc:1963
#32 0xb7516b0e in operator()<FlutterTask> () at ../../flutter/shell/platform/tizen/flutter_tizen_engine.cc:68
#33 __invoke<(lambda at ../../flutter/shell/platform/tizen/flutter_tizen_engine.cc:67:37) &, const FlutterTask *> () at ../../third_party/libcxx/include/type_traits:3530
#34 __call<(lambda at ../../flutter/shell/platform/tizen/flutter_tizen_engine.cc:67:37) &, const FlutterTask *> () at ../../third_party/libcxx/include/__functional_base:348
#35 operator() () at ../../third_party/libcxx/include/functional:1533
#36 operator() () at ../../third_party/libcxx/include/functional:1707
#37 0xb751a989 in operator() () at ../../third_party/libcxx/include/functional:1860
#38 operator() () at ../../third_party/libcxx/include/functional:2419
#39 OnTaskExpired () at ../../flutter/shell/platform/tizen/tizen_event_loop.cc:107
#40 0xb751a15c in ExecuteTaskEvents () at ../../flutter/shell/platform/tizen/tizen_event_loop.cc:56
#41 0xb751a9d1 in operator() () at ../../flutter/shell/platform/tizen/tizen_event_loop.cc:25
#42 __invoke () at ../../flutter/shell/platform/tizen/tizen_event_loop.cc:23
#43 0xb53513e8 in ?? () from target:/lib/libecore.so.1
#44 0xb535208b in ?? () from target:/lib/libecore.so.1
#45 0xb531690b in ?? () from target:/lib/libecore.so.1
#46 0xb5316ffb in ?? () from target:/lib/libecore.so.1
#47 0xb531c3d6 in ?? () from target:/lib/libecore.so.1
#48 0xb531b2d4 in efl_loop_begin () from target:/lib/libecore.so.1
#49 0xb5315388 in ecore_main_loop_begin () from target:/lib/libecore.so.1
#50 0xb3a72d9a in elm_run () from target:/lib/libelementary.so.1
#51 0xb4da10f7 in ?? () from target:/lib/libappcore-efl.so.1
#52 0xb4de23b2 in appcore_base_init () from target:/lib/libappcore-common.so.1
#53 0xb38027d6 in appcore_ui_base_init () from target:/lib/libappcore-ui.so.1
#54 0xb4da1724 in appcore_efl_base_init () from target:/lib/libappcore-efl.so.1
#55 0xb74ea59d in ?? () from target:/lib/libcapi-appfw-application.so.0
#56 0xb74ea8a1 in ui_app_main () from target:/lib/libcapi-appfw-application.so.0
#57 0x80012d2c in FlutterApp::Run (this=0xbfadc938, argc=29, argv=0xbfadca34) at flutter_app.cc:162
#58 0x80010ec4 in main (argc=29, argv=0xbfadca34) at src/runner.cc:17
swift-kim commented 2 years ago

Level 1 (g1) provides no local variable information:

image

Level 2 (g2) should be the best fit for general purpose debugging, although the file size is quite large (156 MB → 331 MB).

swift-kim commented 2 years ago

Instructions (CLI)

  1. Modify build/config/compiler/BUILD.gn as follows.

    @@ -907,6 +903,6 @@ config("minimal_symbols") {
    
    config("no_symbols") {
      if (!is_win) {
    -    cflags = [ "-g0" ]
    +    cflags = [ "-g2" ]
      }
    }

    Note: Alternatively you can give the --unoptimized option to gn, but it will result in additional libdart dependency of the embedder:

    --- a/shell/platform/tizen/BUILD.gn
    +++ b/shell/platform/tizen/BUILD.gn
    @@ -215,6 +215,7 @@ template("embedder") {
        public_deps = [ ":flutter_engine" ]
    
        deps = [
    +      "//flutter/runtime:libdart",
          "//flutter/shell/platform/common:common_cpp",
          "//flutter/shell/platform/common:common_cpp_input",
          "//flutter/shell/platform/common:common_cpp_library_headers",
  2. Build the engine and embedder.

  3. Build your app with stripped versions of the engine and embedder and install to your device.

  4. Launch the app under gdbserver. (How: https://github.com/flutter-tizen/plugins/issues/295 - will be detailed later)

  5. Connect to the gdbserver and find the base addresses of the engine and embedder objects using info share.

    (gdb) info share
    0xb53ee540  0xb5fe6719  Yes (*)     target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_engine.so
    0xb74d7030  0xb7537b79  Yes (*)     target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_tizen_mobile.so
  6. Register symbol files (.debug) using add-symbol-file.

    (gdb) add-symbol-file ~/Git/engine/src/out/linux_debug_x86/so.unstripped/libflutter_engine.so 0xb53ee540
    (gdb) add-symbol-file ~/Git/engine/src/out/linux_debug_x86/so.unstripped/libflutter_tizen_mobile.so 0xb74d7030
swift-kim commented 2 years ago

Instructions (VS Code)

  1. Follow steps 1-5 in the above comment.

  2. Run info share through the VS Code debug console.

    -exec info share
    0xb7548030  0xb75a8b79  Yes         target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_tizen_mobile.so
    0xb545f540  0xb6057719  Yes         target:/opt/usr/globalapps/com.example.native_plugin_example/bin/../lib/libflutter_engine.so
  3. Run add-symbol-file through the debug console.

    -exec add-symbol-file ~/Git/engine/src/out/linux_debug_x86/so.unstripped/libflutter_engine.so 0xb545f540
    -exec add-symbol-file ~/Git/engine/src/out/linux_debug_x86/so.unstripped/libflutter_tizen_mobile.so 0xb7548030
swift-kim commented 2 years ago

There's no need to extract debug files from artifacts. See https://github.com/flutter-tizen/flutter-tizen/wiki/Debugging-the-engine-and-embedder for how to load symbol info in GDB.