티스토리 뷰
class CObject { public: CObject(int nKey) : m_nKey(nKey) { } virtual ~CObject() { } DWORD Key() { return m_nKey; } private: int m_nKey; }; class CChild : public CObject { public: CChild(int nKey) : CObject(nKey) { memcpy(m_szData, 0, sizeof(m_szData)); } void Set(char* pData) { strncpy_s(m_szData, pData, sizeof(m_szData)); m_szData[DATA_SIZE - 1] = 0; } char* Data() { return m_szData; } private: static const int DATA_SIZE = 1024; char m_szData[DATA_SIZE]; }; class COtherChild : public CObject { public: COtherChild(int nKey) : CObject(nKey) { } DWORD Data() { return m_nData; } private: int m_nData; };
예외가 발생하는 상황
0으로 나누기
-> 나누기를 직접 사용하지 말고, 매크로 함수로 만들어놓고 사용하는 것이 좋다. (0으로 나누기를 시도했을 경우 로그를 남기는 등의 동작)
int nDivisor = 0; int nResult = rand() / nDivisor; //Divide zero.잘못된 메모리 접근 (널포인터 접근 포함)
-> Access Violation 예외 발생
-> 프로그래머가 주의해서 코드 짜야지 뭐~ 어쩔 수 없지~.
CObject* pObject = new CChild((DWORD)time(NULL)); pObject = NULL; pObject->Key();
CObject* pObject = NULL; pObject = new CObject((DWORD)time(NULL)); delete pObject; delete pObject;
-> 주로 Access Violation이 발생하지만, 멀티 스레드라서 다른 스레드에서 같은 주소에 할당을 요청했고, 그 주소를 다시 한번 delete했을 경우는 증상이 엉뚱한 곳에서 나오기도 하니 반드시 SAFE_DELETE같은 매크로 함수 혹은 auto_ptr, shared_ptr 등의 스마트한 메모리 관리 객체를 사용하자.
바로 크래쉬 되는 상황
스택 오버플로우 (무한 재귀 또는, 스택 변수를 너무 크게 잡고 사용할 시에 발생)
-> 대책 : http://msdn.microsoft.com/ko-kr/library/aa289171(VS.71).aspx
-> 스택 오버 플로우 트랩 : http://support.microsoft.com/kb/315937
void StackOverflow(int depth) { char blockdata[10000]; printf("Overflow: %d\n", depth); StackOverflow(depth+1); }예외가 발생해 스택 되감기하는 도중 예외 발생.
-> 이런 경우가 흔치는 않은데, 안전하지 않은 코드 작성시에는 이렇게 되기도 한다. 딱히 대책은 없다. 너무 무책임한가 =_=;
멈춘 듯 보이는 상황
반복 수행되는 쓰레드에서, 익셉션에 계속 남는다. (원스레드식으로 돌릴 때)
-> 덤프 백만개 쌓이다가 하드 풀나기도 한다. 우울해지곤하지...=_=
대책은 HardDisk Space 계산해서, 특정 수치 이상이면 서버 떨구는게 차라리 낫다.
무한 루프
-> GPG3권에 있는 1.3의 C스타일 매크로의 새로운 가치를 찾아서에 나오는 while_limit 를 적극 활용하는 것이 어떨까 싶다.
좋은 습관은 주로 위기 상황에서 효과를 발휘하는 법이다.
데드락
-> 실제로 멈춘상태. 주의 사항은, 데드락이 걸려있는 스레드랑 전혀 별도로 돌아가던 스레드는 여전히 계속 돌고 있다는 점이다. 이 얘기는 뭐냐하면, AliveCheck용 스레드를 따로 두었을 경우, HeartBeat가 제대로 전달되 데드락 걸린 상황을 탐지하기 어려울 수도 있다는 것이다.
멈춘 듯 보이는 현상을 해결하기 위해선, UserDump 등으로 FullDump 뜨는 것을 추천한다.
-> http://elky.tistory.com/162
FullDump로 콜스택을 확인해보면, 어떤 스레드가 무한 루프에 빠졌거나, 데드락에 걸렸는지 등을 확인 할 수 있다.
좀 더 확실히 하려면 Snapshot처럼 여러번 FullDump를 남겨 확인해보면 좀 더 확실해 질 것이다.
구분이 잘 안가는 상황 (인과 관계를 깨드리는 상황)
스택 조금만 덮어 씌웠을 때
-> 대책 : http://msdn.microsoft.com/ko-kr/library/aa289171(VS.71).aspx
-> 버퍼 오버플로우 되는 상황이 나왔다는거 자체가 우울한 상황이다. 이 상황에서 원인을 찾길 바라는건 요행에 가깝다.
-> 메모리 관련 함수는 되도록 자제하라. (memcpy, memset 등등...)
-> 네이티브 포인터도 자제하라.
자식 클래스로의 잘못된 다운 캐스트한 후, 자식 클래스의 함수 호출.
CObject* pObject = new COtherChild((DWORD)time(NULL)); CChild* pChild = static_cast< CChild * >(pObject); pChild->Set("TypecastError"); delete pObject;
-> 해당 영역에 어떤 데이터가 있었는지에 따라 다르다. 자식 클래스의 함수에서 사용하는 데이터가, 자식 클래스 전용 멤버일 경우 잘못된 메모리 접근이 있을 것이고....혹은 메모리 관련 함수거나 하다면 더 이상한 증상을 보인다.
-> 잘못된 다운 캐스트 자체가 정줄 놓은거지...진짜 확신한다해도 다운 캐스트 자체는 죄악. 허나 어쩔 수 없이 다운캐스트가 필요하다면 dynamic_cast를 사용하라. 근데 나는 이것도 좀 반대하는 입장.
-> 이런건 어떨까? http://www.gamedev.net/reference/programming/features/TypeSafeGenPtr/
잘못된 함수 포인터
-> 주의 해라. 뭐 별 수 있나...
삭제 중인 객체 혹은 삭제된 객체의 순수 가상 함수 호출
-> http://msdn.microsoft.com/en-us/library/t296ys27(VS.80).aspx
CRT가 함수에 잘못된 인수를 전달 받았을 때에 불리는 함수
-> http://msdn.microsoft.com/en-us/library/a9yf33zb(VS.80).aspx
'C++ > General' 카테고리의 다른 글
함수의 리턴 값의 포인터를 사용할 수 없는 문제 (1) | 2011.05.18 |
---|---|
any_ptr - A Type-safe Generic Pointer (0) | 2010.09.30 |
WIN32 Console Application 에서 MFC 사용하기 (2) | 2010.01.22 |
dllimport, dllexport (3) | 2009.12.29 |
스택 크기 (1) | 2009.12.08 |
- Total
- Today
- Yesterday
- RoR
- 디버깅
- SQLite Spy
- 게임개발포에버
- c언어
- 엘키
- 게임데브포에버
- 바로가기 프로그램
- 임백준
- TraceRoute
- svn
- 디자인 패턴
- Ruby on Rails
- 리버스 엔지니어링
- ftp
- 조엘 온 소프트웨어
- TDD
- perfmon
- MS-SQL
- NDC2013
- 좋은 프로그래머
- 멀티스레드
- Rails
- 루비
- CppSQLite
- EzShortcut
- EasyExec
- SDL
- 루비 온 레일즈
- ruby
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |