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

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

QT 강좌/팁

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

페이지 정보

작성자 no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 댓글 1건 조회 9,731회 작성일 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 200건 1 페이지
QT 강좌/팁 목록
번호 제목 글쓴이 조회 추천 날짜
200 QT/Win32 no_profile 이지수입니다 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 2330 0 02-14
199 QT/Win32 no_profile 주영대감 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 3536 0 05-31
198 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9125 0 09-10
197 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9379 0 12-03
196 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10387 1 03-07
195 QT/Embedded no_profile 요원009 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 15224 0 11-13
194 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9391 0 05-18
193 QT/Embedded no_profile 잉농 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9237 0 05-14
열람중 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9732 0 04-01
191 QT/Embedded no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 28674 1 03-31
190 QT/Win32 no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 19481 0 03-17
189 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8489 0 02-13
188 QT/Win32 no_profile 인라이너 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8633 1 02-12
187 QT/Embedded no_profile 김아무개 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 21153 0 11-12
186 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8806 0 11-11
185 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8863 0 11-11
184 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 15099 0 10-22
183 QT/Win32
Qt와 C++11 댓글+ 2
no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 15050 1 10-12
182 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 16785 0 10-09
181 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10858 0 10-02
180 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 13658 0 10-01
179 QT/X11 no_profile 별님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 7784 0 09-25
178 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9500 0 09-16
177 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10100 0 09-03
176 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9945 0 09-02
175 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10358 2 09-02
174 QT/X11 no_profile 나무나무나무 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 12493 0 07-25
173 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9538 2 07-11
172 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 12995 2 07-09
171 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9364 2 07-08
게시물 검색

  • 게시물이 없습니다.

회원로그인

설문조사

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

접속자집계

오늘
575
어제
1,010
최대
4,337
전체
4,815,451

Copyright © korone.net. All rights reserved.