C++ Exception을 활용한 런타임 콜스택 정보 얻기 > QT 강좌/팁

본문 바로가기
사이트 내 전체검색

QT 강좌/팁

QT/Embedded C++ Exception을 활용한 런타임 콜스택 정보 얻기

페이지 정보

작성자 no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 댓글 1건 조회 6,666회 작성일 15-04-01 22:13

본문

이글은 제가 podovat.com의 blog 올린글(http://www.podovat.com/?p=432)에서 퍼온것입니다.

[b]1. 개요[/b]
동작중인 프로그램이 갑자기 오류를 발생하여 프로그램이 종료하는 문제를 찾기 위해서는 종료시점의 Call Stack을 확인하여 소스코드 상의 어디까지 수행을 하다 멈추었는지를 찾아서 디버깅을 해야 한다. 이를 위해서 Linux API중 backtrace함수는 호출 시점에 수행한 기록들을 알아낼 수 있는데, 이 함수를 프로그램 오류시 Exception이 발생될 때 호출하여, 그 기록을 파일로 저장하고, 이를 토대로 addr2line 유틸리티를 이용해서 실제 소스코드상의 위치를 알아낼 수 있다.

[b]2. 구현[/b]
1과 같이 설명한 내용을 구현한 내용은 다음과 같으며 excpthandler.h 파일 이름으로 저장을 한다.
[code=c]
#ifndef _EXCPTHANDLER_H_
#define _ECCPTHANDLER_H_

#include
#include

#include
#include
#include

using namespace std;

class ExceptionTracer
{
public:
ExceptionTracer()
{
void * array[100];
int nSize = backtrace(array, 100);
char ** symbols = backtrace_symbols(array, nSize);

// error file
ofstream outFile;
outFile.open("/program-error.log", ios::trunc);
outFile << __DATE__ << " " << __TIME__ << endl;
for (int i = 0; i < nSize; i++)
{
cout << symbols[i] << endl;
outFile << symbols[i] << endl;
}

free(symbols);
}
};

template class SignalTranslator
{
private:
class SingleTonTranslator
{
public:
SingleTonTranslator()
{
signal(SignalExceptionClass::GetSignalNumber(), SignalHandler);
}

static void SignalHandler(int)
{
throw SignalExceptionClass();
}
};

public:
SignalTranslator()
{
static SingleTonTranslator s_objTranslator;
}
};

// An example for SIGSEGV
class SegmentationFault : public ExceptionTracer, public exception
{
public:
static int GetSignalNumber() {return SIGSEGV;}
};
SignalTranslator g_objSegmentationFaultTranslator;

// An example for SIGFPE
class FloatingPointException : public ExceptionTracer, public exception
{
public:
static int GetSignalNumber() {return SIGFPE;}
};
SignalTranslator g_objFloatingPointExceptionTranslator;

// An example for SIGILL
class IllegalInstructionException : public ExceptionTracer, public exception
{
public:
static int GetSignalNumber() {return SIGILL;}
};
SignalTranslator
g_objIllegalInstructionExceptionTranslator;

// An example for SIGTRAP
class TrapException : public ExceptionTracer, public exception
{
public:
static int GetSignalNumber() {return SIGTRAP;}
};
SignalTranslator g_objTrapExceptionTranslator;

class ExceptionHandler
{
private:
class SingleTonHandler
{
public:
SingleTonHandler()
{
set_terminate(Handler);
}

static void Handler()
{
// Exception from construction/destruction of global variables
try
{
// re-throw
throw;
}
catch (SegmentationFault &)
{
cout << "SegmentationFault" << endl;
}
catch (FloatingPointException &)
{
cout << "FloatingPointException" << endl;
}
catch (IllegalInstructionException &)
{
cout << "IllegalInstructionException" << endl;
}
catch (TrapException &)
{
cout << "TrapException" << endl;
}
catch (...)
{
cout << "Unknown Exception" << endl;
}

//if this is a thread performing some core activity
abort();
// else if this is a thread used to service requests
// pthread_exit();
}
};

public:
ExceptionHandler()
{
static SingleTonHandler s_objHandler;
}
};

// Before defining any global variable, we define a dummy instance
// of ExceptionHandler object to make sure that
// ExceptionHandler::SingleTonHandler::SingleTonHandler() is invoked
ExceptionHandler g_objExceptionHandler;

#endif
[/code]

위의 구현 파일을 excpthandler.h 파일로 저장한다.

[b]3. 예제[/b]
다음과 같은 예제를 만들어서 excpthandler.h 파일을 include 한다.
main.cpp
[code=c]
#include
#include
#include "excpthandler.h"

int main(int argc, char** argv)
{
QString* s1 = new QString("111");
QString* s2 = new QString("222");

QString* string[2] = { s1, s2 };

for (int i=0; i<3; i++)
{
qDebug() << "string:" << *string[i];
}

return 0;
}
[/code]

위의 코드를 컴파일 하기 위해서 다음과 같이 Project파일을 생성한다.
excpthandler.pro
[code]
TEMPLATE = app
QT += core
QT -= gui
CONFIG += debug
TARGET =
DEPENDPATH += .
INCLUDEPATH += .

# Input
SOURCES += main.cpp
[/code]

command상에서 다음과 같이 compile을 한다.
$ qmake
$ make

[b]4. 실행 및 디버깅[/b]
다음과 같이 프로그램을 실행하면 에러가 발생한다.
[code]
$ ./excpthandler
podo@ubuntu:~/excpthandler$ ./excpthandler
string: "111"
string: "222"
./excpthandler() [0x80497c4]
./excpthandler() [0x8049cff]
./excpthandler() [0x8049d8c]
[0xb7784400]
/usr/lib/i386-linux-gnu/libQtCore.so.4(_ZN11QTextStreamlsERK7QString+0x3a) [0xb75ae8aa]
./excpthandler() [0x8049752]
./excpthandler() [0x8049262]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3) [0xb71ff4d3]
./excpthandler() [0x8049131]
SegmentationFault
Aborted (core dumped)
[/code]

