Skip to content

macos: unable to get debug information from dylib dependencies #83730

Closed
@ehuss

Description

@ehuss

On macOS, the debug information for the dependencies of a dylib do not seem to be working with split-debuginfo=unpacked.

One way to demonstrate this is building rustc itself with debug enabled, and split-debuginfo as unpacked (the default). Backtraces are unable to find the source file information for anything past rustc_query_system. lldb is also unable to find any debug information (it can't even find the symbols).

Example of what the backtrace looks like:

Backtrace

   0: std::panicking::begin_panic
   1: rustc_errors::HandlerInner::emit_diagnostic
   2: rustc_errors::Handler::emit_diagnostic
   3: rustc_errors::diagnostic_builder::DiagnosticBuilder::emit
   4: rustc_resolve::late::lifetimes::LifetimeContext::resolve_lifetime_ref
   5: <rustc_resolve::late::lifetimes::LifetimeContext as rustc_hir::intravisit::Visitor>::visit_lifetime
   6: <rustc_resolve::late::lifetimes::LifetimeContext as rustc_hir::intravisit::Visitor>::visit_path
   7: rustc_hir::intravisit::walk_expr
   8: rustc_resolve::late::lifetimes::LifetimeContext::with
   9: <rustc_resolve::late::lifetimes::LifetimeContext as rustc_hir::intravisit::Visitor>::visit_nested_body
  10: rustc_resolve::late::lifetimes::LifetimeContext::visit_early_late
  11: <rustc_resolve::late::lifetimes::LifetimeContext as rustc_hir::intravisit::Visitor>::visit_item
  12: rustc_resolve::late::lifetimes::do_resolve
  13: rustc_resolve::late::lifetimes::resolve_lifetimes
  14: rustc_query_impl::<impl rustc_query_system::query::config::QueryAccessors<rustc_query_impl::plumbing::QueryCtxt> for rustc_query_impl::queries::resolve_lifetimes>::compute
  15: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  16: rustc_data_structures::stack::ensure_sufficient_stack
  17: rustc_query_system::query::plumbing::force_query_with_job
  18: rustc_query_system::query::plumbing::get_query_impl
  19: rustc_query_system::query::plumbing::get_query
  20: rustc_resolve::late::lifetimes::resolve_lifetimes_for
  21: core::ops::function::FnOnce::call_once
  22: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  23: rustc_data_structures::stack::ensure_sufficient_stack
  24: rustc_query_system::query::plumbing::force_query_with_job
  25: rustc_query_system::query::plumbing::get_query_impl
  26: rustc_query_system::query::plumbing::get_query
  27: rustc_middle::ty::context::TyCtxt::named_region
  28: <dyn rustc_typeck::astconv::AstConv>::ast_region_to_region
  29: <<dyn rustc_typeck::astconv::AstConv>::create_substs_for_ast_path::SubstsForAstPathCtxt as rustc_typeck::astconv::CreateSubstsForGenericArgsCtxt>::provided_kind
  30: rustc_typeck::astconv::generics::<impl dyn rustc_typeck::astconv::AstConv>::create_substs_for_generic_args
  31: <dyn rustc_typeck::astconv::AstConv>::create_substs_for_ast_path
  32: <dyn rustc_typeck::astconv::AstConv>::ast_path_substs_for_ty
  33: <dyn rustc_typeck::astconv::AstConv>::ast_path_to_ty
  34: <dyn rustc_typeck::astconv::AstConv>::res_to_ty
  35: rustc_typeck::check::fn_ctxt::checks::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_struct_path
  36: rustc_typeck::check::expr::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_kind
  37: rustc_typeck::check::expr::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation
  38: rustc_typeck::check::fn_ctxt::_impl::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::with_breakable_ctxt
  39: rustc_typeck::check::fn_ctxt::checks::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_block_with_expected
  40: rustc_typeck::check::expr::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_kind
  41: rustc_typeck::check::expr::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation
  42: rustc_typeck::check::expr::<impl rustc_typeck::check::fn_ctxt::FnCtxt>::check_return_expr
  43: rustc_typeck::check::check::check_fn
  44: rustc_infer::infer::InferCtxtBuilder::enter
  45: rustc_typeck::check::inherited::InheritedBuilder::enter
  46: rustc_typeck::check::typeck_with_fallback
  47: rustc_typeck::check::typeck
  48: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  49: rustc_data_structures::stack::ensure_sufficient_stack
  50: rustc_query_system::query::plumbing::force_query_with_job
  51: rustc_query_system::query::plumbing::get_query_impl
  52: rustc_query_system::query::plumbing::get_query
  53: rustc_middle::ty::<impl rustc_middle::ty::context::TyCtxt>::par_body_owners
  54: rustc_typeck::check::typeck_item_bodies
  55: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  56: rustc_data_structures::stack::ensure_sufficient_stack
  57: rustc_query_system::query::plumbing::force_query_with_job
  58: rustc_query_system::query::plumbing::get_query_impl
  59: rustc_query_system::query::plumbing::get_query
  60: rustc_session::utils::<impl rustc_session::session::Session>::time
  61: rustc_typeck::check_crate
  62: rustc_interface::passes::analysis
  63: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  64: rustc_query_system::dep_graph::graph::DepGraph<K>::with_eval_always_task
  65: rustc_data_structures::stack::ensure_sufficient_stack
  66: rustc_query_system::query::plumbing::force_query_with_job
  67: rustc_query_system::query::plumbing::get_query_impl
  68: rustc_query_system::query::plumbing::get_query
  69: rustc_middle::ty::query::TyCtxtAt::analysis
             at /Users/eric/Proj/rust/rust2/compiler/rustc_middle/src/ty/query/mod.rs:205:17
  70: rustc_middle::ty::query::<impl rustc_middle::ty::context::TyCtxt>::analysis
             at /Users/eric/Proj/rust/rust2/compiler/rustc_middle/src/ty/query/mod.rs:186:17
  71: rustc_driver::run_compiler::{{closure}}::{{closure}}::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_driver/src/lib.rs:436:59
  72: rustc_interface::passes::QueryContext::enter::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_interface/src/passes.rs:754:42
  73: rustc_middle::ty::context::tls::enter_context::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_middle/src/ty/context.rs:1726:50
  74: rustc_middle::ty::context::tls::set_tlv
             at /Users/eric/Proj/rust/rust2/compiler/rustc_middle/src/ty/context.rs:1710:9
  75: rustc_middle::ty::context::tls::enter_context
             at /Users/eric/Proj/rust/rust2/compiler/rustc_middle/src/ty/context.rs:1726:9
  76: rustc_interface::passes::QueryContext::enter
             at /Users/eric/Proj/rust/rust2/compiler/rustc_interface/src/passes.rs:754:9
  77: rustc_driver::run_compiler::{{closure}}::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_driver/src/lib.rs:436:13
  78: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
             at /Users/eric/Proj/rust/rust2/compiler/rustc_interface/src/queries.rs:422:19
  79: rustc_driver::run_compiler::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_driver/src/lib.rs:337:22
  80: rustc_interface::interface::create_compiler_and_run::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_interface/src/interface.rs:208:13
  81: rustc_span::with_source_map
             at /Users/eric/Proj/rust/rust2/compiler/rustc_span/src/lib.rs:788:5
  82: rustc_interface::interface::create_compiler_and_run
             at /Users/eric/Proj/rust/rust2/compiler/rustc_interface/src/interface.rs:202:5
  83: rustc_interface::interface::run_compiler::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_interface/src/interface.rs:224:12
  84: rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals::{{closure}}::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_interface/src/util.rs:155:13
  85: scoped_tls::ScopedKey<T>::set
             at /Users/eric/.cargo/registry/src/github.com-1ecc6299db9ec823/scoped-tls-1.0.0/src/lib.rs:137:9
  86: rustc_span::with_session_globals
             at /Users/eric/Proj/rust/rust2/compiler/rustc_span/src/lib.rs:105:5
  87: rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_interface/src/util.rs:153:9
  88: rustc_interface::util::scoped_thread::{{closure}}
             at /Users/eric/Proj/rust/rust2/compiler/rustc_interface/src/util.rs:128:24

From what I can tell, the debug information for everything directly in rustc_driver can be found, but anything from a dependency cannot. Note that generic functions are part of rustc_driver, so that is why things like rustc_middle functions appear in the backtrace above.

Minimal example

I created a simple demo project at https://github.com/ehuss/macos-dylib-debug.

This has an executable foo depends on dylib driver which depends on somedep.

If you build on macOS with the latest nightly (2021-03-31) which has split-debuginfo enabled by default, and run with RUST_BACKTRACE=1, you can see that the information is missing from the dependency:

   0: std::panicking::begin_panic
   1: somedep::do_something
   2: driver::run_driver
             at ./driver/src/lib.rs:2:5
   3: foo::main
             at ./src/main.rs:2:5
   4: core::ops::function::FnOnce::call_once
             at /rustc/74874a690bc95443292496ff5df5cc5c8cb56e0b/library/core/src/ops/function.rs:227:5

If you disable split-debuginfo (CARGO_PROFILE_DEV_SPLIT_DEBUGINFO=packed), then it gets the full information:

   0: std::panicking::begin_panic
             at /rustc/74874a690bc95443292496ff5df5cc5c8cb56e0b/library/std/src/panicking.rs:519:12
   1: somedep::do_something
             at ./somedep/src/lib.rs:3:5
   2: driver::run_driver
             at ./driver/src/lib.rs:2:5
   3: foo::main
             at ./src/main.rs:2:5
   4: core::ops::function::FnOnce::call_once
             at /rustc/74874a690bc95443292496ff5df5cc5c8cb56e0b/library/core/src/ops/function.rs:227:5

Similarly, trying to debug with lldb is unable to see anything in somedep. Running lldb with a dylib is a little tricky due to system integrity protection, it is something like this:

DYLD_FALLBACK_LIBRARY_PATH=$(rustc --print=sysroot)/lib/rustlib/x86_64-apple-darwin/lib \
    /Applications/Xcode.app/Contents/Developer/usr/bin/lldb ./target/debug/foo

b do_something fails to find the symbol. Setting a breakpoint on run_driver and running and then trying to step into do_something is unable to work. Doing all of the above with packed split-debuginfo works as expected.

Meta

rustc 1.53.0-nightly (74874a690 2021-03-30)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-debuginfoArea: Debugging information in compiled programs (DWARF, PDB, etc.)C-bugCategory: This is a bug.O-macosOperating system: macOS

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions