Kscrash: ์ž„๋ฒ ๋””๋“œ ํ”„๋ ˆ์ž„์›Œํฌ์˜ C++ ์˜ˆ์™ธ์— ๋Œ€ํ•œ ์ž˜๋ชป๋œ ์Šคํƒ ์ถ”์ 

์— ๋งŒ๋“  2017๋…„ 02์›” 20์ผ  ยท  12์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: kstenerud/KSCrash

์ž„๋ฒ ๋””๋“œ ํ”„๋ ˆ์ž„์›Œํฌ(์˜ˆ: Crash-Tester ์•ฑ์˜ CrashLib)์—์„œ C++ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด KSCrashMonitor_CPPException.c์˜ __cxa_throw ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ œ๊ฒŒ๋Š” ๋ชจ๋“  ์ž„๋ฒ ๋””๋“œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ KSCrash์˜ ๊ตฌํ˜„์ด ์•„๋‹Œ libc++์˜ __cxa_throw๋ฅผ ํ•ญ์ƒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

์ถ”๊ฐ€๋กœ: ํฌํ•จ๋œ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ C++ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด stackCursor->advanceCursor๊ฐ€ KSCrashReport.c:writeBacktrace()์—์„œ NULL๊ณผ ๊ฐ™์œผ๋ฏ€๋กœ ๋ณด๊ณ  ์ค‘์— KSCrash๊ฐ€ ์ถฉ๋Œํ•ฉ๋‹ˆ๋‹ค.

ํŽธ์ง‘: ๋ณด๊ณ  ์ค‘ KSCrash ์ถฉ๋Œ ์ •๋ณด๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ถ”๊ฐ€ ์กฐ์‚ฌ ํ›„ ๋‚ด ์ด์ „ ์˜๊ฒฌ์ด ์ž˜๋ชป๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” _"KSCrash์™€ ์ •์ ์œผ๋กœ ๋งํฌ๋˜์ง€ ์•Š์€ ์ด๋ฏธ์ง€์—์„œ ๋ฐœ์ƒํ•œ C++ ์˜ˆ์™ธ์— ๋Œ€ํ•œ ์Šคํƒ ์ถ”์  ๋ˆ„๋ฝ"_๊ณผ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

KSCrash๊ฐ€ ๊ธฐ๋ณธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋งํฌ๋˜๋Š” ๊ฒฝ์šฐ:

  • MyApplication ( main.o , libKSCrash.a )

    • libDynamicLibrary.dylib ( lib.o )

    • /usr/lib/libc++abi.dylib

MyApplication ์—์„œ ๋ฐœ์ƒํ•œ ๋ชจ๋“  ์˜ˆ์™ธ๋Š” libKSCrash.a::__cxa_throw ์ž…๋ ฅ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ libKSCrash.a ๋Š” __cxa_throw ๋ฅผ weak $๋กœ ์„ ์–ธํ•˜๋ฏ€๋กœ $ main.o ์— ์ž์ฒด __cxa_throw ๊ฐ€ ์žˆ์œผ๋ฉด $ MyApplication ์—ฐ๊ฒฐ์ด ์‹คํŒจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. __cxa_throw ์žฌ์ •์˜. ์—ฌํƒœ๊นŒ์ง€๋Š” ๊ทธ๋Ÿฐ๋Œ€๋กœ ์ž˜๋๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ์—์„œ ๊ด€์ฐฐํ–ˆ๋“ฏ์ด libDynamicLibrary.dylib libKSCrash.a::__cxa_throw ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š์œผ๋ฉฐ /usr/lib/libc++abi.dylib::__cxa_throw ๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค.

KSCrash๊ฐ€ ๋ฉ”์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋งํฌ๋œ ๊ฒฝ์šฐ:

  • MyApplication ( main.o )

    • libKSCrash.dylib

    • /usr/lib/libc++abi.dylib

    • libDynamicLibrary.dylib ( lib.o )

    • /usr/lib/libc++abi.dylib

MyApplication ์—์„œ ๋ฐœ์ƒํ•œ ๋ชจ๋“  ์˜ˆ์™ธ๋Š” libKSCrash.dylib::__cxa_throw ์— ๋“ค์–ด๊ฐ€์ง€๋งŒ ๋‹ค์Œ ๊ฒฝ์šฐ์—๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  1. __cxa_throw ์„ libKSCrash.dylib ์—์„œ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.
  2. __cxa_throw ์€(๋Š”) weak ๋กœ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

__cxa_throw ๊ฐ€ weak ( 0000000000002e90 (__TEXT,__text) weak external ___cxa_throw )๋กœ ํ‘œ์‹œ๋œ ๊ฒฝ์šฐ libKSCrash.dylib ๋งํฌํ•  ๋•Œ ๋ง์ปค๋Š” /usr/lib/libc++abi.dylib , -weak __cxa_throw , libKSCrash.dylib::__cxa_throw ๋Š” ๋ฌด์‹œํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒฐ๋ก ์„ ๋‚ด๋ฆฝ๋‹ˆ๋‹ค. MyApplication ์—์„œ ์‹คํ–‰ ์‹œ๊ฐ„ ๊ธฐํ˜ธ ์กฐํšŒ ์ค‘์— libKSCrash.dylib::__cxa_throw ๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ weak ์†์„ฑ์ด KSCrash๋ฅผ ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋นŒ๋“œํ•  ๋•Œ๋งŒ ์กฐ๊ฑด๋ถ€๋กœ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ๋ฏฟ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ ์‚ฌ์šฉ ์‚ฌ๋ก€์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ libDynamicLibrary.dylib libKSCrash.dylib::__cxa_throw ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š๊ณ  $ /usr/lib/libc++abi.dylib::__cxa_throw ๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” __cxa_throw ์— ๋Œ€ํ•œ ์ •์˜๋˜์ง€ ์•Š์€ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š” ๋กœ๋“œ๋œ ์ด๋ฏธ์ง€์˜ ์ผ๋ถ€ ์ €์ˆ˜์ค€ ๋Ÿฐํƒ€์ž„ ํŒจ์น˜ ๋กœ ์ž ์žฌ์ ์œผ๋กœ ์ˆ˜์ •๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์‚ฌ์—์„œ ์ฐธ์กฐํ•œ ํ…Œ์ŠคํŠธ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ธฐ์ˆ ์ด ์‹ค์ œ๋กœ __cxa_throw ์—์„œ๋„ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

cooked_throw

๋ชจ๋“  12 ๋Œ“๊ธ€

์ด๊ฒƒ์— ํ–‰์šด์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋‚ด ์•ฑ์— KSCrash๋ฅผ ํ†ตํ•ฉํ•˜๋ ค๊ณ  ํ•˜๋Š”๋ฐ ์ž„๋ฒ ๋””๋“œ ํ”„๋ ˆ์ž„์›Œํฌ ๋•Œ๋ฌธ์— ๋ฉˆ์ท„์Šต๋‹ˆ๋‹ค.
์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฉด ์•Œ๋ ค์ฃผ์„ธ์š”.

์šด์ด ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ €๋Š” ๊ทธ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ๋ฏฟ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ ์–ด๋„ ์šฐ๋ฆฌ์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ƒํ™ฉ์— ๋Œ€ํ•œ ๋‚˜์˜ ์ดํ•ด์ž…๋‹ˆ๋‹ค.

KSCrash๊ฐ€ ์Šคํƒ ์ถ”์ ์„ ๊ธฐ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์€ libc++์— ์˜ํ•ด ํ•ด์ œ๋˜๊ธฐ ์ „์— ์Šคํƒ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค๋ฅผ ํ—ˆ์šฉํ•˜๋Š” __cxa_throw์˜ ์ž์ฒด ๊ตฌํ˜„์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ง์ปค๊ฐ€ libc++์—์„œ ๊ตฌํ˜„ํ•˜๋Š” ๋Œ€์‹  KSCrash์—์„œ __cxa_throw๋ฅผ ์ฐพ์•„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— KSCrash๊ฐ€ C++ ์ฝ”๋“œ์™€ ์ •์ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ๋Š” ํ•œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ libc++์— ๋งํฌ๋˜๋Š” ์ž„๋ฒ ๋””๋“œ ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๊ฒฝ์šฐ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ KSCrash์˜ ์ฝ”๋“œ์— ๋Œ€ํ•ด ์•Œ์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— libc++์˜ __cxa_throw ๊ตฌํ˜„์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ž„๋ฒ ๋””๋“œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์ด ์žˆ์„ ์ˆ˜ ์žˆ์ง€๋งŒ ์ด ์‚ฌ์šฉ ์‚ฌ๋ก€์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์ฑ…์„ ์ฐพ์œผ๋ฉด ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค.

์ž„๋ฒ ๋””๋“œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์„ ๊ณ ์น  ๋ฐฉ๋ฒ•์ด ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋‚˜๋Š” ๋˜ํ•œ PLCrashReporter์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ KSCrash๊ฐ€ ์ตœ์†Œํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ์—์„œ throw๋œ C++ ์˜ˆ์™ธ๋ฅผ ํฌ์ฐฉํ•˜๊ธฐ ์œ„ํ•ด ์ด์ƒ์ ์œผ๋กœ ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋นŒ๋“œ๋˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์—ฐ๊ฒฐ๋˜์–ด์•ผ ํ•จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ?

๊ทธ๋Ÿฌ๋‚˜ ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ @pdrtrifork ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดํ•ดํ•˜๋ฉด KSCrash๊ฐ€ ํฌ์ฐฉํ•˜์ง€ ๋ชปํ•œ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋‚ด์žฅ๋œ ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ œ์–ดํ•˜๋Š” โ€‹โ€‹๊ฒฝ์šฐ ๊ณต์œ  KSCrash ์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ์ฐธ์กฐํ•˜๋Š” __cxa_throw ์Šคํ…์„ ์‚ฌ์šฉํ•˜์—ฌ ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

ํ•˜, ๊ทธ๋ž˜์„œ ์ด๊ฒƒ์„ ์กฐ์‚ฌํ•˜๋ฉด์„œ ๋‚˜๋Š” http://stackoverflow.com/questions/36846628/conditionally-overriding-cxa-throw ์— ์ด๋ฅด๋ €์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์šฐ๋ฆฌ ์ž์‹ ์˜ @kstenerud ์— ์˜ํ•ด ์—ด๋ ธ์Šต๋‹ˆ๋‹ค ๐Ÿ˜„

์–ด์จŒ๋“  PR #219๋Š” ์ตœ์†Œํ•œ ์ถฉ๋Œ ๋ณด๊ณ  ์ค‘์— ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@kstenerud ์ œ ์ƒ๊ฐ์—๋Š” ์ด ๋ฌธ์ œ์˜ ์ด๋ฆ„์„ _"KSCrash์™€ ์ •์ ์œผ๋กœ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ ์ด๋ฏธ์ง€์—์„œ ๋ฐœ์ƒํ•œ C++ ์˜ˆ์™ธ์— ๋Œ€ํ•œ ์Šคํƒ ์ถ”์  ๋ˆ„๋ฝ"_๊ณผ ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ์ด๋ฆ„์„ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๊ฐ€ ๋งํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ __cxa_throw ์žฌ์ •์˜๋Š” KSCrash์™€ ๋™์ผํ•œ ์ด๋ฏธ์ง€์—์„œ๋งŒ ์ž‘๋™ํ•˜๋ฏ€๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • KSCrash๊ฐ€ ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋นŒ๋“œ๋˜๊ณ  ๊ธฐ๋ณธ ์•ฑ์— ๋งํฌ๋œ ๊ฒฝ์šฐ ๊ธฐ๋ณธ ์•ฑ์—์„œ ์˜ˆ์™ธ๊ฐ€ throw๋˜๋ฉด C++ ์˜ˆ์™ธ ์—ญ์ถ”์ ์ด ๋ฐœ์ƒํ•˜์ง€๋งŒ ๋™์ ์œผ๋กœ ๋กœ๋“œ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ throw๋  ๋•Œ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • KSCrash๊ฐ€ ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋นŒ๋“œ๋˜๊ณ  ๋™์ (๋ž˜ํผ) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋งํฌ๋œ ๊ฒฝ์šฐ ํ•ด๋‹น ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์˜ˆ์™ธ๊ฐ€ throw๋˜๋ฉด C++ ์˜ˆ์™ธ ์—ญ์ถ”์ ์ด ๋ฐœ์ƒํ•˜์ง€๋งŒ ๊ธฐ๋ณธ ์•ฑ์ด๋‚˜ ๋™์ ์œผ๋กœ ๋กœ๋“œ๋œ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ throw๋  ๋•Œ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • KSCrash๊ฐ€ ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(ํ”„๋ ˆ์ž„์›Œํฌ)๋กœ ๋นŒ๋“œ๋œ ๊ฒฝ์šฐ KSCrash์—์„œ ์˜ˆ์™ธ๊ฐ€ throw๋˜๋ฉด C++ ์˜ˆ์™ธ ์—ญ์ถ”์ ์ด ๋ฐœ์ƒํ•˜์ง€๋งŒ ๊ธฐ๋ณธ ์•ฑ ๋˜๋Š” ๊ธฐํƒ€ ๋™์ ์œผ๋กœ ๋กœ๋“œ๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ throw๋  ๋•Œ๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํ›„์ž๋Š” sentry-swift , https://docs.sentry.io/clients/cocoa/ ์™€ ๊ฐ™์€ ํด๋ผ์ด์–ธํŠธ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋ฉฐ, ์ด๋Š” KSCrash๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ์กฐ์‚ฌ ํ›„ ๋‚ด ์ด์ „ ์˜๊ฒฌ์ด ์ž˜๋ชป๋œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” _"KSCrash์™€ ์ •์ ์œผ๋กœ ๋งํฌ๋˜์ง€ ์•Š์€ ์ด๋ฏธ์ง€์—์„œ ๋ฐœ์ƒํ•œ C++ ์˜ˆ์™ธ์— ๋Œ€ํ•œ ์Šคํƒ ์ถ”์  ๋ˆ„๋ฝ"_๊ณผ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

KSCrash๊ฐ€ ๊ธฐ๋ณธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋งํฌ๋˜๋Š” ๊ฒฝ์šฐ:

  • MyApplication ( main.o , libKSCrash.a )

    • libDynamicLibrary.dylib ( lib.o )

    • /usr/lib/libc++abi.dylib

MyApplication ์—์„œ ๋ฐœ์ƒํ•œ ๋ชจ๋“  ์˜ˆ์™ธ๋Š” libKSCrash.a::__cxa_throw ์ž…๋ ฅ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ libKSCrash.a ๋Š” __cxa_throw ๋ฅผ weak $๋กœ ์„ ์–ธํ•˜๋ฏ€๋กœ $ main.o ์— ์ž์ฒด __cxa_throw ๊ฐ€ ์žˆ์œผ๋ฉด $ MyApplication ์—ฐ๊ฒฐ์ด ์‹คํŒจํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. __cxa_throw ์žฌ์ •์˜. ์—ฌํƒœ๊นŒ์ง€๋Š” ๊ทธ๋Ÿฐ๋Œ€๋กœ ์ž˜๋๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด ๋ฒ„๊ทธ ๋ณด๊ณ ์„œ์—์„œ ๊ด€์ฐฐํ–ˆ๋“ฏ์ด libDynamicLibrary.dylib libKSCrash.a::__cxa_throw ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š์œผ๋ฉฐ /usr/lib/libc++abi.dylib::__cxa_throw ๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค.

KSCrash๊ฐ€ ๋ฉ”์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋™์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋งํฌ๋œ ๊ฒฝ์šฐ:

  • MyApplication ( main.o )

    • libKSCrash.dylib

    • /usr/lib/libc++abi.dylib

    • libDynamicLibrary.dylib ( lib.o )

    • /usr/lib/libc++abi.dylib

MyApplication ์—์„œ ๋ฐœ์ƒํ•œ ๋ชจ๋“  ์˜ˆ์™ธ๋Š” libKSCrash.dylib::__cxa_throw ์— ๋“ค์–ด๊ฐ€์ง€๋งŒ ๋‹ค์Œ ๊ฒฝ์šฐ์—๋งŒ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  1. __cxa_throw ์„ libKSCrash.dylib ์—์„œ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค.
  2. __cxa_throw ์€(๋Š”) weak ๋กœ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

__cxa_throw ๊ฐ€ weak ( 0000000000002e90 (__TEXT,__text) weak external ___cxa_throw )๋กœ ํ‘œ์‹œ๋œ ๊ฒฝ์šฐ libKSCrash.dylib ๋งํฌํ•  ๋•Œ ๋ง์ปค๋Š” /usr/lib/libc++abi.dylib , -weak __cxa_throw , libKSCrash.dylib::__cxa_throw ๋Š” ๋ฌด์‹œํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒฐ๋ก ์„ ๋‚ด๋ฆฝ๋‹ˆ๋‹ค. MyApplication ์—์„œ ์‹คํ–‰ ์‹œ๊ฐ„ ๊ธฐํ˜ธ ์กฐํšŒ ์ค‘์— libKSCrash.dylib::__cxa_throw ๋Š” ๋ฌด์‹œ๋ฉ๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ weak ์†์„ฑ์ด KSCrash๋ฅผ ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋นŒ๋“œํ•  ๋•Œ๋งŒ ์กฐ๊ฑด๋ถ€๋กœ ์ถ”๊ฐ€๋˜์–ด์•ผ ํ•œ๋‹ค๊ณ  ๋ฏฟ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

์ฒซ ๋ฒˆ์งธ ์‚ฌ์šฉ ์‚ฌ๋ก€์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ libDynamicLibrary.dylib libKSCrash.dylib::__cxa_throw ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š๊ณ  $ /usr/lib/libc++abi.dylib::__cxa_throw ๋กœ ๋๋‚ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋Š” __cxa_throw ์— ๋Œ€ํ•œ ์ •์˜๋˜์ง€ ์•Š์€ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š” ๋กœ๋“œ๋œ ์ด๋ฏธ์ง€์˜ ์ผ๋ถ€ ์ €์ˆ˜์ค€ ๋Ÿฐํƒ€์ž„ ํŒจ์น˜ ๋กœ ์ž ์žฌ์ ์œผ๋กœ ์ˆ˜์ •๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์‚ฌ์—์„œ ์ฐธ์กฐํ•œ ํ…Œ์ŠคํŠธ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ๊ธฐ์ˆ ์ด ์‹ค์ œ๋กœ __cxa_throw ์—์„œ๋„ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

cooked_throw

๋‚ด ์•ฑ์˜ ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ์ถฉ๋Œ์„ ํ™•์ธํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ถฉ๋Œ ๋กœ๊ทธ๋ฅผ ์–ป์œผ๋ ค๊ณ  ํ•˜๋ฉด ์Šคํƒ ์ถ”์ ์— ์‹ค์ œ ์ถฉ๋Œ์ด ํ‘œ์‹œ๋˜์ง€ ์•Š๊ณ  ๋Œ€์‹  KSCrash๊ฐ€ ์ถฉ๋Œํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ™์€ ๋ฌธ์ œ์ธ๊ฐ€์š”?

์Šค๋ ˆ๋“œ 0 ์ถฉ๋Œ:
0 libsystem_kernel.dylib 0x0000000181cc5348 0x181ca4000 + 136008 (__pthread_kill + 8)
1 libsystem_pthread.dylib 0x0000000181ddd7a4 0x181dd6000 + 30628 ( + 360)
2 libsystem_c.dylib 0x0000000181c34fd8 0x181bd2000 + 405464 (์ค‘๋‹จ + 140)
3 libc++abi.dylib 0x0000000181698068 0x181696000 + 8296 ( + 132)
4 libc++abi.dylib 0x0000000181698210 0x181696000 + 8720 ( + 304)
5 libobjc.A.dylib 0x00000001816c0810 0x1816b8000 + 34832 ( + 124)
6 KSCrash 0x00000001054a0590 0x10549c000 + 17808 (kscm_cppexception_getAPI + 280)
7 libc++abi.dylib 0x00000001816b054c 0x181696000 + 107852 ( + 16)
8 libc++abi.dylib 0x00000001816b0158 0x181696000 + 106840 (__cxa_rethrow + 144)
9 libobjc.A.dylib 0x00000001816c06e8 0x1816b8000 + 34536 (objc_exception_rethrow + 44)
10 CoreFoundation 0x0000000182072344 0x18206a000 + 33604 (CFRunLoopRunSpecific + 544)
11 ๊ทธ๋ž˜ํ”ฝ ์„œ๋น„์Šค 0x0000000183f03f84 0x183ef9000 + 44932(GSEventRunModal + 100)
12 UIKit 0x000000018b61e880 0x18b5ab000 + 473216 (UIApplicationMain + 208)

@torarnv ์•ˆ๋…•ํ•˜์„ธ์š”, ์„ฑ๊ณต์ ์ธ mach-o-hook ๋ฐ๋ชจ๋ฅผ ๊ณต์œ ํ•ด ์ฃผ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? mach_hook __cxa_throw๋ฅผ ์‹œ๋„ํ•  ๋•Œ EXC_BAD_ACCESS๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

void ter_handler(){
    printf("custom handler\n");
}

void test(){
    throw std::runtime_error("test function");
}

static void (*orig_throw)(void * thrown_exception, std::type_info *tinfo, void (*dest)(void *));

void hooked_throw(void * thrown_exception, std::type_info *tinfo, void (*dest)(void *)){
    printf("hooked_throw...\n");
    return orig_throw(thrown_exception, tinfo, dest);
}

int main(int argc, char * argv[])
{
    <strong i="5">@autoreleasepool</strong> {

        struct rebinding binds[1];
        struct rebinding bind1 = {"__cxa_throw", (void *)hooked_throw, (void **)&orig_throw};
        binds[0] = bind1;
        rebind_symbols(binds, 1);

        std::set_terminate(ter_handler);
        try {
            throw std::runtime_error("test error");
        }
        catch (...){
            printf  ("catch exception\n");
        }

        test();
    }
}

์ด๊ฒƒ์„ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค ... ํ–‰์šด์„ ๋น•๋‹ˆ๋‹ค

๋‚˜๋Š” KSCrash์™€ ํ•˜๋‚˜์˜ ์ถฉ๋Œ์„ ๋งŒ๋‚ฉ๋‹ˆ๋‹ค.
kscrash

๊ทธ๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•?

์œ„์—์„œ ์–ธ๊ธ‰ํ•œ @huakucha : #375 ๋™์  ํ›„ํฌ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” PR์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