{"id":19720900,"url":"https://github.com/piasy/xrash","last_synced_at":"2026-02-28T08:08:41.371Z","repository":{"id":75583080,"uuid":"263491965","full_name":"Piasy/Xrash","owner":"Piasy","description":"Xrash is a CMake based cross-platform project for C++ sources, and also illustrate crash symbolicate within them.","archived":false,"fork":false,"pushed_at":"2023-12-08T06:07:13.000Z","size":3592,"stargazers_count":11,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-29T21:39:24.788Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Piasy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-05-13T01:15:05.000Z","updated_at":"2023-12-08T06:06:06.000Z","dependencies_parsed_at":"2025-04-29T21:43:31.332Z","dependency_job_id":null,"html_url":"https://github.com/Piasy/Xrash","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Piasy/Xrash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Piasy%2FXrash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Piasy%2FXrash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Piasy%2FXrash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Piasy%2FXrash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Piasy","download_url":"https://codeload.github.com/Piasy/Xrash/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Piasy%2FXrash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29928162,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T19:37:42.220Z","status":"online","status_checked_at":"2026-02-28T02:00:07.010Z","response_time":90,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T23:12:53.155Z","updated_at":"2026-02-28T08:08:41.361Z","avatar_url":"https://github.com/Piasy.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Xrash\n\nXrash is a CMake based cross-platform project for C++ sources, and also illustrate crash symbolicate within them.\n\nXrash supports Android, iOS, Windows, and Linux now.\n\n_Note, for iOS and Windows, CMake 3.17.2 is suggested_.\n\n## Android\n\nUse Gradle + CMake to build C++ sources, and save the unstripped `.so` libs, which are located inside `build/intermediates/cmake/release/obj`. Check `build_android.sh` for details. Note that you can build your sources with any NDK version.\n\n### logcat\n\nWhen crash happens, collect it from logcat like below:\n\n```bash\n2020-05-16 09:25:36.508 10259-10259/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n2020-05-16 09:25:36.508 10259-10259/? A/DEBUG: Build fingerprint: 'google/bullhead/bullhead:8.1.0/OPM6.171019.030.B1/4768815:user/release-keys'\n2020-05-16 09:25:36.508 10259-10259/? A/DEBUG: Revision: 'rev_1.0'\n2020-05-16 09:25:36.508 10259-10259/? A/DEBUG: ABI: 'arm64'\n2020-05-16 09:25:36.508 10259-10259/? A/DEBUG: pid: 10229, tid: 10229, name: y.crash.example  \u003e\u003e\u003e com.piasy.crash.example \u003c\u003c\u003c\n2020-05-16 09:25:36.508 10259-10259/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG: Cause: null pointer dereference\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG:     x0   0000000000000000  x1   0000000000000000  x2   0000000000000000  x3   0000007976ebea00\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG:     x4   0000007fd259c890  x5   000000796c088c32  x6   0000000000000000  x7   7f7f7f7f7f7f7f7f\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG:     x8   0000000000585859  x9   42af910898b7fabb  x10  0000000000000015  x11  00000000ffffffff\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG:     x12  0000007976e0d5e0  x13  5b9e86d03edc445b  x14  0000000000000000  x15  0000007960400000\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG:     x16  00000079fb22cca8  x17  00000079fb1c94b8  x18  000000796be6a820  x19  0000000000000000\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG:     x20  0000007976cf0d90  x21  0000007976ebea00  x22  0000007fd259c70c  x23  000000796c088c32\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG:     x24  0000000000000000  x25  00000079fbb38a40  x26  0000007976ebeaa0  x27  0000000000000000\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG:     x28  0000000000000000  x29  0000007fd259c460  x30  000000796098b6c8\n2020-05-16 09:25:36.509 10259-10259/? A/DEBUG:     sp   0000007fd259c450  pc   000000796098b6e8  pstate 0000000060000000\n2020-05-16 09:25:36.513 10259-10259/? A/DEBUG: backtrace:\n2020-05-16 09:25:36.513 10259-10259/? A/DEBUG:     #00 pc 00000000000006e8  /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so\n2020-05-16 09:25:36.513 10259-10259/? A/DEBUG:     #01 pc 00000000000006c4  /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so (testCrash()+40)\n2020-05-16 09:25:36.513 10259-10259/? A/DEBUG:     #02 pc 00000000000040b0  /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/oat/arm64/base.odex (offset 0x4000)\n```\n\nThen use `ndk-stack` in NDK r21 to symbolicate it, note that only `ndk-stack` need to be NDK r21, because older version's `ndk-stack` can't symblicate arm64 crash, you can build your sources with older NDK.\n\n```bash\nndk-stack -sym libs/android-unstripped/arm64-v8a -dump crash.txt\n```\n\nChoose the corresponding architecture of the crash, which is `arm64` in this case, as shown by `ABI: 'arm64'`.\n\nThe symbolicated stack should be:\n\n```bash\n********** Crash dump: **********\nBuild fingerprint: 'google/bullhead/bullhead:8.1.0/OPM6.171019.030.B1/4768815:user/release-keys'\n#00 0x00000000000006e8 /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so\nusePtr(int*)\n/Users/piasy/src/CrashSymbolicate/Android/.externalNativeBuild/cmake/release/arm64-v8a/../../../../../src/crash.cpp:14:15\n#01 0x00000000000006c4 /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so (testCrash()+40)\ntestCrash()\n/Users/piasy/src/CrashSymbolicate/Android/.externalNativeBuild/cmake/release/arm64-v8a/../../../../../src/crash.cpp:23:5\n#02 0x00000000000040b0 /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/oat/arm64/base.odex (offset 0x4000)\n```\n\nWe can see the file name and line number now.\n\n### crash report\n\nIf the crash report is collected by some crash report system, e.g. Bugly, then we can get stacktrace like this:\n\n```bash\n1 #00 pc 00000000000006e8  /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so\n2 #01 pc 00000000000006c4  /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so (testCrash()+40)\n3 #02 pc 00000000000040b0  /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/oat/arm64/base.odex (offset 0x4000)\n```\n\nWe can just insert two lines before it, make it looks like this:\n\n```bash\n*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\npid: 0, tid: 0\n1 #00 pc 00000000000006e8  /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so\n2 #01 pc 00000000000006c4  /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so (testCrash()+40)\n3 #02 pc 00000000000040b0  /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/oat/arm64/base.odex (offset 0x4000)\n```\n\n**Please note that there must be at least one space before the stack frame, i.e. `#00`, otherwise, it won't output anything.**\n\nThen it could be symbolicated with the same command we used earlier, the result should be:\n\n```bash\n********** Crash dump: **********\n#00 0x00000000000006e8 /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so\nusePtr(int*)\n/Users/piasy/src/CrashSymbolicate/Android/.externalNativeBuild/cmake/release/arm64-v8a/../../../../../src/crash.cpp:14:15\n#01 0x00000000000006c4 /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/lib/arm64/libcrash.so (testCrash()+40)\ntestCrash()\n/Users/piasy/src/CrashSymbolicate/Android/.externalNativeBuild/cmake/release/arm64-v8a/../../../../../src/crash.cpp:23:5\n#02 0x00000000000040b0 /data/app/com.piasy.crash.example-na2ugYuDMIIBetyZjBi90A==/oat/arm64/base.odex (offset 0x4000)\n```\n\n## iOS\n\nUse CMake + `xcodebuild` to build sources, and save `dSYM`, check `build_libs_ios.sh` for details.\n\n### device logs\n\nWhen crash happens, collect it from \"View Device Logs\", save it to `1.crash`, and put all `dSYM` with it in the same dir, then symbolicate with:\n\n```bash\n# cd into the dir containing 1.crash and all .dSYM\n/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/Current/Resources/symbolicatecrash 1.crash\n```\n\nThe un-symbolicated stack should be (only show several frames):\n\n```bash\nThread 0 name:  Dispatch queue: com.apple.main-thread\nThread 0 Crashed:\n0   crash                         \t0x000000010009ff54 0x100098000 + 32596\n1   crash                         \t0x000000010009ff30 0x100098000 + 32560\n2   CrashExample                  \t0x00000001000864b0 0x100080000 + 25776\n3   UIKitCore                     \t0x000000018ea0a36c 0x18e60d000 + 4182892\n4   UIKitCore                     \t0x000000018ea0ef20 0x18e60d000 + 4202272\n```\n\nThe symbolicated stack should be:\n\n```bash\nThread 0 name:  Dispatch queue: com.apple.main-thread\nThread 0 Crashed:\n0   crash                         \t0x000000010009ff54 usePtr(int*) + 32596 (crash.cpp:13)\n1   crash                         \t0x000000010009ff30 testCrash() + 32560 (crash.cpp:24)\n2   CrashExample                  \t0x00000001000864b0 0x100080000 + 25776\n3   UIKitCore                     \t0x000000018ea0a36c -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 104\n4   UIKitCore                     \t0x000000018ea0ef20 -[UIViewController loadViewIfRequired] + 952\n```\n\nWe can see the file name and line number now.\n\n**NOTE**: the symbolicate result is not correct, the first frame should be line 14, the second frame should be line 23, [read more at here](iOS-symbolicate-wrong-line.md).\n\n### crash report\n\nIf the crash report is collected by some crash report system, e.g. Bugly, then we can get stacktrace like this:\n\n```bash\n0   crash                         \t0x0000000100357f54 0x100350000 + 32596\n1   crash                         \t0x0000000100357f30 0x100350000 + 32560\n2   CrashExample                  \t0x000000010033e4b0 0x100338000 + 25776\n3   UIKitCore                     \t0x000000018ea0a36c 0x18e60d000 + 4182892\n```\n\nWe can use `xcrun` to symbolicate each line manually, but I write a Python script for it.\n\nSave the stacktrace to `2.crash`, and put all `dSYM` with it in the same dir, then symbolicate with:\n\n```bash\n# cd into the dir containing 2.crash and all .dSYM\npython3 symbolicatereport.py 2.crash arm64\n```\n\nChoose the corresponding architecture of the crash, which is arm64 in this case.\n\nThe result should be:\n\n```bash\n0 crash 0x0000000100357f54 usePtr(int*) (in crash) (crash.cpp:13)\n1 crash 0x0000000100357f30 testCrash() (in crash) (crash.cpp:24)\n2 CrashExample 0x000000010033e4b0 0x100338000 + 25776\n3 UIKitCore 0x000000018ea0a36c 0x18e60d000 + 4182892\n```\n\n### Xcode bt\n\nWhen we connect the device to computer and run app from Xcode, we can use `bt` command in lldb console, which looks like below (only show several frames):\n\n```bash\n* thread #50, queue = 'avencoder.capture', stop reason = breakpoint 1.1\n    frame #0: 0x00000001865abbb0 libsystem_malloc.dylib`malloc_error_break\n    frame #1: 0x00000001865b7b20 libsystem_malloc.dylib`malloc_vreport + 432\n    ...\n    frame #29: 0x000000018810b278 CoreImage`-[CIContext render:toCVPixelBuffer:] + 112\n    frame #30: 0x00000001037b7ef4 AwesomeFramework\n    ...\n```\n\nIt only contains address offset, we need to get base address using `image list` command in lldb console, which looks like below (only show several entries):\n\n```bash\n[  0] 6ECB0D69-5B54-32AA-93F8-2C72BF3A1A64 0x0000000102690000 /Users/user/Library/Developer/Xcode/DerivedData/AwesomeApp-glbfdxeftnvbsyfeehomifxmhlcb/Build/Products/Debug-iphoneos/AwesomeApp.app/AwesomeApp \n...\n[ 11] DFCB6ED9-5F0B-3F45-AE74-76F4A1E3F480 0x0000000103778000 /Users/user/Library/Developer/Xcode/DerivedData/AwesomeApp-glbfdxeftnvbsyfeehomifxmhlcb/Build/Products/Debug-iphoneos/AwesomeApp.app/Frameworks/AwesomeFramework.framework/AwesomeFramework \n...\n```\n\nWe can see the base address of a framework, e.g. `0x0000000103778000` for `AwesomeFramework.framework`.\n\nThen save the output of `bt` and `image list` to `bt.txt` and `image_list.txt`, and put all `dSYM` with it in the same dir, then symbolicate with:\n\n```bash\n# cd into the dir containing bt.txt, image_list.txt and all .dSYM\npython3 symbolicatexcode.py bt.txt image_list.txt arm64\n```\n\n## Windows\n\nUse CMake to build sources, ~~and save `.pdb` file~~, check `build_lib_windows.bat` for details. Use `MiniDumpWriteDump` from `DbgHelp` to write a minudump when crash happens, check `Win32Example/Win32Example.cpp` for details.\n\n`windbg` could analyze minidump with `!analyze -v` command, but it could only get the line number of the last frame, which isn't very helpful. After some googling, I didn't find how to get line number of all frames, so I decide to switch to `minidump_stackwalk`. To use `minidump_stackwalk`, we need convert `.pdb` to `.sym`, and save `.sym` file, check `build_lib_windows.bat` for details.\n\nI also create a Python script to help me calling `minidump_stackwalk` on macOS, note we can use `minidump_stackwalk` on macOS or Linux, we only need to convert `.pdb` to `.sym` on Windows.\n\nPut the `.dmp` and `.sym` in the same dir, then symbolicate with:\n\n```bash\n# cd into the dir containing .dmp and .sym\npython3 walk_stack.py \u003c.dmp file\u003e\n# if the output is too long, we can redirect all the output into files with\n# \u003e 1.crash 2\u003e\u00261\n```\n\nNote that `walk_stack.py` and `minidump_stackwalk` should be put in the same dir.\n\nThe result should be (only show several frames):\n\n```bash\nThread 0 (crashed)\n 0  crash.dll!static void usePtr(int *) [crash.cpp : 16 + 0x3]\n    eip = 0x708c1066   esp = 0x0136e910   ebp = 0x0136e910   ebx = 0x00e716a0\n    esi = 0x00c10612   edi = 0x00000111   eax = 0x00000000   ecx = 0x00000000\n    edx = 0x00000000   efl = 0x00010202\n    Found by: given as instruction pointer in context\n 1  crash.dll!testCrash() [crash.cpp : 23 + 0x9]\n    eip = 0x708c1044   esp = 0x0136e918   ebp = 0x0136e928\n    Found by: call frame info\n 2  Win32Example.exe + 0x1792\n    eip = 0x00e71792   esp = 0x0136e930   ebp = 0x0136e984\n    Found by: call frame info\n 3  user32.dll + 0x45cab\n    eip = 0x76d75cab   esp = 0x0136e98c   ebp = 0x0136e9b0\n    Found by: previous frame's frame pointer\n```\n\nWe can see the file name and line number now, we can ignore the `+ 0x` after the line number.\n\n## Linux\n\nUse CMake and make to build sources, add `-g` option in `CMakeLists.txt`, dump symbols using `dump_syms` from [breakpad](https://chromium.googlesource.com/breakpad/breakpad/), and save `.sym` file, check `build_lib_linux.sh` for details.\n\nUse `google_breakpad::ExceptionHandler` to catch crash and write minidump, check `LinuxExample/CrashExample.cpp` for details.\n\nWhen crash happens, we can symbolicate it in the same way as Windows.\n\nPut the `.dmp` and `.sym` in the same dir, then symbolicate with:\n\n```bash\n# cd into the dir containing .dmp and .sym\npython3 walk_stack.py \u003c.dmp file\u003e\n# if the output is too long, we can redirect all the output into files with\n# \u003e 1.crash 2\u003e\u00261\n```\n\nThe result should be (only show several frames):\n\n```bash\nThread 0 (crashed)\n 0  libcrash.so!usePtr [crash.cpp : 14 + 0x4]\n    rax = 0x0000000000000000   rdx = 0x0000000000000001\n    rcx = 0x00005592e78a1100   rbx = 0x0000000000000000\n    rsi = 0x0000000000000000   rdi = 0x0000000000000000\n    rbp = 0x00007ffd1c4c91b0   rsp = 0x00007ffd1c4c91b0\n     r8 = 0x0000000000000000    r9 = 0x0000000000000000\n    r10 = 0x00005592e788b010   r11 = 0x0000000000000000\n    r12 = 0x00005592e66d5360   r13 = 0x00007ffd1c4c9460\n    r14 = 0x0000000000000000   r15 = 0x0000000000000000\n    rip = 0x00007f8d674c56fc\n    Found by: given as instruction pointer in context\n 1  libcrash.so!testCrash() [crash.cpp : 23 + 0xc]\n    rbx = 0x0000000000000000   rbp = 0x00007ffd1c4c91d0\n    rsp = 0x00007ffd1c4c91c0   r12 = 0x00005592e66d5360\n    r13 = 0x00007ffd1c4c9460   r14 = 0x0000000000000000\n    r15 = 0x0000000000000000   rip = 0x00007f8d674c5755\n    Found by: call frame info\n 2  CrashExample + 0x2560\n    rbx = 0x0000000000000000   rbp = 0x00007ffd1c4c9380\n    rsp = 0x00007ffd1c4c91e0   r12 = 0x00005592e66d5360\n    r13 = 0x00007ffd1c4c9460   r14 = 0x0000000000000000\n    r15 = 0x0000000000000000   rip = 0x00005592e66d5560\n    Found by: call frame info\n 3  CrashExample + 0x246a\n    rbp = 0x00007ffd1c4c9380   rsp = 0x00007ffd1c4c9290\n    rip = 0x00005592e66d546a\n    Found by: stack scanning\n```\n\nWe can see the file name and line number now, we can ignore the `+ 0x` after the line number.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiasy%2Fxrash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiasy%2Fxrash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiasy%2Fxrash/lists"}