- ¸Þ¸ð¸® µð¹ö±× ÄÚµå
- °£´ÜÇÑ ÄÄÆÄÀÏ Å¸ÀÓ ¾î¼Æ®
- ½ºÅà ¿À¹öÇÃ·Î¿ì ¹ß»ý½Ã ´ýÇÁ ±â·ÏÇϱâ
- »ý¼ºÀÚ ¹× ¼Ò¸êÀÚ ³»ºÎ¿¡¼´Â °¡»ó ÇÔ¼ö°¡ Á¦´ë·Î È£ÃâµÇÁö ¾Ê´Â´Ù
- µð¹ö±ëÀ» À§ÇÑ ÀÚÀßÇÑ ÇÔ¼öµé (Visual C++)
- ½º·¹µå¿¡ À̸§ ºÙÀ̱â (Visual C++)
- Critical Section¿¡ ¶ôÀ» °Ç ½º·¹µå ¾Ë¾Æ³»±â (Visual C++)
- ¼ø¼
- ¾Ë¾ÆµÑ Á¡
- ÄݽºÅÃÀÌ ³ª¿ÀÁö ¾Ê°Å³ª ÀÌ»óÇÑ °æ¿ì (Visual C++)
- µð¹ö±× ½Éº¼ÀÌ ¾ø´Â °æ¿ì
- À߸øµÈ OS ½Éº¼
- ¾î¼Àºí¸®¾î·Î ¸¸µé¾îÁø ÇÔ¼ö
- ½ºÅà ÀÚü°¡ ¿À¿°µÈ °æ¿ì
- À߸øµÈ ESP/EIP ·¹Áö½ºÅÍ °ª
- ÇÔ¼ö ÇÕÄ¡±â (Linker COMDAT folding)
- ¿¹¿Ü¸¦ ¸¸µéÁö ¾Ê°í, ±×³É »ç¶óÁö´Â ÇÁ·Î¼¼½º (Visual C++)
- À߸øµÈ ¿¹¿Ü ó¸®
- try-except ±¸¹®¿¡¼ ¿¹¿Ü ÇÊÅÍ ºÎºÐ ¾È¿¡¼ ¿¹¿Ü¸¦ ´øÁö´Â °æ¿ì
- À߸øµÈ ¿¹¿Ü ó¸® Çڵ鷯¸¦ ¼³Á¤ÇÑ °æ¿ì
- ½ºÅà ¿À¹öÇ÷ο츦 À߸ø ó¸®ÇÏ´Â °æ¿ì
- ¹«ÇÑ ·çÇÁ
- Á¤»óÀûÀÎ ÇÁ·Î¼¼½º Á¾·á
- ¿¡·¯ÄÚµå ¹®ÀÚ¿·Î º¯È¯Çϱâ
- ¸µÅ©
1 ¸Þ¸ð¸® µð¹ö±× ÄÚµå
VisualCpp ¸Þ¸ð¸® ÄÚµå
| °ª | ÀÇ¹Ì |
| 0xCD, 0xCDCDCDCD | ÃÖÃÊ·Î ÇÒ´çµÈ ¸Þ¸ð¸® |
| 0xFD, 0xFDFDFDFD | À¯Àú°¡ ÇÒ´çÇÑ ¸Þ¸ð¸® µÚ¿¡ ºÙ´Â ¹Ù¿îµå üũ¿ë ¸Þ¸ð¸® |
| 0xDD, 0xDDDDDDDD | »èÁ¦µÈ ¸Þ¸ð¸®. _CRTDBG_DELAY_FREE_MEM_DF Ç÷¡±× °ªÀÌ´Ù. |
| 0xCC, 0xCCCCCCCC | ÃʱâȵÇÁö ¾ÊÀº Áö¿ª º¯¼ö. /GX ¿É¼ÇÀ» ÄÑ¾ß ÇÑ´Ù. |
| 0xABABABAB | LocalAlloc ÇÔ¼ö·Î ÇÒ´çÇÑ ¸Þ¸ð¸® µÚ¿¡ ºÙ´Â ¹Ù¿îµå üũ¿ë ¸Þ¸ð¸® |
| 0xBAADF00D | LocalAlloc ÇÔ¼ö·Î ÇÒ´çÇÑ ¸Þ¸ð¸® |
| 0xFEEEFEEE | HeapAlloc ÇÔ¼ö¸¦ À§ÇØ È®º¸´Â ÇØ³ùÀ¸³ª, ¾ÆÁ÷ ½ÇÁ¦·Î ÇÒ´çµÇÁö´Â ¾ÊÀº ¸Þ¸ð¸®. ¶Ç´Â HeapFree ÇÔ¼ö¸¦ ÅëÇØ ÇØÁ¦µÈ ¸Þ¸ð¸® |
2 °£´ÜÇÑ ÄÄÆÄÀÏ Å¸ÀÓ ¾î¼Æ®
#if defined (NDEBUG)
#define StaticAssert(expr) ((void)0)
#else
template <bool T> struct ASSERT_STRUCT {};
struct ASSERT_STRUCT<true> { static void static_assertion_failed() {} };
#define StaticAssert(expr) { const bool __b = (expr) ? true : false; ASSERT_STRUCT<__b>::static_assertion_failed(); }
#endif VisualCpp 8.0 °æ¿ì¿¡´Â ÅÛÇø´ Ư¼öÈ ¹æ½ÄÀÌ ¾à°£ º¯°æµÇ¾ú´Ù.
template <bool T> struct ASSERT_STRUCT {};
template<> struct ASSERT_STRUCT<true> { static void static_assertion_failed() {} };
3 ½ºÅà ¿À¹öÇÃ·Î¿ì ¹ß»ý½Ã ´ýÇÁ ±â·ÏÇϱâ
½ºÅà ¿À¹öÇÃ·Î¿ì ¹ß»ý½ÃÀÇ ´ýÇÁ ±â·ÏÀº ¾à°£ ´Ù¸£°Ô 󸮸¦ ÇØÁà¾ßÇÑ´Ù. ¾î·Á¿î °Ç ¾Æ´Ï°í, ±×³É ´Ù¸¥ ½º·¹µå¸¦ Çϳª »ý¼ºÇؼ ±×ÂÊÀ¸·Î ½º·¹µå ÇÚµé°ú ¿¹¿Ü Æ÷ÀÎÅ͸¦ ³Ñ°Ü¼ ´ýÇÁ¸¦ ±â·ÏÇÏ¸é µÈ´Ù. ÇöÀç ½º·¹µå¿¡¼´Â ´ýÇÁ ÇÔ¼ö¸¦ È£ÃâÇÒ ½ºÅø¶Àú ¸ðÀÚ¶ö ¼ö Àֱ⠶§¹®ÀÌ´Ù. ÇÏÁö¸¸ ´Ù¸¥ ½º·¹µå¸¦ Çϳª µû·Î »ý¼ºÇÏ¸é »õ·Î »ý¼ºÇÑ ½º·¹µå¿¡¼´Â ½ºÅà °ø°£ÀÌ ÃæºÐÇϱ⠶§¹®¿¡ ´ýÇÁ¸¦ ¹«»çÈ÷ ±â·ÏÇÒ ¼ö ÀÖ´Â °ÍÀÌ´Ù. (½ºÅÃÀº ½º·¹µåº°·Î À¯ÁöµÇ´Ï±î...)
typedef struct _DUMP_PARAMETER
{
HANDLE Thread;
PEXCEPTION_POINTERS ExPtrs;
} DUMP_PARAMETER, *PDUMP_PARAMETER;
DWORD WINAPI WriteDump(LPVOID param)
{
PDUMP_PARAMETER dumpParam = reinterpret_cast<PDUMP_PARAMETER>(param);
...¿©±â¼ ½ÇÁ¦ ´ýÇÁ¸¦ ¼öÇà...
}
LONG WINAPI HandleException(PEXCEPTION_POINTERS exPtrs)
{
if (exPtrs)
{
PDUMP_PARAMETER dumpParam = (PDUMP_PARAMETER)malloc(sizeof(DUMP_PARAMETER));
dumpParam->Thread = GetCurrentThread();
dumpParam->ExPtrs = exPtrs;
if (exPtrs->ExceptionRecord->ExceptionCode != EXCEPTION_STACK_OVERFLOW)
{
WriteDump(dumpParam);
}
else // ½ºÅà ¿À¹öÇ÷Π¹ß»ý ½Ã¿¡´Â º°µµÀÇ ½º·¹µå¸¦ »ý¼ºÇؼ ´ýÇÁ¸¦ ±â·ÏÇÑ´Ù.
{
HANDLE hThread = CreateThread(NULL, 102400, WriteDump, dumpParam, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
}
}
return EXCEPTION_EXECUTE_HANDLER;
}
void main()
{
...
// ¿¹¿Ü ó¸® Çڵ鷯¸¦ ¼³Á¤ÇÑ´Ù.
SetUnhandledExceptionFilter(HandleException);
...
}
4 »ý¼ºÀÚ ¹× ¼Ò¸êÀÚ ³»ºÎ¿¡¼´Â °¡»ó ÇÔ¼ö°¡ Á¦´ë·Î È£ÃâµÇÁö ¾Ê´Â´Ù
vtableÀÌ ¿ÏÀüÈ÷ ¼³Á¤µÈ »óŰ¡ ¾Æ´Ï±â ¶§¹®ÀÌ´Ù. ³ª»Û ÇÁ·Î±×·¡¹Ö ¹æ¹ýÀ̹ǷΠ´Ù¸¥ ¹æ¹ýÀ» »ç¿ëÇÏ´Â °ÍÀÌ ÁÁ´Ù.
»ùÇÃ
#include <iostream>
using namespace std;
class base
{
public:
base() { function(); }
virtual void function() { cout << "i'm base" << endl; }
};
class derived : public base
{
public:
derived() { }
virtual void function() { cout << "i'm derived" << endl; }
};
int main()
{
derived d;
return 0;
} Ãâ·Â
i'm base
5 µð¹ö±ëÀ» À§ÇÑ ÀÚÀßÇÑ ÇÔ¼öµé (Visual C++)
CRT ½Ã¸®Áî´Â Á¦¿Ü. À½... Àû¾î³õ°í º¸´Ï ²Ï ¸¹Àºµ¥... -_-
| ÇÔ¼ö | ¼³¸í |
| _set_new_handler | µ¿Àû ¸Þ¸ð¸® ÇÒ´çÀÌ ½ÇÆÐÇßÀ» ¶§ È£ÃâµÇ´Â Äݹé ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù. |
| _set_new_mode | malloc ÇÔ¼ö°¡ ½ÇÆÐÇßÀ» ¶§ _set_new_handler¿¡¼ ¼³Á¤ÇÑ ÇÔ¼ö¸¦ È£ÃâÇÒ °ÍÀΰ¡ÀÇ ¿©ºÎ¸¦ ¹ÝȯÇÑ´Ù. |
| set_terminate | 󸮵ÇÁö ¾ÊÀº ¿¹¿Ü·Î ÀÎÇØ ÇÁ·Î±×·¥ÀÌ Á¾·áµÉ ¶§ È£ÃâÇÒ ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù. |
| set_unexpected | 󸮵ÇÁö ¾ÊÀº ¿¹¿Ü°¡ ¹ß»ýÇßÀ» ¶§ È£ÃâÇÒ ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù. |
| uncaught_exception | ??? |
| _set_error_mode | ¿¡·¯ ¹ß»ý½Ã ¸Þ½ÃÁö Ãâ·ÂµÇ´Â °÷(ÄܼÖÈ¸é ¶Ç´Â ¸Þ½ÃÁö¹Ú½º)À» ¼³Á¤ÇÑ´Ù. |
| _set_purecall_handler | ¼ø¼ö °¡»ó ÇÔ¼ö°¡ È£ÃâµÇ¾úÀ» ¶§ È£ÃâÇÒ Äݹé ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù. |
| _set_sbh_threshold | Small Block Heap¿¡ ÇÒ´çµÇ´Â ¸Þ¸ð¸®ÀÇ ÃÖ´ë¾çÀ» ¼³Á¤ÇÑ´Ù. |
| _set_se_translator | Win32 Structured ExceptionÀ» C++ ExceptionÀ¸·Î ó¸® °¡´ÉÇÏ°Ô ÇÑ´Ù. ÀÚ¼¼ÇÑ °ÍÀº StructuredExceptionAsCppException ÆäÀÌÁö¸¦ Âü°í. |
| _set_security_error_handler | BufferOverrunÀÌ ¹ß»ýÇßÀ» ¶§ È£ÃâÇÒ Äݹé ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù. |
| _setmaxstdio | µ¿½Ã¿¡ ¿ ¼ö ÀÖ´Â ÃÖ´ë ÆÄÀÏ °¹¼ö¸¦ ¼³Á¤ÇÑ´Ù. ulimit¿Í ºñ½ÁÇÏ´Ù. |
| _matherr | math.h ÇÔ¼ö ½ÇÇà ¿¡·¯ ¹ß»ý½Ã È£ÃâµÇ´Â ÇÔ¼ö(?) |
| _fpieee_flt | IEEE ºÎµ¿ ¼Ò¼öÁ¡ ¿¬»ê ¿¹¿Ü ¹ß»ý½Ã È£ÃâµÇ´Â ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù. |
| atexit | ¸ÞÀÎ ÇÔ¼ö°¡ ¹ÝȯµÈ ÈÄ È£ÃâµÇ´Â ÇÔ¼ö¸¦ ¼³Á¤ÇÑ´Ù |
6 ½º·¹µå¿¡ À̸§ ºÙÀ̱â (Visual C++)
//
// Usage: SetThreadName (-1, "MainThread");
//
typedef struct tagTHREADNAME_INFO
{
DWORD dwType; // must be 0x1000
LPCSTR szName; // pointer to name (in user addr space)
DWORD dwThreadID; // thread ID (-1=caller thread)
DWORD dwFlags; // reserved for future use, must be zero
} THREADNAME_INFO;
void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName)
{
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = szThreadName;
info.dwThreadID = dwThreadID;
info.dwFlags = 0;
__try
{
RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info );
}
__except(EXCEPTION_CONTINUE_EXECUTION)
{
}
} SetThreadName ÇÔ¼ö¸¦ ½º·¹µå ¸ÞÀÎ ·çÇÁ Á¦ÀÏ À§ÂÊ(Áï ½º·¹µå ID¸¦ ÇÒ´ç ¹Þ°í³ ÈÄ)¿¡¼ È£ÃâÇØ ÁÖ¸é, ½º·¹µåâ¿¡ ½º·¹µå À̸§µéÀÌ Ãâ·ÂµÇ´Â °ÍÀ» º¼ ¼ö ÀÖ´Ù. ½º·¹µå À̸§ ¾ø¾îµµ ½º·¹µå ÇÔ¼ö·Î ´ëºÎºÐ ¾î´À ½º·¹µåÀÎÁö¸¦ ¾Ë ¼ö ÀÖ±â´Â ÇÏÁö¸¸... Âü°í·Î µð¹ö°Å°¡ ºÙ¾îÀÖ´Â »óÅ¿¡¼¸¸ µ¿ÀÛÇÑ´Ù. IsDebuggerPresent ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼ µð¹ö°Å°¡ ºÙ¾îÀÖ´Â °æ¿ì¿¡¸¸ À̸§À» ¼³Á¤ÇÏÀÚ.
7 Critical Section¿¡ ¶ôÀ» °Ç ½º·¹µå ¾Ë¾Æ³»±â (Visual C++)
from
How to find the owner of a critical section
7.1 ¼ø¼
- ½Éº¼ ¼³Ä¡´Â Çʼö. DrWatson ÆäÀÌÁö¸¦ Âü°í.
- ¾Æ¹« °÷À̳ª ºê·¹ÀÌÅ© Æ÷ÀÎÆ®¸¦ ¼³Á¤Çؼ ½ÇÇàÀ» ÀϽà ÁßÁö½ÃŲ´Ù.
- µµ±¸ ¸ðÀ½ -> µð¹ö±× À§Ä¡ -> ½º·¹µå ¸Þ´º¸¦ ÀÌ¿ëÇØ ¶ôÀ» °É·Á Çϰí ÀÖ´Â ½º·¹µå¸¦ ã¾Æ³½´Ù. (EnterCriticalSection ÇÔ¼ö¿¡ ¸ØÃçÀÖ´Â ½º·¹µå°¡ ÀÖÀ» °ÍÀÌ´Ù.)
- ¶ôÀ» °É·Á ÇÏ´Â ½º·¹µå¸¦ ã¾Ò´Ù¸é ÄݽºÅÃÀ» Ç¥½ÃÇÑ´Ù. ´ë° ¾Æ·¡¿Í °°Àº ¸ð¾çÀÇ ÄݽºÅÃÀÌ Ãâ·ÂµÉ °ÍÀÌ ´Ù.
NTDLL.DLL!_NtWaitForSingleObject@12() + 0xb
NTDLL.DLL!_RtlpWaitForCriticalSection@4() + 0x74
NTDLL.DLL!_RtlEnterCriticalSection@4() + 0x91f5
GameServerD.exe!BasicCriticalSection::enter() ÁÙ 41 + 0xf C++
GameServerD.exe!CriticalSection::lock(...) const ÁÙ 94 C++
GameServerD.exe!DeadlockTestThread::run() ÁÙ 135 + 0x27 C++
GameServerD.exe!thread_func_proxy(void * pContext=0x0012feb4) ÁÙ 41 + 0xd C++
GameServerD.exe!_threadstartex(void * ptd=0x00e45300) ÁÙ 241 + 0xd C
KERNEL32.DLL!77e5b382()
NTDLL.DLL!_RtlAllocateHeapSlowly@12() + 0x14acd
- ÄݽºÅÿ¡¼ NTDLL.DLL!_RtlEnterCriticalSection@4() ÇÁ·¹ÀÓÀ¸·Î °£´Ù.
- µð¹ö±× -> â -> ¸Þ¸ð¸® ¸Þ´º¸¦ ÀÌ¿ëÇØ ¸Þ¸ð¸® À©µµ¿ì¸¦ ¶ç¿î´Ù.
- ¸Þ¸ð¸® À©µµ¿ì ÄÁÅØ½ºÆ® ¸Þ´º¸¦ ÀÌ¿ëÇØ¼ Ãâ·ÂÀ» 4¹ÙÀÌÆ® Á¤¼ö, Ç¥½Ã¸¦ 16Áø¼ö·Î ÇÑ´Ù.
- ¸Þ¸ð¸® À©µµ¿ìÀÇ ÁÖ¼Òâ¿¡¼ '@vframe'À̶ó°í ÀÔ·ÂÇÑ´Ù.
- Á¦ÀÏ Ã¹¹øÂ° 4¹ÙÀÌÆ® Á¤¼ö °ªÀÌ ÇÔ¼öÀÇ ¸®ÅÏ À§Ä¡´Ù. µÎ¹øÂ° 4¹ÙÀÌÆ® Á¤¼ö°ªÀÌ Å©¸®Æ¼Äà ¼½¼ÇÀÇ À§Ä¡´Ù. ÀÌ °ªÀ» Ä«ÇÇÇØ¼ ¸Þ¸ð¸® À©µµ¿ìÀÇ ÁÖ¼Òâ¿¡´Ù ÀÔ·ÂÇÑ´Ù.
- ¾Õ¿¡¼ ³×¹øÂ°ÀÇ 4¹ÙÀÌÆ® Á¤¼ö°¡ Å©¸®Æ¼Äà ¼½¼Ç¿¡ ¶ôÀ» °Ç ½º·¹µåÀÇ ID´Ù. Á¶»ç½Ä À©µµ¿ì¿¡¼ °ªÀ» Ç¥½ÃÇØ º¸¸é, ½º·¹µå ¸ñ·Ï¿¡ ÀÏÄ¡ÇÏ´Â ½º·¹µå°¡ ÀÖÀ» °ÍÀÌ´Ù.
7.2 ¾Ë¾ÆµÑ Á¡
8 ÄݽºÅÃÀÌ ³ª¿ÀÁö ¾Ê°Å³ª ÀÌ»óÇÑ °æ¿ì (Visual C++)
from
Bad Native Callstacks
8.1 µð¹ö±× ½Éº¼ÀÌ ¾ø´Â °æ¿ì
´õ ÀÌ»ó ¸»ÇÒ °¡Ä¡°¡ Àִ°¡?
8.2 À߸øµÈ OS ½Éº¼
VC6°ú VC7Àº ½Éº¼ ÆÄÀÏÀÇ Çü½ÄÀÌ ¾à°£ ´Ù¸¥µ¥, ±âº»ÀûÀ¸·Î ¸¶ÀÌÅ©·Î¼ÒÇÁÆ®¿¡¼ ¹èÆ÷ÇÏ´Â ½Éº¼Àº VC6 Çü½ÄÀÌ´Ù. OS¿Í ¹ÐÁ¢ÇÏ°Ô °ü·ÃµÇ¾î ÀÖ´Â ÇÁ·Î±×·¥ÀÏ °æ¿ì ¹®Á¦°¡ µÈ´Ù.
8.3 ¾î¼Àºí¸®¾î·Î ¸¸µé¾îÁø ÇÔ¼ö
¾î¼Àºí¸®¾î·Î ÇÁ·Î±×·¥À» Á¦ÀÛÇÏ´Â °æ¿ì, µð¹ö°Å°¡ »ó´çÈ÷ È¥¶õÀ» °Þ°Ô µÈ´Ù. ±âº» C ·±Å¸ÀÓÀÌ ´ëÇ¥ÀûÀÎ ¿¹ÀÌ´Ù.
8.4 ½ºÅà ÀÚü°¡ ¿À¿°µÈ °æ¿ì
½ºÅà ¿À¹öÇÃ·Î¿ì µîÀÇ ÀÌÀ¯·Î ÀÎÇØ ÄݽºÅà µ¥ÀÌÅÍ ÀÚü°¡ ³¯¾Æ°¡¹ö¸° °æ¿ì´Ù. ÀÌ °æ¿ì ¸Þ¸ð¸® ÂÊÀ¸·Î ¹ö±×¸¦ ãÀ» °ÍÀÌ ¾Æ´Ï¶ó, C ·±Å¸ÀÓ ÇÔ¼ö¸¦ »ç¿ëÇϰųª, ÄÄÆÄÀÏÇÒ ¶§ '/gs' Ç÷¡±×¸¦ ÁÖ´Â °ÍÀÌ ÁÁ´Ù.
8.5 À߸øµÈ ESP/EIP ·¹Áö½ºÅÍ °ª
ÀÌ´Â Äڵ尡 ¾²·¹±â°ªÀ» ½ÇÇàÇϱ⠽ÃÀÛÇÒ ¶§ ¹ß»ýÇÑ´Ù. »èÁ¦µÈ °´Ã¼ÀÇ vtableÀ» ÂüÁ¶Çϰųª, À߸øµÈ ÇÔ¼ö Æ÷ÀÎÅ͸¦ »ç¿ëÇÏ´Â °æ¿ì°¡ ´ëÇ¥ÀûÀ̶ó°í ÇÒ ¼ö ÀÖ´Ù. À߸øµÈ ŸÀÔ Ä³½ºÆ®µµ ¿øÀÎÀÌ µÉ ¼ö ÀÖ´Ù.
Debugging Tools for Windows¿¡ µþ·Á¿À´Â gflags.exe¸¦ ÀÌ¿ëÇØ Page Heap ¿É¼ÇÀ» ÄÒ ´ÙÀ½, WinDbg¸¦ ÀÌ¿ëÇØ µð¹ö±×Çϱ⠹ٶõ´Ù. (VisualCpp µð¹ö°Å·Î´Â ¾È ÀâÈù´Ù.)
Page Heap ¿É¼Ç¿¡ °üÇØ¼´Â
PageHeap ¹®¼¸¦ Âü°íÇÏ¸é µÈ´Ù. pageheap.exe ¾î¼±¸ Àú¼±¸ ÇÏ´Â °Ç ¹«½ÃÇϰí, ±×³É gflags.exe¸¦ ÀÌ¿ëÇϱ⸸ ÇÏ¸é µÈ´Ù.
8.6 ÇÔ¼ö ÇÕÄ¡±â (Linker COMDAT folding)
µÎ ÇÔ¼ö°¡ ¿ÏÀüÈ÷ °°Àº ¸Ó½Å Äڵ带 »ý¼ºÇÏ´Â °æ¿ì, ÄÄÆÄÀÏ·¯°¡ À̸¦ Çϳª·Î ÇÕÄ¡´Â °æ¿ì°¡ ÀÖ´Ù. ÇÔ¼ö À̸§ÀÌ Æ²¸®´Ï, µð¹ö°Å°¡ È¥¶õÀ» ÀÏÀ¸Å³ ¼ö ¹Û¿¡ ¾ø´Ù. ÃÖÀûȸ¦ ²ô°í Å×½ºÆ®Çغ¸±â ¹Ù¶õ´Ù.
9 ¿¹¿Ü¸¦ ¸¸µéÁö ¾Ê°í, ±×³É »ç¶óÁö´Â ÇÁ·Î¼¼½º (Visual C++)
from
Why a process vanishes
9.1 À߸øµÈ ¿¹¿Ü ó¸®
SEH ºÎºÐÀ» º¸¸é ¾Ë°ÚÁö¸¸, ¿¹¿Ü 󸮸¦ À߸øÇÏ´Â °æ¿ì, OS°¡ JIT µð¹ö°Å¸¦ ¶ç¿ï ±âȸ¸¦ ¾òÁö ¸øÇÒ ¼öµµ ÀÖ´Ù.
9.1.1 try-except ±¸¹®¿¡¼ ¿¹¿Ü ÇÊÅÍ ºÎºÐ ¾È¿¡¼ ¿¹¿Ü¸¦ ´øÁö´Â °æ¿ì
´ÙÀ½°ú °°Àº Äڵ带 ÄÄÆÄÀÏÇØº¸½Ã¶ó.
DWORD check()
{
throw 333;
return EXCEPTION_EXECUTE_HANDLER;
}
void main()
{
__try
{
int* p = NULL;
*p = 444;
}
__except(check()) // ÇÊÅÍ ¾È¿¡¼ ¿¹¿Ü°¡ ¹ß»ýÇÑ´Ù.
{
throw 111;
}
}
µð¹ö°Å¸¦ ºÙÀÎ »óÅ·Π½ÇÇàÇÏ¸é ¿¹¿Ü 󸮰¡ °¡´ÉÇϰÚÁö¸¸, ±×³É ½ÇÇàÇÏ¸é ¾Æ¹« ¸»µµ ÇÏÁö ¾Ê°í »ç¶óÁö´Â °ÍÀ» º¼ ¼ö ÀÖÀ» °ÍÀÌ´Ù.
9.1.2 À߸øµÈ ¿¹¿Ü ó¸® Çڵ鷯¸¦ ¼³Á¤ÇÑ °æ¿ì
SetUnhandledExceptionFilter, AddVectoredExceptionHandler, _set_se_translator ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¼ ¿¹¿Ü ó¸® Çڵ鷯¸¦ ¼³Á¤ÇÒ ¼ö ÀÖ´Ù. Çڵ鷯°¡ À߸ø ®´Ù¸é OS¿¡°Ô ±âȸ°¡ ¿ÀÁö ¾ÊÀ» ¼ö ÀÖ´Ù. DLLÀÌ ·ÎµåµÇ¸é¼ ÀÚµ¿À¸·Î ¿¹¿Ü ó¸® Çڵ鷯¸¦ ¼³Á¤ÇÏ´Â °æ¿ì, ÀÌ·± ¹®Á¦°¡ ÀÚÁÖ ¹ß»ýÇÑ´Ù. Windows Server 2003ÀÇ °æ¿ì, SafeSEH ¸®½ºÆ®¿¡ ¾ø´Â Çڵ鷯¸¦ ¼öµ¿À¸·Î ¼³Á¤ÇÏ·Á´Â °æ¿ì, ¹ß»ýÇÑ´Ù.
9.1.3 ½ºÅà ¿À¹öÇ÷ο츦 À߸ø ó¸®ÇÏ´Â °æ¿ì
½ºÅà ¿À¹öÇ÷ο찡 ¹ß»ýÇÏ´Â °æ¿ì, ½ºÅÃÀÇ ³¡¿¡ ÀÖ´Â °¡µå ÆäÀÌÁö(guard page)°¡ ¾ø¾îÁø´Ù. ¿¹¿Ü ÇÊÅÍ¿¡¼ ½ºÅà ¿À¹öÇÃ·Î¿ì ¿¹¿Ü¸¦ Àâ¾Ò´Ù¸é, °¡µå ÆäÀÌÁöµµ Àç¼³Á¤ÇØÁà¾ß ÇÑ´Ù. °¡µå ÆäÀÌÁö¸¦ Àç¼³Á¤ÇØ ÁÖÁö ¾ÊÀ¸¸é, ´ÙÀ½ ½ºÅà ¿À¹ö ÇÃ·Î¿ì ½Ã¿¡ ÇÁ·Î¼¼½º°¡ ±×³É »ç¶óÁö°Ô µÈ´Ù.
9.1.4 ¹«ÇÑ ·çÇÁ
ÀͼÁ¼Ç Çڵ鷯 ÀÚü¸¦ °¡ºñÁö·Î µ¤¾î¾´ °æ¿ì
9.2 Á¤»óÀûÀÎ ÇÁ·Î¼¼½º Á¾·á
TerminateProcess, ExitProcess, TerminateThread, ExitThread µîÀÇ ÇÔ¼ö¸¦ »ç¿ëÇØ¼ ÇÁ·Î±×·¥À» Á¾·áÇÑ °æ¿ì, OS´Â À̸¦ Á¤»óÀûÀÎ µ¿ÀÛÀ¸·Î Ãë±ÞÇÑ´Ù.
10 ¿¡·¯ÄÚµå ¹®ÀÚ¿·Î º¯È¯Çϱâ
/// \brief ¿¡·¯ Äڵ带 ¹®ÀÚ¿·Î º¯È¯Çؼ ¸®ÅÏÇÑ´Ù.
std::string Error2String(unsigned int errorCode)
{
LPVOID msgBuf = NULL;
std::string message = "Error2String() call failed!";
if (::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
errorCode,
//MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN),
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPTSTR)&msgBuf,
0,
NULL))
{
message = reinterpret_cast<LPCTSTR>(msgBuf);
::LocalFree(msgBuf);
}
return message;
}
/// \brief GetLastError() + Error2String()
std::string GetLastErrorString()
{
return Error2String(::GetLastError());
}
11 ¸µÅ©
SeriousMoin v1 (koMoinMoin 1.0a4 Modified)