Post

Replies

Boosts

Views

Activity

Reply to Dynamic Library cannot call exposed C function
@DTS Engineer no matter what I tried I could not get this to work. I tried a .tbd file, using the -export-symbols-list flag, passing individual functions, etc. They get stripped every time. I ended up injecting the functions into the library at runtime. Functions are declared normally: void ios_prepare_request(const char *url) { ... } Then in my library I created a function that takes the function pointers, which I call when I load it: NSBundle *frameworkBundle = [NSBundle bundleWithIdentifier:@"com.opacitylabs.sdk"]; [frameworkBundle load]; opacity_core::register_ios_callbacks(ios_prepare_request); It's more verbose on my side but there is no runtime crash anymore. Thanks for the help anyways!
Topic: Code Signing SubTopic: General Tags:
3w
Reply to Dynamic Library cannot call exposed C function
@DTS Engineer after much tweaking I've managed to reduce the working configuration to: s.user_target_xcconfig = { 'STRIP_STYLE' => 'non-global' } This works but sets the stripping style of the whole user project. I took a look at the output of Xcode build phases for the pod target and -exported_symbols_list doesn't work with cocoapods (out of the box) because cocoapods generates static lib by default. However setting s.static_framework = false did produce a dynamic framework but the symbols still are stripped. I'm not sure what other consequences STRIP_STYLE would have... sounds like a setting this only for my library is a bad idea, but I'm out of ideas on how to keep the symbols. I also tried passing each symbol directly to the linker and that also did not work s.user_target_xcconfig = { 'OTHER_LDFLAGS' => '$(inherited) -Wl,-u,_ios_prepare_request -Wl,-u,_ios_set_request_header -Wl,-u,_ios_present_webview -W...' }
Topic: Code Signing SubTopic: General Tags:
3w
Reply to Dynamic Library cannot call exposed C function
@DTS Engineer I just went a bit through the docs trying to understand really what do the linker flags do and I completely misunderstood what -undefined dynamic_lookup and export_symbols_list do. They are meant for the pod/library to expose it's interface to the outside world. This is not the issue I'm having. I tried completely removing the linker flags and the app is still working when ran directly from Xcode, with only this function that forces the compiler not to strip the dead code: #define EXPORT __attribute__((visibility("default"), used, retain)) extern "C" EXPORT void ios_prepare_request(const char *url) { ... } void force_symbol_registration() { // Force these symbols to be included in the binary by referencing them volatile void *ptrs[] = {(void *)ios_prepare_request,}; // Actually use the pointers to prevent optimization for (int i = 0; i < sizeof(ptrs); i++) { if (ptrs[i] == NULL) { printf("Symbol %d is NULL\n", i); } } } The linking issue I'm having is internal to the library and the dylib it contains.
Topic: Code Signing SubTopic: General Tags:
3w
Reply to Dynamic Library cannot call exposed C function
Good news first. With the following config in my podspec the functions are not stripped and it works (🎉) both with debugging archive/TestFlight: s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-undefined dynamic_lookup -Wl,-keep_private_externs -Wl,-no_deduplicate -all_load -rdynamic', 'STRIP_INSTALLED_PRODUCT' => 'NO', 'DEPLOYMENT_POSTPROCESSING' => 'NO', 'DEAD_CODE_STRIPPING' => 'NO', 'GCC_SYMBOLS_PRIVATE_EXTERN' => 'NO', 'STRIP_STYLE' => 'non-global', 'COPY_PHASE_STRIP' => 'NO' } # Force these settings for all configurations s.user_target_xcconfig = { 'STRIP_INSTALLED_PRODUCT' => 'NO', 'DEPLOYMENT_POSTPROCESSING' => 'NO', 'DEAD_CODE_STRIPPING' => 'NO' } However, zero dead code stripping is not ideal ofc. I tried the .exp approach and it doesn't work. Maybe I'm misunderstanding something. I tried the .exp approach but it still gets stripped. Just to be clear, it's not the symbols from the dylib that fail to be executed. It's when the dylib tries to call to the functions in my library code that it fails. I've added the following to my podspec s.resource_bundles = { 'OpacityCore' => ['exports.exp'] } s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-undefined dynamic_lookup -exported_symbols_list "${PODS_TARGET_SRCROOT}/exports.exp"', } The exports.exp file: _ios_prepare_request All of this symbols come from src/Helper.mm which is part of my ios library code: #define EXPORT __attribute__((visibility("default"), used, retain)) extern "C" EXPORT void ios_prepare_request(const char *url) { ... } It's the dylib that once loaded tries to reach in and call those functions. In any case, the code above does not work.
Topic: Code Signing SubTopic: General Tags:
3w
Reply to Dynamic Library cannot call exposed C function
@DTS Engineer you are right, the KERN_PROTECTION_ERROR really through me off. I updated today to Xcode 26 beta 5 and with my dylib compiled with debug symbols all of the sudden I can see where the null invocation is happening However, I don't have any idea why the compiler is stripping this symbols when packaging for TestFlight/Debugging. I've already added a lot of preprocessor directives to try to keep the symbols intact. Any idea what could I try? #define EXPORT __attribute__((visibility("default"), used, retain)) extern "C" { EXPORT void ios_prepare_request(const char *url) { NSString *urlString = [NSString stringWithUTF8String:url]; request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]]; } void force_symbol_registration() { // Force these symbols to be included in the binary by referencing them volatile void *ptrs[] = {(void *)ios_prepare_request, (void *)ios_set_request_header, (void *)ios_present_webview, (void *)ios_close_webview, (void *)ios_get_browser_cookies_for_current_url, (void *)ios_get_browser_cookies_for_domain, (void *)get_ip_address, (void *)is_rooted, (void *)is_wifi_connected, (void *)is_location_services_enabled, (void *)get_os_name, (void *)get_os_version, (void *)is_emulator, (void *)get_battery_level, (void *)get_battery_status }; // Prevent compiler from optimizing away the array // (void)ptrs; // Actually use the pointers to prevent optimization for (int i = 0; i < 6; i++) { if (ptrs[i] == NULL) { printf("Symbol %d is NULL\n", i); } } } // Add this to ensure symbols are not stripped __attribute__((constructor)) static void ensure_symbols_retained() { force_symbol_registration(); } static void *__attribute__((used)) symbol_references[] = { (void *)ios_prepare_request, (void *)ios_set_request_header, (void *)ios_present_webview, (void *)ios_close_webview, (void *)ios_get_browser_cookies_for_current_url, (void *)ios_get_browser_cookies_for_domain, (void *)get_ip_address, nullptr}; EXPORT void ensure_symbols_loaded() { volatile void **ptr = (volatile void **)symbol_references; while (*ptr) { // Just touch the memory to ensure it's loaded ptr++; } } When my library is loaded I do: opacity::force_symbol_registration(); opacity::ensure_symbols_loaded(); // Make sure the main executable's symbols are available dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); NSBundle *frameworkBundle = [NSBundle bundleWithIdentifier:@"com.opacitylabs.sdk"]; if (![frameworkBundle isLoaded]) { BOOL success = [frameworkBundle load]; if (!success) { NSString *errorMessage = @"Failed to load framework"; *error = [NSError errorWithDomain:@"OpacitySDKDylibError" code:1002 userInfo:@{NSLocalizedDescriptionKey : errorMessage}]; return -1; } } // Validate function pointers before registration void *functions[] = {(void *)opacity::ios_prepare_request, (void *)opacity::ios_set_request_header, (void *)opacity::ios_present_webview, (void *)opacity::ios_close_webview, (void *)opacity::ios_get_browser_cookies_for_current_url, (void *)opacity::ios_get_browser_cookies_for_domain, (void *)opacity::get_ip_address}; for (int i = 0; i < 6; i++) { if (functions[i] == NULL || functions[i] == (void *)0x1) { NSString *errorMessage = [NSString stringWithFormat:@"Invalid function pointer at index %d", i]; *error = [NSError errorWithDomain:@"OpacitySDKCallbackError" code:1004 userInfo:@{NSLocalizedDescriptionKey : errorMessage}]; return -1; } } __sync_synchronize(); On my podspec linker flags I have added s.pod_target_xcconfig = { 'OTHER_LDFLAGS' => '-undefined dynamic_lookup -Wl,-keep_private_externs -Wl,-no_deduplicate' }
Topic: Code Signing SubTopic: General Tags:
3w
Reply to Dynamic Library cannot call exposed C function
@DTS Engineer I just tried the SPM version of the package and found out that on release config, it crashes with a undefined symbol. I guess cocoapods masqueraded the issue. When ran with the debug scheme then it runs fine. The Package.swift is defined as follows // swift-tools-version: 5.8 import PackageDescription let package = Package( name: "OpacityCore", platforms: [ .iOS(.v13) ], products: [ .library( name: "OpacityCore", targets: ["OpacityCoreObjc", "OpacityCoreSwift"]) ], dependencies: [], targets: [ .binaryTarget( name: "sdk", path: "sdk.xcframework" ), .target( name: "OpacityCoreObjc", dependencies: ["sdk"], path: "src/objc", publicHeadersPath: ".", cSettings: [ .headerSearchPath("../../include") ], linkerSettings: [ .linkedFramework("CoreTelephony"), .linkedFramework("CoreLocation"), .linkedFramework("WebKit"), ] ), .target( name: "OpacityCoreSwift", dependencies: ["OpacityCoreObjc"], path: "src/swift" ), ] )
Topic: Code Signing SubTopic: General Tags:
3w
Reply to Dynamic Library cannot call exposed C function
@DTS Engineer as an aside for extra info. I'm adding the xcframework via cocoapods and I have tried to modify the signing of the framework via the following script in the podspec. I know Apple might not encourage the usage of Cocoapods but this is needed so we can distribute our library through several platforms s.script_phase = { :name => 'Sign Framework Binary', :execution_position => :before_compile, :script => <<-SCRIPT echo "🟦🟦🟦🟦🟦🟦🟦 Framework Binary Signing Script ===" # Use BUILT_PRODUCTS_DIR which points to BuildProductsPath FRAMEWORK_DIR="${BUILT_PRODUCTS_DIR}/../XCFrameworkIntermediates/${PRODUCT_NAME}/sdk.framework" # Debug: Print the expected path echo "Looking for framework at: $FRAMEWORK_DIR" if [ -d "$FRAMEWORK_DIR" ]; then # Try different ways to get signing identity SIGN_IDENTITY="$EXPANDED_CODE_SIGN_IDENTITY" if [ -z "$SIGN_IDENTITY" ] || [ "$SIGN_IDENTITY" = "-" ]; then SIGN_IDENTITY="$CODE_SIGN_IDENTITY" fi if [ -z "$SIGN_IDENTITY" ] || [ "$SIGN_IDENTITY" = "-" ]; then # Use the first available distribution identity SIGN_IDENTITY=$(security find-identity -v -p codesigning | grep "Apple Distribution" | head -1 | awk '{print $2}') fi if [ -z "$SIGN_IDENTITY" ] || [ "$SIGN_IDENTITY" = "-" ]; then # Fallback to development identity SIGN_IDENTITY=$(security find-identity -v -p codesigning | grep "Apple Development" | head -1 | awk '{print $2}') fi if [ -z "$SIGN_IDENTITY" ] || [ "$SIGN_IDENTITY" = "-" ]; then echo "🟥🟥 No valid signing identity found" exit 1 fi echo "Using identity: $SIGN_IDENTITY" codesign --force --sign "$SIGN_IDENTITY" "$FRAMEWORK_DIR" echo "🟩 Binary signed successfully" else echo "🟥 Framework not found at: $FRAMEWORK_DIR" exit 1 fi SCRIPT } Even with this script, the crash in TestFlight and via the debugging distribution still happens though.
Topic: Code Signing SubTopic: General Tags:
4w
Reply to Dynamic Library cannot call exposed C function
Yes, the .env is just for testing purposes. This entire app is just a tester app, so some quirks are fine and indeed the file does not cause any issues. Here is the crash report of my latest build crashlog.crash Here is the output of the file command $ file OpacityPod_Example OpacityPod_Example: Mach-O 64-bit executable arm64 $ file Frameworks/sdk.framework/sdk Frameworks/sdk.framework/sdk: Mach-O 64-bit dynamically linked shared library arm64 I'm sure I have ran the app with the Release config (done via changing the scheme and selecting run → release). I just tried the Isolating Code Signig Problems from Build Problems you shared. The development option is not there in Xcode 26, but I chose debugging that generated an .ipa which I installed in my device by dragging and dropping. The crash persists on that version. @DTS Engineer
Topic: Code Signing SubTopic: General Tags:
4w
Reply to Dynamic Library cannot call exposed C function
Here is what I get from my latest sent .xcarchive. It's fine to share almost everything about this app, it's just a small demo app. ...Products/Applications/OpacityPod_Example.app $ tree . |_____CodeSignature | |____CodeResources |____en.lproj | |____InfoPlist.strings |____AppIcon60x60@2x.png |____Base.lproj | |____Main.storyboardc | | |____whP-gf-Uak-view-TpU-gO-2f1.nib | | |____UIViewController-whP-gf-Uak.nib | | |____Info.plist | |____LaunchScreen.storyboardc | | |____01J-lp-oVM-view-Ze5-6b-2t3.nib | | |____UIViewController-01J-lp-oVM.nib | | |____Info.plist |____Assets.car |____.env |____OpacityPod_Example |____Frameworks | |____libswift_Concurrency.dylib | |____sdk.framework | | |_____CodeSignature | | | |____CodeResources | | |____sdk | | |____Info.plist |____embedded.mobileprovision |____Info.plist |____PkgInfo
Topic: Code Signing SubTopic: General Tags:
Aug ’25
Reply to Dynamic Library cannot call exposed C function
I have played around a bit more with the code: I tried passing pointers to the functions themselves Making sure the callbacks are called from the mainthread But nothing seems to work. I did stumble into this page though https://developer.apple.com/documentation/xcode/investigating-memory-access-crashes#Use-VM-Region-Info-to-locate-the-memory-in-your-apps-address-space And it's useful to understand the crash logs. My full crash is: Exception Type: EXC_BAD_ACCESS (SIGKILL) Exception Subtype: KERN_PROTECTION_FAILURE at 0x0000000000000000 Exception Codes: 0x0000000000000002, 0x0000000000000000 VM Region Info: 0 is not in any region. Bytes before following region: 4307271680 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL UNUSED SPACE AT START ---> __TEXT 100bbc000-100bc0000 [ 16K] r-x/r-x SM=COW /var/containers/Bundle/Application/D7CA13B9-71D1-467E-882D-317F9AF57049/OpacityPod_Example.app/OpacityPod_Example Termination Reason: CODESIGNING 2 Invalid Page So it's clearly a pointer exception error but it's not a bad acess but a KERN_PROTECTION_FAILURE so it could be indeed a iOS protection system to not be able to call a callback
Topic: Code Signing SubTopic: General Tags:
Aug ’25
Reply to Xcode 15, how to uncheck "Connect via network" for physical device?
I'm experiencing super slow installs on Xcode 15. I have nothing between me and the router and the phone, yet installing an app that would take a minute at most before is now stuck after 15 mins. The changelog seems to suggest turning off WiFi on mac and on iPhone forces to switch to USB connection but not even that is working. https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes issue 109466074 Is there any other workaround to disable network debugging? I simply cannot launch any app right now.
Sep ’23
Reply to NEHotspotConfigurationManager cannot connect
Hey! We are facing the same problem, I have scoured the internet and found no viable solution: Re-wrote the implementation I was using from obj-c to swift Do a SSID check after "applying" the configuration (not a fix, but at least let's me confirm the connection is successful) We tried a device running iOS 15 and it constantly fails, restarting the device does nothing A device running iOS 16 doesn't seem to show this issue (so far...) Somebody on StackOverflow mentioned the only workaround was to join the network manually, then try to join using the API, then forget the network, afterwards the network can be joined again So, it could be the issue is fixed on iOS 16 but cannot really confirm it so far. I hope to get some confirmation this bug has been fixed.
Dec ’22