위의 표시 내용중 Segmentation Fault발생 이전까지 주소들이 표시가 되는데, 이 주소값을 이용해 소스코드 상의 어디인지 확인할 수 있다.
이를 위해 addr2line 프로그램을 이용해서 주소값을 입력하여 소스코드상의 위치를 확인한다.

[code]
podo@ubuntu:~/excpthandler$ addr2line -C -fe ./excpthandler 0x80497c4
ExceptionTracer
/home/podo/excpthandler/excpthandler.h:19
podo@ubuntu:~/excpthandler$ addr2line -C -fe ./excpthandler 0x8049cff
SegmentationFault
/home/podo/excpthandler/excpthandler.h:61
podo@ubuntu:~/excpthandler$ addr2line -C -fe ./excpthandler 0x8049d8c
SignalTranslator::SingleTonTranslator::SignalHandler(int)
/home/podo/excpthandler/excpthandler.h:49
podo@ubuntu:~/excpthandler$ addr2line -C -fe ./excpthandler 0x8049752
QDebug::operator<<(QString const&)
/usr/include/qt4/QtCore/qdebug.h:112
podo@ubuntu:~/excpthandler$ addr2line -C -fe ./excpthandler 0x8049262
main
/home/podo/excpthandler/main.cpp:14
[/code]

addr2line 을 이용해서 주소값을 차례대로 입력하다보면 main.cpp 의 14번째 라인에서 이상이 있음을 확인할 수 있다.

추천0

댓글목록

Total 198건 1 페이지
QT 강좌/팁 목록
번호 제목 글쓴이 조회 추천 날짜
198 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 4030 0 09-10
197 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 5573 0 12-03
196 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6946 1 03-07
195 QT/Embedded no_profile 요원009 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11286 0 11-13
194 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6530 0 05-18
193 QT/Embedded no_profile 잉농 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6286 0 05-14
열람중 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6667 0 04-01
191 QT/Embedded no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 22208 1 03-31
190 QT/Win32 no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 13415 0 03-17
189 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 5907 0 02-13
188 QT/Win32 no_profile 인라이너 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 5839 1 02-12
187 QT/Embedded no_profile 김아무개 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 16276 0 11-12
186 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 5876 0 11-11
185 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 5915 0 11-11
184 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10641 0 10-22
183 QT/Win32
Qt와 C++11 댓글+ 2
no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10982 1 10-12
182 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10630 0 10-09
181 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7620 0 10-02
180 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8759 0 10-01
179 QT/X11 no_profile 별님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 5449 0 09-25
178 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6122 0 09-16
177 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7588 0 09-03
176 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7498 0 09-02
175 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7993 2 09-02
174 QT/X11 no_profile 나무나무나무 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8474 0 07-25
173 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6822 2 07-11
172 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9491 2 07-09
171 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 6637 2 07-08
170 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 13173 1 07-07
169 QT/X11 no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8311 0 07-02
게시물 검색

  • 게시물이 없습니다.

회원로그인

설문조사

새로운 홈페이지에 대한 평가

접속자집계

오늘
184
어제
539
최대
3,878
전체
4,094,905

Copyright © korone.net. All rights reserved.