(四)C++的异常处理和堆栈信息
1. c++标准异常
#include <exception>
// std::exception
2. 堆栈信息
获取堆栈信息,主要是使用execinfo.h
中定义的几个函数.
在抛出异常之后,通过execinfo.h
中定义的函数,获取堆栈信息,有助于定位问题.
/* Copyright (C) 1998-2016 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#ifndef _EXECINFO_H
#define _EXECINFO_H 1
#include <features.h>
__BEGIN_DECLS
/* Store up to SIZE return address of the current program state in
ARRAY and return the exact number of values stored. */
extern int backtrace (void **__array, int __size) __nonnull ((1));
/* Return names of functions from the backtrace list in ARRAY in a newly
malloc()ed memory block. */
extern char **backtrace_symbols (void *const *__array, int __size)
__THROW __nonnull ((1));
/* This function is similar to backtrace_symbols() but it writes the result
immediately to a file. */
extern void backtrace_symbols_fd (void *const *__array, int __size, int __fd)
__THROW __nonnull ((1));
__END_DECLS
#endif /* execinfo.h */
3. 自定义异常类
BacktraceException.h
/*
* BacktraceException.h
*
* Created on: 2018-6-10
*/
#ifndef BACKTRACEEXCEPTION_H_
#define BACKTRACEEXCEPTION_H_
#include <exception>
#include <string>
class BacktraceException : public std::exception
{
public:
BacktraceException(const std::string& msg);
virtual ~BacktraceException()throw();
const char* what()const throw()override;
const char* stackTrace()const throw();
private:
void fillStackTace();
private:
std::string msg_;
std::string stack_;
};
#endif /* BACKTRACEEXCEPTION_H_ */
BacktraceException.cpp
/*
* BacktraceException.cpp
*
* Created on: 2018-6-10
* Author:
*/
#include <execinfo.h>
#include <stdlib.h>
#include "BacktraceException.h"
BacktraceException::BacktraceException(const std::string& msg):msg_(msg) {
fillStackTace();
}
BacktraceException::~BacktraceException() throw() {
// TODO Auto-generated destructor stub
}
const char* BacktraceException::what()const throw(){
return msg_.c_str();
}
const char* BacktraceException::stackTrace()const throw(){
return stack_.c_str();
}
void BacktraceException::fillStackTace(){
const int len = 200;
void* buffer[len];
int nptrs = ::backtrace(buffer, len);
char** strings = ::backtrace_symbols(buffer, nptrs);
if (strings)
{
for (int i = 0; i < nptrs; ++i)
{
stack_.append(strings[i]);
stack_.push_back('\n');
}
free(strings);
}
}
测试
#include "BacktraceException.h"
#ifdef TEST_BACKTRACE_EXCEPTION
#include <iostream>
int main()
{
try{
throw BacktraceException("this is an BacktraceException");
}catch(BacktraceException &e){
std::cout<<e.what()<<std::endl;
std::cout<<e.stackTrace()<<std::endl;
}
}
#endif // TEST_BACKTRACE_EXCEPTION