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

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

QT 강좌/팁

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

페이지 정보

작성자 no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 댓글 1건 조회 10,525회 작성일 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 154건 1 페이지
QT 강좌/팁 목록
번호 제목 글쓴이 조회 추천 날짜
154 QT/Win32 no_profile 이지수입니다 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 3303 0 02-14
153 QT/Win32 no_profile 주영대감 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 4328 0 05-31
152 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10108 0 09-10
151 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10252 0 12-03
150 QT/X11 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11337 1 03-07
149 QT/Embedded no_profile 요원009 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 16071 0 11-13
148 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10074 0 05-18
147 QT/Embedded no_profile 잉농 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10013 0 05-14
열람중 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10526 0 04-01
145 QT/Embedded no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 29749 1 03-31
144 QT/Win32 no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 20555 0 03-17
143 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9135 0 02-13
142 QT/Win32 no_profile 인라이너 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9424 1 02-12
141 QT/Embedded no_profile 김아무개 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 22093 0 11-12
140 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9634 0 11-11
139 QT/Embedded no_profile korone 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 9688 0 11-11
138 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 15994 0 10-22
137 QT/Win32
Qt와 C++11 댓글+ 2
no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 16022 1 10-12
136 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 17844 0 10-09
135 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11585 0 10-02
134 QT/Win32 no_profile devilqoo 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 14584 0 10-01
133 QT/X11 no_profile 별님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 8420 0 09-25
132 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10200 0 09-16
131 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10770 0 09-03
130 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10618 0 09-02
129 QT/Win32 no_profile tmdwn 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 11022 2 09-02
128 QT/X11 no_profile 나무나무나무 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 13366 0 07-25
127 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10261 2 07-11
126 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 13768 2 07-09
125 QT/Win32 no_profile 구름님 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 10079 2 07-08
게시물 검색

  • 게시물이 없습니다.

회원로그인

설문조사

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

접속자집계

오늘
126
어제
651
최대
4,337
전체
4,923,731

Copyright © korone.net. All rights reserved.