(四)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
posted @ 2018-06-10 22:33  yvhqbat  阅读(1727)  评论(0编辑  收藏  举报