Post

Replies

Boosts

Views

Activity

Reply to Best container for automated download & running of installer .pkg
[quote='788938022, DTS Engineer, /thread/756027?answerId=788938022#788938022'] Are you using hdiutil for that? And, if so, I presume you hide that mount from the user? [/quote] Why yes, I am using hdiutil to mount the image. Specifically, I'm using: (translating Obj-C to pseudocode just for brevity) diskImagePath = "<path to dmg>" mountPath = "/Volumes/" + UUID().uuidString /usr/bin/hdiutil attach "$diskImagePath" -mountpoint "$mountPath" -nobrowse -noautoopen And, later, to unmount, I'm using: /usr/bin/hdiutil detach "$mountPath" -force [quote='788938022, DTS Engineer, /thread/756027?answerId=788938022#788938022'] Your primary concern seems to be the point at which the system ingests your stapled ticket. [/quote] That's correct. More precisely, I'm actually not completely sure what to be scared of in this ecosystem. I definitely want normal security measures to work as intended. This is why I phrased the original question (albeit somewhat confusingly) as "what is the best practice here", rather than "how do I fix this rare problem". For example, if you were to (hypothetically) come back and say, "in this scenario, a notarized DMG is appropriate because , and you should also do to avoid ", then what that tells me is: The general approach I'm using today is here to stay, at least for now. Thus, it's worth my time to add more automated metrics around my hdiutil attach failure (see "Skippable Backstory" in the original post), and file a (useful) bug report. And, because I'm using the technologies in a recommended way, I'm more likely to get a useful answer back, which is good for me. On the other hand, if you were to say, "in this scenario, a notarized DMG is bad because , and you should use instead", then what that tells me is: There's a risk that my undesirable use of this technology is contributing to my hdiutil attach problem. Thus, it's not worth my time to fix the hdiutil attach problem, and instead, I should reengineer my fancy self-update system to operate in a way that is recommended by Apple And, applying the recommendations may completely sidestep my problems, which is good for me.
May ’24
Reply to Best container for automated download & running of installer .pkg
[quote='788832022, crazymacguy, /thread/756027?answerId=788832022#788832022, /profile/crazymacguy'] For pre-macOS 10.15, we also have a kernel extension. [/quote] [quote='788851022, DTS Engineer, /thread/756027?answerId=788851022#788851022'] So that’s only necessary, and only installed, on systems prior to macOS 10.15? [/quote] Correct. That's a big part of why I'm itching to drop support for 10.14 and earlier. Just waiting for the populations to drop low enough.
May ’24
Reply to Best container for automated download & running of installer .pkg
[quote='788790022, DTS Engineer, /thread/756027?answerId=788790022#788790022'] Does your app need an installer at all? That is, does the installer package install components outside of the main app in /Applications? If so, what sort of components? [/quote] You're asking an engineer whether or not something is possible? ;) No, we do not technically need an installer. We do currently install files outside of the main app bundle, yes — but, honestly, the only reason we're using an installer package today is because that's the way it was originally designed. The only components remaining outside of the main application bundle are launch agents, launch daemons, and command-line executables. For pre-macOS 10.15, we also have a kernel extension. And, for supported browsers, we also have browser extensions that go in "magical" system folders, such as (for example) in /Library/Application Support/Mozilla/Extensions/. The installer package understands these details, and also correctly requires a system reboot when needed. More components used to exist; as they have been replaced and/or upgraded over the years, more often than not, they get moved to inside the main application bundle. I have hope that we will eventually become an app that can be installed by dragging a single app into the Applications folder, but it's a slow process. We'll make a huge step forward when we drop support for 10.14 and older, because the kext and the conditional reboot requirement will both go away. In summary, I think my answer is actually both. Today, yes, we "require" an installer package. But, I'm also quite interested in the future where our app is a single bundle.
May ’24
Reply to Forced exit of the application will have abnormal crash data
I'm having what I suspect is the same problem.  I have a multithreaded app, and one of the threads decides to shut the app down, and it sometimes crashes.  I've narrowed down the crash to this example C++ app: #import <dispatch/dispatch.h> #import <iostream> #import <regex> int main() {     dispatch_async(dispatch_get_main_queue(), ^{         // Main app code goes here         // Spawn a background thread to do some work:         dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{             static const std::regex pattern("hello world", std::regex_constants::icase);             std::cmatch match;             for (int x = 0; x < 1000; ++x) {                 //std::cout << x << std::endl; // To make sure exit() is called somewhere inside this loop                 std::regex_search("example", match, pattern);                 std::regex_search("hello", match, pattern);                 std::regex_search("world", match, pattern);                 std::regex_search("hello world", match, pattern);                 std::regex_search("hello beautiful world", match, pattern);             }         });         // App continues on this thread         // Try to delay exit until somewhere inside the regex work:         usleep(5000);         exit(0);     });     dispatch_main();     return -1; } (Enabling the Address Sanitizer makes it easier to hit the crash) The ways this app exits are any of the following: (clean exit) or libcabi.dylib: terminating with uncaught exception of type std::1::regex_error: Unknown error type Abort trap: 6 or libcabi.dylib: terminating with uncaught exception of type std::1::regex_error: Unknown error type If you run this example app through lldb, the stack trace indicates that one thread is using the STL while another is inside the STL's destructor. I'd paste a stack trace here, but at the moment, using lldb with this example app is hanging my entire computer... Anyways, what's a little interesting is that if you move the std::regex constant from the stack to the heap, the crash goes away. So, at the very least, a possible workaround is to never store any C++ object on the stack. Unfortunately, with legacy codebases and third party libraries we don't control, that's not really a feasible option. I like what you describe iOS does in some cases (unloading the app from memory)... is that possible in a traditional tool on macOS? It seems to me that the root problem here is that invoking exit() causes all destructors for all statically allocated objects (regardless of thread) to be invoked, regardless of whether or not those threads are still running and are still using those objects. To make matters more complicated, destructors take non-zero time to finish, and invoking the destructors runs in parallel with all other threads in the app, none of which have any clue that the world is getting burned down. This leads to unreproducible crashes caused by what are essentially race conditions. One interesting possibility is to (1) iterate over the list of all threads in the app, (2) suspend all of them except your own, and (3) exit(). However, doing so has the same underlying problem as signal handling; there is no way to control exactly where/when a thread is suspended relative to critical sections of code. For all you know, you suspended a thread in the middle of reallocing a std::map, and when exit() ultimately gets around to invoking the destructor for that object, it's in an undefined state, and we crash. So although it may be an interesting academic exercise, it's not really helpful, even at all. Ideally, we want the entire app to halt, exactly where it is, wherever it is, and then force-unload the entire app from memory, without invoking any destructors at all. What is the correct way for a modern multi-threaded C++ app to shut down without crashing?
Nov ’20
Reply to Notarizing a command-line tool
I've noticed that in the case of apps exported from an archive using -exportArchive, the exported copy is different than the copy inside the archive. I don't know what the mutation is, but I'm assuming it's important.Unlike an app, can you yank a tool out of an archive with cp or ditto?
Feb ’20
Reply to Notarizing a command-line tool
Here's the contents of my options plist:&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt; &lt;plist version="1.0"&gt; &lt;dict&gt; &lt;key&gt;method&lt;/key&gt; &lt;string&gt;developer-id&lt;/string&gt; &lt;/dict&gt; &lt;/plist&gt;What you suggest is exactly what I'm doing at the moment; the apps I can build using archive/export, and Xcode does most of everything automatically. For the tool, I added --timestamp to OTHER_CODE_SIGN_FLAGS (only in Release mode), and I set CODE_SIGN_INJECT_BASE_ENTITLEMENTS to NO (only in Release mode), and then I simply build it in Release mode. This approach works just fine, but results in some forking of logic in our build scripts. To clean up our build scripts and to standardize how each Xcode target is built, I was hoping I could use archive/export for both apps and tools.
Feb ’20