How to symbolicate a Hang report for OS X apps? - macos

One of my apps (release version) was unresponsive, so I had to force-quit it.
OS X presented a Hang report (no crash report), which I copied to a *.crash file.
I'm aware of I can use services such as HockeyApp or atos directly to symbolicate Crash Reports, but how can I symbolicate Hang reports for OS X apps?

After some time, I found out how to handle the Hang reports, which are slightly different from normal crash reports. Here's what I did:
In Xcode look up the corresponding archive of the app that crashed in the Organizer and reveal it in Finder (right-click).
Right-click the archive and choose Show Package Contents.
Copy the *.app from Products and the corresponding *.dSYM file from the dSYMs directory into a new folder, e.g., on your Desktop. You will have a MyApp.app and a MyApp.app.dSYM in the new folder. The naming of the files is important.
ls into the new folder via the Terminal.
Now to use the atos tool ('convert numeric addresses to symbols of binary images or processes'), we need to first determine the load address of your app at runtime, and the address of the stack frame while the app was hanging.
Open the Hang report, and find a line which says Binary Images: somewhere below the Heaviest stack for ... line. In my case this looks similar to:
Binary Images:
**0x107b0f000** - 0x108b59fff com.company.MyApp 1.1.0 (2) <6080DCE1-9086-311C-899F-CC22B32D694D> /Applications/MyApp.app/Contents/MacOS/MyApp
0x7fff89c7e000 - 0x7fff89c87fff libsystem_pthread.dylib (105.10.1) <3103AA7F-3BAE-3673-9649-47FFD7E15C97> /usr/lib/system/libsystem_pthread.dylib
0x7fff8b0bf000 - 0x7fff8bc06fff com.apple.AppKit 6.9 (1344.36) <D94A7D32-A789-37EA-A85C-BEFA7DE716E6> /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
0x7fff8bd6e000 - 0x7fff8c09cfff com.apple.Foundation 6.9 (1152.12) <C0EE9DA6-C111-358A-8874-DA175BB797D6> /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
The address 0x107b0f000 surrounded by ** is our load-address, which you should copy.
Next, we need to find the addresses we want to find symbol information for, that is, get the actual method signatures and the code lines, which led to the hang. Therefore, look up your app's name in the stack at the beginning of the Hang report, below 'Heaviest stack':
Heaviest stack for the main thread of the target process:
10 start + 1 (libdyld.dylib + 13769) [0x7fff91df35c9]
10 NSApplicationMain + 1832 (AppKit + 10612) [0x7fff8b0c1974]
10 -[NSApplication run] + 594 (AppKit + 95459) [0x7fff8b0d64e3]
10 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 194 (AppKit + 145072) [0x7fff8b0e26b0]
10 _DPSNextEvent + 964 (AppKit + 147201) [0x7fff8b0e2f01]
10 _BlockUntilNextEventMatchingListInModeWithFilter + 71 (HIToolbox + 190347) [0x7fff96ae378b]
10 ReceiveNextEventCommon + 431 (HIToolbox + 190794) [0x7fff96ae394a]
10 RunCurrentEventLoopInMode + 235 (HIToolbox + 191439) [0x7fff96ae3bcf]
10 CFRunLoopRunSpecific + 296 (CoreFoundation + 464984) [0x7fff901f1858]
10 __CFRunLoopRun + 927 (CoreFoundation + 466495) [0x7fff901f1e3f]
10 __CFRunLoopDoSources0 + 269 (CoreFoundation + 469005) [0x7fff901f280d]
10 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 (CoreFoundation + 525953) [0x7fff90200681]
10 __NSThreadPerformPerform + 293 (Foundation + 416988) [0x7fff8bdd3cdc]
10 ??? (MyApp + 62967) [0x108b1e5f7]
8 ??? (MyApp + 48600) [0x108b1add8]
8 -[IKImageBrowserView(ImageBrowserLayout) itemFrameAtIndex:] + 63 (ImageKit + 400983) [0x7fff91140e57]
[...]
At the end of this example stack trace, you find MyApp listed twice. Copy both addresses, 0x108b1e5f7, 0x108b1add8, and close the report.
Now we are ready to use atos. In the Terminal enter the following and press Return:
atos -o MyApp.app/Contents/MacOS/MyApp -arch x86_64 -l 0x107b0f000 0x108b1e5f7 0x108b1add8
atos will symbolicate the addressess using the *.dSYM file within the same directory and hopefully output something like:
-[MainWindowController loadDidFinish:] (in MyApp) (MainWindowController.m:127)
-[MainWindowController view:stringForToolTip:point:userData:] (in MyApp) (MainWindowController.m:231)
Yay, that looks promising!
If atos outputs the same addresses you've put it, instead of code lines, something went wrong. The top source for errors here are probably wrong memory addresses, so make sure, you've chosen the right ones.
Let me know if you have further questions (#raffael_me).

Related

Incomplete paste in a file (using cat) when copy selection from terminal

I am trying to copy output from the Mobaxterm terminal in a file in Ubuntu 20.4 running on Win 10 - WSL 2.
Steps I perform:
I select the lines I want to copy.
cat > file
Paste (with Middle-Click, Shift-Ins, Right click menu & Paste)
Ctrl-D to finish the input for the cat command
The result are not complete/reliable. I created several files using different copy&paste methods and the files obtained has different sizes (even when using the same method). See bellow:
wc AftnRG.trace.log.*
233 1704 13751 AftnRG.trace.log.console
233 1819 14570 AftnRG.trace.log.consoleMc
233 1734 13940 AftnRG.trace.log.consoleMcCc
233 1689 13625 AftnRG.trace.log.consoleMcCd
233 1759 14129 AftnRG.trace.log.consoleMcCd2
233 1749 14066 AftnRG.trace.log.consoleMp
233 1713 13814 AftnRG.trace.log.consoleSi
234 1756 14134 AftnRG.trace.log.consolecp
233 1704 13688 AftnRG.trace.log.consolesi
Legend: Mc - middle click, Mp - Menu Paste, Si - shift Insert, Cp - menu Copy Paste, Cd - Ctrl-D , Cc - Ctrl-C
The paste looks complete but data in the file is not.
What am I doing wrong?
How to obtain the data from the clipboard complete in a file?
P.S. I remeber a similar situation when using ssh between RedHat native machines.
At the question how to obtain complete data, I found that using vim, paste and save in a file, there were no lost of information.
It is still unclear why cat is not working as expected.

Otool - Get file size only

I'm using Otool to look into a compiled library (.a) and I want to see what the file size of each component in the binary is. I see that
otool -l [lib.a]
will show me this information but there is also a LOT of other information I do not need. Is there a way I can just see the file size and not everything else? I can't seem to find it if there is.
The size command does that, e.g.,
size lib.a
will show the size of each object stored in the lib.a archive. For example:
$ size libasprintf.a
text data bss dec hex filename
0 0 0 0 0 lib-asprintf.o (ex libasprintf.a)
639 8 1 648 288 autosprintf.o (ex libasprintf.a)
on most systems. OS X format is a little different:
$ size libl.a
__TEXT __DATA __OBJC others dec hex
86 0 0 32 118 76 libl.a(libmain.o)
75 0 0 32 107 6b libl.a(libyywrap.o)
Oddly (though "everyone" implements it), I do not see size on the POSIX site. OS X has a manual page for it.

Getting symbol names from a Mac app's call stack

I have a stack trace from my Mac App Store app, that I'd like to read to help diagnose a problem the user is experiencing. I have the dSYM file and original archived build, but I do not have a full crash report. All I would like to know is the name of the methods in the stack trace (you can see two of them for MyAppName, below). I have not been able to get lldb or atos to give me this information. This is what the stack trace looks like:
0 CoreFoundation 0x00007fff92fdd25c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff918dbe75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff92ebb4f5 -[__NSArrayM objectAtIndex:] + 245
3 MyAppName 0x0000000108e91c6b MyAppName + 126059
4 MyAppName 0x0000000108e7556f MyAppName + 9583
5 AppKit 0x00007fff8d883099 -[NSToolbarButton sendAction:to:] + 75
6 AppKit 0x00007fff8d8830e8 -[NSToolbarButton sendAction] + 65
7 AppKit 0x00007fff8d436f0c -[NSToolbarItemViewer mouseDown:] + 4897
8 AppKit 0x00007fff8d352a58 -[NSWindow sendEvent:] + 11296
9 AppKit 0x00007fff8d2f15d4 -[NSApplication sendEvent:] + 2021
10 AppKit 0x00007fff8d1419f9 -[NSApplication run] + 646
11 AppKit 0x00007fff8d12c783 NSApplicationMain + 940
12 libdyld.dylib 0x00007fff87df35fd start + 1
13 ??? 0x0000000000000001 0x0 + 1
To get a symbol (say, for level 3 above), what command can I use? When I was calling lldb, it wasn't even clear if I should be using the hex address or the offset, if that's what the 126059 is on level 3.
Update
According to the atos documentation, it looks like I should invoke it like so:
xcrun atos -arch x86_64 -o MyAppName.app/Contents/MacOS/MyAppName -l <LOADED ADDRESS> 0x0000000108e91c6b
What would I use as the loaded address, though? All I have is what I pasted above. Whether I use 0x0000000000000001, 0x00007fff87df35fd, or leave out -l entirely, I get 0x0000000108e91c6b (the address I specified) printed back to standard out.
In most tools that dump stack traces (particularly CrashReporter) there's a section at the bottom of the report with all the images currently loaded in the program, their UUID's and their load addresses. You should always make sure to get that info along with the stack trace since that's what tells you the load address of the binary, and also will ensure that you have the right version of the debug information, since you can match the UUID against the UUID in the dSYM or binary.
You might be able to use the "Symbol Name + offset" part of the trace to figure out the load address, however. Generally, this last column is the offset of the address in the backtrace from the closest unstripped symbol in that binary. So you just find the address of that symbol in your stored binary, add the offset to that address, and subtract that from the address listed in the third column above. In lldb, you can find the address of a symbol using:
(lldb) image lookup -n <SymbolName>
That calculation will give you the "slide" of the binary from its default load address. Then run lldb on your binary and do:
(lldb) image load -f MyAppName -s <Calculated Slide>
Now you can look up the addresses from MyAppName in the stack trace using:
(lldb) image lookup -va <ADDRESS>
However, main executables are usually totally stripped - since they generally don't provide symbols for use by any other component of the system, so there aren't any symbols left. In that case, I would guess MyAppName in the listing above is just the __TEXT.__text section of the binary, though I'm not 100% sure about that. Anyway if that is right, you can find the default load address of that section by loading the binary in lldb and doing:
(lldb) image dump sections MyAppName
Then do the same calculation listed above.

Symlink to webstorm, ain't working

I've tried doing this:
sudo ln -s "/Applications/WebStorm.app/Contents/MacOS/webide" /bin/webstorm
and then if I run it, it throws
013-10-26 15:40:56.191 webstorm[12210:1f03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString hasPrefix:]: nil argument'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff895cc41c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff863eae75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff895cc2cc +[NSException raise:format:] + 204
3 CoreFoundation 0x00007fff894e572a -[__NSCFString hasPrefix:] + 90
4 webstorm 0x0000000100001f03 satisfies + 435
5 webstorm 0x000000010000245d findMatchingVm + 1213
6 webstorm 0x0000000100003832 -[Launcher launch] + 98
7 Foundation 0x00007fff8fdf170b __NSThread__main__ + 1318
8 libsystem_pthread.dylib 0x00007fff847bd899 _pthread_body + 138
9 libsystem_pthread.dylib 0x00007fff847bd72a _pthread_struct_init + 0
10 libsystem_pthread.dylib 0x00007fff847c1fc9 thread_start + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
So, how do I start webstorm from the terminal?
ps. interestingly if I run it directly it runs
"/Applications/WebStorm.app/Contents/MacOS/webide"
but I prefer something shorter than that
Oh... I was doing it wrong... There's an option in Webstorm... "Tools -> Create command line launcher"
it works great. I love this IDE. "JetBrains" - you guys are awesome!
The code is not expecting to be run from a symlink. Kind of a bug, but an obscure one I guess. You can instead put it on your PATH (or add an alias, but that's not the normal way to solve this problem). Here is how to put it on your PATH -
export PATH=$PATH:/Applications/WebStorm.app/Contents/MacOS/
although this might still hit the same bug, I guess. So try it first - if it works, add it to your $HOME/.bashrc file.

NSInternalInconsistencyException while running Haskell & SDL program

I am trying to compile and run a simple SDL program on OSX 10.8.2, SDL 1.2.15, GHC 7.4.2, haskell SDL bindings 0.6.4:
import Graphics.UI.SDL as SDL
main :: IO ()
main = do
screen <- setVideoMode 640 480 32 [SWSurface]
hello <- loadBMP "hello.bmp"
blitSurface hello Nothing screen Nothing
SDL.flip screen
delay 2000
It compiles (ghc test.hs) without erros, but when I try to run it, I get the following exception:
$ ./test
2012-11-30 12:37:29.453 test[8995:707] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Error (1000) creating CGSWindow on line 259'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff8cf060a6 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff88e813f0 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8cf05e7c +[NSException raise:format:] + 204
3 AppKit 0x00007fff87e41c29 _NSCreateWindowWithOpaqueShape2 + 655
4 AppKit 0x00007fff87e40420 -[NSWindow _commonAwake] + 2002
5 AppKit 0x00007fff87dfee62 -[NSWindow _commonInitFrame:styleMask:backing:defer:] + 1763
6 AppKit 0x00007fff87dfdfaf -[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1568
7 AppKit 0x00007fff87dfd97f -[NSWindow initWithContentRect:styleMask:backing:defer:] + 45
8 libSDL-1.2.0.dylib 0x0000000101dc6bf6 -[SDL_QuartzWindow initWithContentRect:styleMask:backing:defer:] + 279
9 libSDL-1.2.0.dylib 0x0000000101dc4ac9 QZ_SetVideoMode + 2629
10 libSDL-1.2.0.dylib 0x0000000101dbb903 SDL_SetVideoMode + 886
11 test 0x0000000101b9d6b2 smJx_info + 50
)
libc++abi.dylib: terminate called throwing an exception
As far as I understand, this has something to do with main()-replacement trickery SDL performs. I looked at several other SDL-using Haskell apps; the ones that I managed to compile show the same behavior (which may point to some problem with my particular configuration). One exception is Eternal10Seconds which uses -no-hs-main ghc option and some .c/.h magic. Is this necessary, or there is more clear way to make things work?
Sorry for the informational noise, but I managed to solve it myself. It seems that .c magic is inevitable, but it requires certain efforts to make it working with cabal. Based on the example from haskell-SDL repo and TimePiece, I put together a template. I am planning to extend it a bit to make it truly cross-platform (because I need it myself anyway).

Resources