I opened an executable built for OSX in a text editor (TextMate).
Within the last line of text there is this string:
/Users/FOOBAR/Documents/macapp/macapp/macapp/
macapp is the name of the executable.
However, FOOBAR, seems to be the username of the person who compiled this.
Is this something that Xcode will put into your executable on build?
If it helps, there are other string indicating the name of the Xcode program to be "/Applications/Xcode 2.app".
That's clearly a mistake on the part of the developer and has possibly been left behind from a previous debugging or testing session.
Getting details of particular directories that can be used by the app must be done using APIs like [NSFileManager URLsForDirectory:inDomains:] or NSSearchPathDirectory.
Related
In my old macOS app, written in Objective-C, I am debugging a reproducible problem in which a file package is removed too early during a system frameworks call. To get a clue, I would like to have the debugger break whenever a file is deleted. To that end, I have set symbolic breakpoints in Xcode at these symbols:
unlink
unlinkat
-[NSFileManager removeItemAtPath:error:]
-[NSFileManager removeItemAtURL:error:]
All of these breakpoints resolve as expected to actual breakpoints, and they break as expected when files are deleted as expected. But during the troublesome too-early file deletion, no break occurs.
Are there any other functions in macOS which can delete files, for which I should add breakpoints?
BACKGROUND INFORMATION:
The problem occurs in my custom NSDocument subclass, when calling [super saveDocument] on a newly-duplicated (as in File > Duplicate) but never-before saved document package. Such document packages reside in ~/Library/Autosave Information/, and when things work properly, remain there until the Save panel appears, and is subsesquently dismissed. However, in the bug case, the package disappears immediately when the user clicks File > Save (or an Auto Save occurs), apparently causing a later error indicating that the deleted package could not be moved to the path returned by the Save Panel.
I also tried changing the POSIX permissions of that package after it appears, and before clicking File > Save, to octal 500. The idea is that it could not be deleted, and I also turned on all of my exception and error breakpoints, hoping the mystery deleter would squawk to the debugger console. Result: The package was not deleted, and, as I had hypothesized, the Save operation succeeded. But nothing squawked. So this mystery deleter is indeed the problem, but is apparently both stealthy and forgiving :(
UPDATE 2019-JUL-19:
After 5 days of finding other things to do, I decided to bite the bullet and use DTrace as suggested Ken Thomases. It worked, showing me that all files in the subject file package were deleted by a call to libsystem_kernel.dylib__unlink, which was in turn called by -[NSFileManager removeItemAtPath:error:].
I do not know why my breakpoints on these functions did not break for these calls, except maybe there is a clue at the bottom of the stack trace, mentioning "xpc". Is it possible that this file deletion is done by an XPC helper process? Does DTrace also probe helper processes of the process being probed? That would be pretty amazing.
Here is an abridged DTrace session transcript:
Air2 jk$ sudo dtrace -n 'syscall::unlink*:entry,syscall::rmdir:entry,syscall::rename:entry { printf("time=%d arg=%s\n", timestamp/1000000000, copyinstr(arg0)); ustack(100); }' -p `pgrep MyApp`
Password:
dtrace: description 'syscall::unlink*:entry,syscall::rmdir:entry,syscall::rename:entry ' matched 4 probes
CPU ID FUNCTION:NAME
1 178 unlink:entry time=6562 arg=/Users/jk/Library/Autosave Information/Unsaved MyApp Document.bmco
libsystem_kernel.dylib`__unlink+0xa
libremovefile.dylib`__removefile_tree_walker+0x147
libremovefile.dylib`removefile+0x99
Foundation`-[NSFilesystemItemRemoveOperation main]+0xba
Foundation`__NSOPERATION_IS_INVOKING_MAIN__+0x11
Foundation`-[NSOperation start]+0x2db
Foundation`-[NSFileManager removeItemAtPath:error:]+0x54
AppKit`__90-[NSDocumentController(NSInternal) _autoreopenDocumentsFromRecords:withCompletionHandler:]_block_invoke_2+0x90
AppKit`__89-[NSDocumentController reopenDocumentForURL:withContentsOfURL:display:completionHandler:]_block_invoke_2+0xa6
AppKit`___NSMainRunLoopPerformBlockInModes_block_invoke+0x19
CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__+0xc
CoreFoundation`__CFRunLoopDoBlocks+0x17b
CoreFoundation`__CFRunLoopRun+0xae8
CoreFoundation`CFRunLoopRunSpecific+0x1f3
HIToolbox`RunCurrentEventLoopInMode+0x124
HIToolbox`ReceiveNextEventCommon+0x164
HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter+0x40
AppKit`_DPSNextEvent+0x3de
AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:]+0x548
ViewBridge`-[NSViewServiceApplication nextEventMatchingMask:untilDate:inMode:dequeue:]+0x5f
AppKit`-[NSApplication run]+0x292
AppKit`NSApplicationMain+0x309
libxpc.dylib`_xpc_objc_main.cold.3+0x38
libxpc.dylib`_xpc_objc_main+0x203
libxpc.dylib`_xpc_copy_xpcservice_dictionary
ViewBridge`xpc_connection_handler
ViewBridge`NSViewServiceApplicationMain+0xbff
com.apple.appkit.xpc.openAndSavePanelService`main+0xc0
libdyld.dylib`start+0x1
com.apple.appkit.xpc.openAndSavePanelService`0x1
(The call in that transcript apparently tried to unlink the file package, which I think would have failed since the package was not empty. It is followed by several similar calls which walk the package tree, deleting each node, and finally a repeat of that call to delete the package, apparently with success.)
UPDATE 2019-AUG-06
Although we now know the low-level cause of the problem, we still don't know the high-level cause. I have since discovered that the problem (premature deletion of the temporary document file in ~/Library/Autosave Information) only occurs in macOS 10.15 Beta 4-5 (the current version) and only when the app is built with App Sandbox OFF. When App Sandbox is on, the relevant Autosave Information is in a different location, in the app's container, so this should be a good clue! The problem is easily reproducible with a small demo app, Core Data, document-based, which I have submitted to Apple along with a short video. If anyone has a line to Apple, please direct their attention to FB6937676 !
A rename operation will make the source path no longer refer to a file (looks like the file at the source path was deleted). It can also unlink/delete a file at the destination path, although it will be replaced with the file at the source path. So, that would be rename(), renameat(), renamex_np(), and renameatx_np().
Of course, rmdir() can remove a directory, but only if it's empty.
Apparently, there's a hidden delete() system call. It's described as "delet[ing] a name from the filesystem using Carbon semantics". It's possible the frameworks are using that.
The app is being built on another persons computer and then sent to me to test. I am extremely new to this but have been testing apps for a few months. I just don't do programming at all. I can maneuver my way around inside Xcode 7.1 pretty well. However, I do need to fix these errors in order to test this current app. Can someone help me out?
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang failed with exit code 1
I also have another error that reads
Error reading '/Users/logjam3/Desktop/Cosmo Client/Cosmo Client.xcodeproj'
This is exactly the path to where my project is so I don't know why I get this error.
You have to change the prefix header source location. You can do this by searching for prefix header then changing the location by pressing the 'file' icon on the right sidebar of Xcode.
I have been developing an OSX app with Delphi XE3 and running into various problems. The latest one is with the sanboxed version built for the Apple Appstore.
The user has to select an arbitrary folder and the app needs to get access to it. Since there is a problem with the OpenDialog, I had to turn to drag-drop functionality instead.
The user drags a folder to the app, the sandbox gives the app temporary access to it and all works properly.
To preserve the access to this folder when the app is restarted I have to use the so-called "security-scoped bookmarks"
I am having two issues with them:
1) How to add the "com.apple.security.files.bookmarks.app-scope" entitlement to an XE3 firemonkey app? It is not available in the Project Options->Entitlements. If I add it manually in the ".entitlements" file it gets overwritten when the app is built.
So is there a way to add a custom entitlement that is not in the list in the project options?
2) To create the bookmark I should use the NSURL.bookmarkDataWithOptions method. I think it should be used like this, but I am not sure of the exact syntax:
var
URL: NSURL;
Err: NSError;
Data: NSData;
...
URL := TNSURL.Create;
Data := URL.bookmarkDataWithOptions(NSURLBookmarkCreationWithSecurityScope, nil, #Err);
...
Maybe there should be a call to Wrap(...) instead of Create.
I have not yet experimented with it, because it is pointless without the answer to issue 1).
It seems no one has written anything about these problems for Delphi, but I hope someone here has experience with that.
Thanks in advance.
Edit:
For problem 1) I tried to add edit manually the ".entitlements" file in the OSX32 folder and set it to read-only to prevent it from being overwritten. It was too easy to be true of course, because the linker complained that the file can not be modified...
OK, I finally found the way to manually add entitlements that are not available in the Project Options > Entitlements.
Instead of selecting the "App Store" build in the Project Manager you have to select a Normal release build and deploy the application as usual.
The application gets deployed in the PAServer scratch-dir as APP package. Inside this package there is an "Entitlements.plist" file, which is in XML format and can be edited with a text editor. It is quite obvious how to add new entitlements once you open the file.
After it is edited, the app has to be code-signed manually and a package has to be prepared. It is slightly more complicated than using the Delphi IDE, but there are instructions about it on the Embarcadero and Apple websites and it actually went without problems.
Still haven't tried the bookmarkDataWithOptions functions.
An alternative could be to deactivate the checkbox for the entitlements-file in the deployment page.
But attention: Evry time you change between Build/Release or App Store/Normal, delphi activates the checkbox. That means you have to deactivate it again in the deplayment-page, to avoid the transfer of this file to the mac PC.
By the way: Do you have tryed meanwhile the StartAccessingSecurityScopedResource function?
In the MacApi.Foundation unit the function is not declared in the NSURL interface.
Do you have found a way to use this function?
I am new to Mac development and are trying to understand the location that XE2 firemonkey apps are deployed. I understand that the application is deployed into a "package" however I am not sure how this work when getting path information from within my app.
My application loads a dylib that I moved over from Visual Studio to XCode and initializes it by passing in a driver path (intended to be off the application path). i.e.
UDMXLibInit(PAnsiChar(AnsiString(driver_path))
If I put a breakpoint on this line in Delphi I find that driver_path is:
.../PAServer/scratch-dir/MacMini/LightFactory3.app/Content/MacOS/drivers
In my dylib I put a breakpoint in XCode on the "Init" function I find that the path is now:
.../PAServer/scratch-dir/MacMini/LightFactory3.app/Content
There appears to be some vodo that is truncating the path. Is this because "LightFactory3.app" is a package and there is something I dont understand or is there something else I am missing about passing this string between app and library under OSX?
Thanks in advance.
This appears to be a bug in the Expressions view for XCode 3.2. For some reason it truncates strings.
The actual string was correct - figure this out by passing it back to to my app.
I have met a strange problem with the localized strings. I have only a 'Localizable.strings' in my 'en.lproj' folder and it works fine. all the strings are shown on device. but the next time i compile it and run, it shows only the ID of the strings. even if i change nothing and only click on build&debug. and the next time it works fine again and next time again shown with IDs.
so does anyone knows why this is happening? it's kind of annoying that i always need to build twice.
My SOLUTION is at bottom:
I've been running into the same problem: Alternating runs yield correct, then incorrect translations (only for English though).
Adding "-NSShowNonLocalizedStrings YES" as an argument to the app yielded:
Localizable string "MyKey" not found in strings table "Localizable" of bundle CFBundle
So, I tried loading the key file directly from the bundle as a string and dumping it. Well, the times it did NOT work correctly, it was displaying a bunch of built-in iOS messages. So, I went to the APP file that was built, opened the package contents, and viewed the en.lproj/Localizable.strings file...and voila!!! The file had been filled with Apple iOS key/value pairs. On the next build, it was filled as expected.
Of course, this has nothing to do with the encoding of the files (which should be UTF-16). I have not been able to locate anything with mention of this specific problem.
MY SOLUTION:
I copied the contents of the legitimate english Localizable.strings file FROM THE APP PACKAGE (not from my source) into an XML file (when compiled, the .strings file are converted into XML) and added to my project. I then loaded this file into a dictionary at startup, and if the call to NSLocalizedString returned the key instead of the value, I did a lookup on the dictionary I loaded. In theory, you could do this for all languages, but I was only having the problem with english.
Yes, it's not the answer to the problem, but it's a workaround.
Check if you have more than one Localizable.strings in your project. Merging them into one solved it for me. (Check any external code you use e.g. ShareKit)