Post

Replies

Boosts

Views

Activity

dlclose will not unload library when using macOS Frameworks
Hello,I am encountering an unsual problem when linking a library to macOS Frameworks: as soon as I'm linking to some specific frameworks (detailed below), dlclose will no longer work, meaning that the said library will not be unloaded from process memory.This is causing problems, because the update functionality of my application will not work - calling dlopen again will load the "old" library.The build details are:macOS High Sierra (10.13.6)Xcode 9.4.1 C++ Language Dialect: C++14 [-std=c++14]C++ Standard Library: libc++ (LLVM C++ standard library with C++11 support)Steps to reproduce the problem:Library (dylib) is linked ("Link Binary with Libraries") to: CoreFoundation and IOKit, plus the following additional frameworks - OpenDirectory, SystemConfiguration, Security, CoreServices, ApplicationServicesCompiling works fine, of course, and then the library is loaded, using dlopen by another application (Unix / terminal app)After calling dlclose, the library is still reported as being loaded in the process memoryThe problem will only happen when:the terminal app is ran from a terminal window (it cannot be reproduced when using Xcode directly to run / debug it)the library is linked to CoreFoundation, IOKit plus any one of the other frameworks (OpenDirectory, SystemConfiguration, Security, CoreServices, ApplicationServices)Does anyone know what may be causing this problem?On Linux based systems, the "-fno-gnu-unique" flag will not fix the problem, but at least offer the option to use the new / updated library. Is there, maybe, a similar flag for macOS?Any help would be greatly appreciated.Code snippet below:// Returns the full path of the application executable file const char* getApplicationPath() { static char s_szDir[1024] = {0}; if (!*s_szDir) { char buffer[1024]; char *answer = getcwd(buffer, sizeof(buffer)); strncpy(s_szDir, answer, 1024); s_szDir[1024-1] = '\0'; } return s_szDir; } // prints all loaded modules in the process memory (address space) void printLoadedModules( ) { std::cout<<"\ndynamic libraries loaded in the process memory:"; int count = _dyld_image_count(); for(int i = 0; i < count; i++ ) { const char * imageName = _dyld_get_image_name(i); if( !imageName ) continue; std::string strImageName = imageName; if( strImageName.find( "libwa" ) != std::string::npos ) std::cout<<"\n " << strImageName; } } int main(int argc, const char * argv[]) { std::string lib_path = getApplicationPath(); lib_path += "/libtest.dylib"; // Step 1: Print loaded libraries in the process memory before dlopen() std::cout<<"\n### Before dlopen \n"; printLoadedModules(); // Step 2: Load libtest.dylib void * lib_handle = (void*) dlopen( lib_path.c_str() , RTLD_LOCAL ); if( !lib_handle ) { std::cout<<"\nFailed to load libtest.dylib with error \n"<<dlerror(); exit(1); } // Step 3: Print loaded libraries in the process memory after dlopen() std::cout<<"\n\n### After dlopen \n"; printLoadedModules(); // Step 4: Unload libtest.dylib int close_code = dlclose( lib_handle ); lib_handle = nullptr; // Step 5: Print loaded libraries in the process memory after dlclose() std::cout<<"\n\n### After dlclose (closed code: " << close_code << ")\n"; printLoadedModules(); std::cout<<"\n\n"; return 0; }Thank you.
5
1
3.1k
Sep ’19
Different behaviour of softwareupdate CLI on M1 and Intel CPUs
Hello, It looks like the softwareupdate CLI is having different behaviours, depending on the architecture it runs on, when trying to install OS patches: Intel works as expected and is able to install both OS patches and software patches (e.g. Safari), silently, without the need of any user interaction ARM (M1) requires the end-user to input the root password, in order to install OS patches, but works as expected for software patches (e.g. Safari) - doesn't need any user interaction Need to mention that the above happens only on macOS Big Sur, for example updating 12.3 to 12.4. Is this an expected behaviour? Anyone else seeing this? Wondering why the additional step, for inputting the credentials, is required. I know there were mentions of softwareupdate being deprecated, but if this is happening, does anyone know if Apple would provide other means of installing OS patches automatically, but orchestrated? Maybe some Swift / ObjectiveC / C++ APIs? Thank you
0
0
539
Jun ’22
Notarization issue with library (dylib)
Hello, I am encountering a strange problem with the libraries built in my project. The libraries and the executable are packaged and sent to the notarization service, and the response is that the notarization is successful. Checking with codesign, all looks to be good: codesign -vvvv -R="notarized" --check-notarization <my_lib.dylib> <my_lib.dylib>: valid on disk <my_lib.dylib>: satisfies its Designated Requirement test-requirement: code failed to satisfy specified code requirement(s) However, if I do the following, the validation no longer works: spctl --assess --verbose=4 --type install <my_lib.dylib> <my_lib.dylib>: rejected source=Unnotarized Developer ID If I right-click the CLI, it will not execute, stating that the libs cannot be verified for the malicious content. This only happens to a certain build. The previous builds are fine, the next ones are also fine. Why would this happen and is there another way of detecting if the application was not notarized properly? Thank you
3
0
1.4k
Dec ’20
Zombie processes for terminal commands
Hello.We have encountered the following issue: we have a dynamic library that performs signature checks via codesign. The checks are performed using a pipe mechanism. The child runs execv("/usr/bin/codesign", "-dv --versbose=2 {full_path_to_library}") and the parent reads the output of the execv command.When the library is loaded from an user level application, everything is working as expected: our library will run execv, a new codesign process will start and will finish its job successfully.When the library is loaded from a daemon process, our library will run execv, a new codesign process will start, will return success but it will not stop. The process will be marked as a zombie process. Tried to kill it programatically using 'kill( pid, SIGKILL)' and also via terminal using 'kill -9 pid'. We tried also with every available parameter of the kill command, still no success.The zombie processes will not stop, until machine restart. The issue is reproducing only on macOS 10.15.4, in 10.14.6 is working as expected.The issue is reproducing also with other processes, including 'pkgutil', 'spctl', 'sysctl', 'date', 'id' and others.Please let us know how can we kill these zombie processes and what should we do in order to gracefully stop them after executing the requested command. Or if, maybe, this is a know issue with the latest macOS version.I just want to mention that the library is a C++ library.If there is anything we can collect from the system, please let us know.Many thanks in advance!P.S. I noticed a similar thread started in XCode: https://forums.developer.apple.com/thread/133094
4
0
1.7k
Jun ’20