Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Address Sanitizer Does not work with Physical Device #2844

Open
jeffersonsetiawan opened this issue Jan 3, 2024 · 3 comments
Open

Bug: Address Sanitizer Does not work with Physical Device #2844

jeffersonsetiawan opened this issue Jan 3, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@jeffersonsetiawan
Copy link

Description

Using Address Sanitizer in physical device cause error

dyld[17268]: Library not loaded: @rpath/libclang_rt.asan_ios_dynamic.dylib
  Referenced from: <C7946C17-CFDB-39C7-8EDC-C760B1E67372> /private/var/containers/Bundle/Application/A614A60F-3AC2-4585-9E18-F89AC83FF032/AddressSanitizerApp.app/AddressSanitizerApp
  Reason: tried: '/usr/lib/system/introspection/libclang_rt.asan_ios_dynamic.dylib' (no such file, not in dyld cache), '/usr/lib/swift/libclang_rt.asan_ios_dynamic.dylib' (no such file, not in dyld cache),
Screenshot 2024-01-03 at 18 30 18

Extra info:

flutter/flutter#108469

It looks like the ios asan dylib is no longer vended with the clang toolchain that the engine consumes, but Xcode has the dylib, so we could try to use that one.

Reproduction steps

  1. Add target_environments device in example/sanitizers/xcodeproj_targets.bzl
load("@rules_xcodeproj//xcodeproj:defs.bzl", "xcode_schemes", "top_level_target")

SCHEME_AUTOGENERATION_MODE = "none"

_ADDRESS_SANITIZER_TARGET = "//AddressSanitizerApp"
_THREAD_SANITIZER_TARGET = "//ThreadSanitizerApp"
_UNDEFINED_BEHAVIOR_SANITIZER_TARGET = "//UndefinedBehaviorSanitizerApp"

XCODEPROJ_TARGETS = [
    top_level_target(_ADDRESS_SANITIZER_TARGET, target_environments = ["simulator", "device"]),
    _THREAD_SANITIZER_TARGET,
    _UNDEFINED_BEHAVIOR_SANITIZER_TARGET,
]
  1. Setup Provisioning profile in the example/sanitizers/AddressSanitizerApp/
load("@build_bazel_rules_apple//apple:apple.bzl", "local_provisioning_profile")

local_provisioning_profile(
    name = "app_debug_profile",
    profile_name = "iOS Team Provisioning Profile: xyz",
    team_id = "XYZ",
)

ios_application(
    provisioning_profile = ":app_debug_profile",
)
  1. Generate the project bazel run //:xcodeproj
  2. Run the AddressSanitizer in the real device.

Expected behavior

Work the same as the simulator.

rules_xcodeproj version

1.14.2

Xcode version

15.1

Bazel version

7.0.0

rules_apple version

3.1.1

rules_swift version

1.13.0

Additional information

I check the rules_apple and rules_swift version from the examples/rules_ios/MODULE.bazel

@jeffersonsetiawan jeffersonsetiawan added the bug Something isn't working label Jan 3, 2024
@chiragramani
Copy link
Contributor

Thanks for reporting. I can repro this issue. I think codesigning these dylibs will fix this issue. (Vanilla Xcode projects do codesign these dylibs when building for device)

'/private/var/containers/****/AddressSanitizerApp.app/Frameworks/libclang_rt.asan_ios_dynamic.dylib' 
(code signature invalid in <**-**-**-**> 
'/private/var/containers/Bundle/Application/****/AddressSanitizerApp.app/Frameworks/libclang_rt.asan_ios_dynamic.dylib' (errno=1)

@jeffersonsetiawan
Copy link
Author

Thanks for the investigation @chiragramani, have you found a way to sign it and attach it to the device?

@amorde
Copy link

amorde commented Dec 17, 2024

Hitting the same issue was able to hack together a manual codesigning workaround.

  1. First find the bazel execution root by expanding the Generate Bazel Dependencies build step and grabbing the path after cd in the top-level PhaseScriptExecution section (there's probably some other way to do this but this was the way I found)
  2. Find the entitlements file used during the build. It will be in a subdirectory of the execroot found above
  3. Find the built product in Xcode's DerivedData (not the one in the bazel output base, more on this later). You can go to the Products file group, click on the app target and the file inspector on the right pane will have the path.
  4. Get the SHA-1 of the codesign certificate used. You can find this in Keychain Access by right clicking the signing cert under the login section (or where ever yours is stored), click Get Info, and in the Finderprints section at the very bottom will be a SHA-1 value.
  5. Run codesign -v --sign 'SHA_FROM_STEP_4' --force '/path/to/app.app/Frameworks/libclang_rt.asan_ios_dynamic.dylib' using the app path from step 3
  6. Run codesign -v --sign 'SHA_FROM_STEP_4' --force --generate-entitlement-der --entitlements '/path/to/entitlements' '/path/to/app.app' using the entitlements path from step 2
  7. In Xcode perform 'Run without building' via Product > Perform Action > Run Without Building or CMD-CTRL-R

The underlying issue seems to be that the bazel build does the codesigning but a future step inserts the clang dylib afterwards. If you look at the produced .app in the bazel outputs the dylib is not there but it is there in version in Xcode's DerivedData.

Within the Build target XYZApp.app step of the build which comes after Build target BazelDependencies there's a substep Copy Address Sanitizer which appears to be performed by Xcode's build system, followed by a `Run custom shell script 'Copy Bazel Outputs / Generate Bazel Dependencies' which brings the rest of the .app contents over.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants