๋ฐ˜์‘ํ˜•

์Šคํƒ ํ’€๊ธฐ(Stack Unwinding)๋ž€?

์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ํ•จ์ˆ˜์—์„œ ์˜ˆ์™ธ๊ฐ€ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์œผ๋ฉด, ์ƒ์œ„ ํ•จ์ˆ˜๋กœ ๋Œ์•„๊ฐ€ ์˜ˆ์™ธ๊ฐ€ ์ฒ˜๋ฆฌ๋˜๊ธฐ๋ฅผ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ, ์ƒ์œ„ ํ•จ์ˆ˜์—๋„ ์—†๋‹ค๋ฉด ๋‹ค์‹œ ๊ทธ ์œ„์˜ ์ƒ์œ„ ํ•จ์ˆ˜๋กœ ๋Œ์•„๊ฐ€๋ฉฐ ๋ฐ˜๋ณตํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ, ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋Š”๋ฐ ์–ด๋Š ๊ณณ์—์„œ๋„ try-catch ๋ฌธ์ด ์—†๋‹ค๋ฉด ํ”„๋กœ๊ทธ๋žจ์€ ์ข…๋ฃŒ๋˜๊ณ  ๋ง™๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ์ด์ „์— ํ˜ธ์ถœ๋œ ํ•จ์ˆ˜๋กœ ๊ณ„์† ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ์„ ์Šคํƒ ํ’€๊ธฐ(Stack Unwinding)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์˜ ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

namespace ExamException
{
class Program
{
static void func1()
{
func2();
}
static void func2()
{
func3();
}
static void func3()
{
throw new Exception("์˜ˆ์™ธ ๋ฐœ์ƒ!");
}
static void Main(string[] args)
{
func1();
}
}
}

Main ํ•จ์ˆ˜์—์„œ func1()์„ ํ˜ธ์ถœํ•˜๋ฉด, func2(), func3()์ด ์ฐจ๋ก€๋Œ€๋กœ ํ˜ธ์ถœ๋˜๊ณ , func3()์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ง€์ ์— Break point๋ฅผ ์ง€์ •ํ•˜๊ณ , ๋””๋ฒ„๊น…์„ ์‹คํ–‰ํ•œ ํ›„ ๋น„์ฃผ์–ผ ์ŠคํŠœ๋””์˜ค์˜ ํ˜ธ์ถœ ์Šคํƒ(Call Stack) ์ฐฝ์„ ์—ด์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

ํ˜ธ์ถœ ์Šคํƒ ํ™”๋ฉด
ํ˜ธ์ถœ ์Šคํƒ ํ™”๋ฉด

ํ˜ธ์ถœ ์Šคํƒ ๋งจ ์•„๋ž˜์— Main ํ•จ์ˆ˜๋ฅผ ์‹œ์ž‘์œผ๋กœ, ์ฐจ๋ก€๋Œ€๋กœ func1(), func2(), func3()์ด ๊ธฐ๋ก๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ์Šคํƒ์— ์Œ“์—ฌ์žˆ๋Š” ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ ๋ชฉ๋ก์ด๋ฉฐ, func3()์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์œผ๋‹ˆ try-catch์— ๋„๋‹ฌํ•  ๋•Œ๊นŒ์ง€ func2(), func1(), Main ํ•จ์ˆ˜๊นŒ์ง€ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ์ด์ฃ . ์ด๊ฒƒ์„ ์Šคํƒ ํ’€๊ธฐ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์Šคํƒ์ด ์Œ“์ด๊ณ  ํ’€๋ฆฌ๋Š” ๊ณผ์ •
์Šคํƒ์ด ์Œ“์ด๊ณ  ํ’€๋ฆฌ๋Š” ๊ณผ์ •

 

์˜ˆ์™ธ์™€ ํ”„๋กœ๊ทธ๋žจ ์„ฑ๋Šฅ ์˜ํ–ฅ

์œ„์—์„œ ์–ธ๊ธ‰ํ•œ ๋Œ€๋กœ, ์Šคํƒ์„ ํ‘ธ๋Š” ๊ณผ์ •์—์„œ Stack Trace์™€ ๊ฐ™์€ ์˜ˆ์™ธ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๋‹ค ๋ณด๋‹ˆ, ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์˜ค๋ฒ„ํ—ค๋“œ(Overhaed)๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ์˜ˆ์™ธ ๋น„์šฉ(Exception cost)์ด๋ผ๊ณ ๋„ ๋ถ€๋ฆ…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์„œ ์˜คํ•ด์˜ ์†Œ์ง€๊ฐ€ ์žˆ๋Š”๋ฐ์š”. ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•ญ์ƒ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ฆ‰, try-catch ๋ธ”๋ก์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ญ์ƒ ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

์‚ฌ์‹ค try-catch ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์œผ๋ฉด ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๊ฑฐ์˜ ์—†๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์„ฑ๋Šฅ ๊ฒ€์ฆ์€ ๊ตฌ๊ธ€๋ง์„ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์ฐพ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://pspdfkit.com/blog/2020/performance-overhead-of-exceptions-in-cpp/

 

Investigating the Performance Overhead of C++ Exceptions | PSPDFKit

C++ exceptions have their place, but using an alternative is recommended for general program flow control.

pspdfkit.com

https://yesarang.tistory.com/371

 

C++ ์ด์•ผ๊ธฐ ์„œ๋ฅธ๋‘๋ฒˆ์งธ: ์˜ˆ์™ธ๊ฐ€ ์„ฑ๋Šฅ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ

2009/09/25 - [S/W๊ฐœ๋ฐœ/C++ ์ด์•ผ๊ธฐ] - C++ ์ด์•ผ๊ธฐ ์„œ๋ฅธํ•œ๋ฒˆ์งธ: ์™œ ์˜ˆ์™ธ๋ฅผ ์“ฐ๋Š” ๊ฒŒ ์ข‹์„๊นŒ์š”? ์—์„œ ์™œ ์˜ˆ์™ธ๋ฅผ ์“ฐ๋Š” ๊ฒƒ์ด ์ข‹์€์ง€์— ๋Œ€ํ•ด ์–˜๊ธฐ๋ฅผ ํ•ด ๋ดค์Šต๋‹ˆ๋‹ค. ์ •๋ฆฌํ•ด์„œ ๋ง์”€๋“œ๋ฆฌ์ž๋ฉด ๊ฒฐํ•จ๋‚ด์„ฑ ํŠน์„ฑ(fault-tol

yesarang.tistory.com

๊ฒฐ๋ก 

๋ถ„๋ช…ํžˆ try-catch ๋ฌธ์„ ์‚ฌ์šฉํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ฐ€ ์—๋Ÿฌ ์ฝ”๋“œ ๋ฐ˜ํ™˜ํ˜• ๋ณด๋‹ค๋Š” ๋” ๊ฐ€๋…์„ฑ ์žˆ๊ณ  ๊ฒฌ๊ณ ํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๋ ‡๋‹ค๊ณ  ๋ฌด๋ถ„๋ณ„ํ•˜๊ฒŒ ๋ชจ๋“  ๊ณณ์— try-catch๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค๊ฐ„ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ๊ฒช๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ์˜ˆ์ƒ์ด ๋˜๋Š” ๊ณณ์—๋Š” ์กฐ๊ฑด ๋ฌธ์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ , ์˜ˆ์ƒ์ด ๋˜์ง€ ์•Š๋Š” ๊ณณ์— try-catch๋ฅผ ๋ณตํ•ฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•