muduoネットワークライブラリソース再現ノート(三):baseライブラリのException.h
3187 ワード
Muduoネットワークライブラリの概要
muduoはReactorモードに基づく現代C++ネットワークライブラリであり,著者の陳碩である.非ブロックIOモデルを採用し、イベント駆動とコールバックに基づいて、原生はマルチコアマルチスレッドをサポートし、Linuxサービスエンドマルチスレッドネットワークアプリケーションの作成に適しています.muduoネットワークライブラリのコアコードは数千行しかなく、ネットワークプログラミング技術学習の段階では、muduoは非常に学習に値するオープンソースライブラリである.現在、私もこのネットワークライブラリのソースコードを勉強し始めたばかりで、この学習過程を記録したいと思っています.このネットワークライブラリのソースコードはGitHubに公開されており、ここをクリックして読むことができます.現在Github上のこのソースコードは作者にc++11で書き換えられており、私が勉強しているバージョンはc++11バージョンを使用していません.しかし、両者は大同小異で、核心思想は変化していない.ここをクリックして私のソースコードを見ることができて、もしあなたが私の前のブログに興味があれば、次の接続をクリックすることができます:muduoネットワークライブラリのソースコードの再現ノート(一):baseライブラリのTimestamp.h muduoネットワークライブラリソースコード再現ノート(二):baseライブラリのAtomic.h
Exception.h
Exceptionクラスは簡単で、異常イベントのパッケージです.クラスコードを見てみましょう.
ここで注目すべき関数は、2つのプライベートメンバー関数fillStackTrace()とdemangle()関数です.次に分析します.
FillStack()関数
FillStack関数の役割は,現在のスレッドのスタックフレーム情報を取得し,可読性の強いコンテンツに変換して印刷することである.コードを見てみましょう.
fillStackTrace()では、まず、関連するスタックフレーム情報を格納できる汎用ポインタ配列bufferを定義します.次にbacktrace関数を使用して、現在のスレッドのスタックフレーム情報を取得します.backtrace関数のプロトタイプは次のとおりです.
sizeパラメータは、bufferに格納できる情報の数を指定します.戻り値は、実際に返される情報の数です.次にbacktrace_を使用しますSymbolsはbufferの情報を文字列配列に変換し、関数のプロトタイプは
でもbacktrace_Symbols関数が返す情報の可読性はよくありません.コンパイラは定義した関数に新しい名前を与えるので、この新しい名前を可読な名前に翻訳する必要があります.この機能はdemangle関数で完了します.
demangle関数
demangle関数の機能は前述したようにstringsの文字列情報を可読性の良い情報に翻訳するものである.コード:
元の情報を可読性の高い情報に変換するコアの作業cxa_demangleが完了しました.関数のプロトタイプ:
muduoはReactorモードに基づく現代C++ネットワークライブラリであり,著者の陳碩である.非ブロックIOモデルを採用し、イベント駆動とコールバックに基づいて、原生はマルチコアマルチスレッドをサポートし、Linuxサービスエンドマルチスレッドネットワークアプリケーションの作成に適しています.muduoネットワークライブラリのコアコードは数千行しかなく、ネットワークプログラミング技術学習の段階では、muduoは非常に学習に値するオープンソースライブラリである.現在、私もこのネットワークライブラリのソースコードを勉強し始めたばかりで、この学習過程を記録したいと思っています.このネットワークライブラリのソースコードはGitHubに公開されており、ここをクリックして読むことができます.現在Github上のこのソースコードは作者にc++11で書き換えられており、私が勉強しているバージョンはc++11バージョンを使用していません.しかし、両者は大同小異で、核心思想は変化していない.ここをクリックして私のソースコードを見ることができて、もしあなたが私の前のブログに興味があれば、次の接続をクリックすることができます:muduoネットワークライブラリのソースコードの再現ノート(一):baseライブラリのTimestamp.h muduoネットワークライブラリソースコード再現ノート(二):baseライブラリのAtomic.h
Exception.h
Exceptionクラスは簡単で、異常イベントのパッケージです.クラスコードを見てみましょう.
class Exception : public std::exception
{
public:
explicit Exception(const char* what);
explicit Exception(const string& what);
virtual ~Exception() throw();
virtual const char* what() const throw();
const char* stackTrace() const throw();
private:
void fillStackTrace(); //
string demangle(const char* symbol);//
string message_; //
string stack_;//
};
ここで注目すべき関数は、2つのプライベートメンバー関数fillStackTrace()とdemangle()関数です.次に分析します.
FillStack()関数
FillStack関数の役割は,現在のスレッドのスタックフレーム情報を取得し,可読性の強いコンテンツに変換して印刷することである.コードを見てみましょう.
void Exception::fillStackTrace()
{
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)
{
// TODO demangle funcion name with abi::__cxa_demangle
//stack_.append(strings[i]);
stack_.append(demangle(strings[i]));
stack_.push_back('
');
}
free(strings);
}
}
fillStackTrace()では、まず、関連するスタックフレーム情報を格納できる汎用ポインタ配列bufferを定義します.次にbacktrace関数を使用して、現在のスレッドのスタックフレーム情報を取得します.backtrace関数のプロトタイプは次のとおりです.
int backtrace(void **buffer, int size);
sizeパラメータは、bufferに格納できる情報の数を指定します.戻り値は、実際に返される情報の数です.次にbacktrace_を使用しますSymbolsはbufferの情報を文字列配列に変換し、関数のプロトタイプは
char **backtrace_symbols(void *const *buffer, int size);
でもbacktrace_Symbols関数が返す情報の可読性はよくありません.コンパイラは定義した関数に新しい名前を与えるので、この新しい名前を可読な名前に翻訳する必要があります.この機能はdemangle関数で完了します.
demangle関数
demangle関数の機能は前述したようにstringsの文字列情報を可読性の良い情報に翻訳するものである.コード:
string Exception::demangle(const char* symbol)
{
size_t size;
int status;
char temp[128];
char* demangled;
//first, try to demangle a c++ name
if (1 == sscanf(symbol, "%*[^(]%*[^_]%127[^)+]", temp)) {
if (NULL != (demangled = abi::__cxa_demangle(temp, NULL, &size, &status))) {
string result(demangled);
free(demangled);
return result;
}
}
//if that didn't work, try to get a regular c symbol
if (1 == sscanf(symbol, "%127s", temp)) {
return temp;
}
//if all else fails, just return the symbol
return symbol;
}
元の情報を可読性の高い情報に変換するコアの作業cxa_demangleが完了しました.関数のプロトタイプ:
char *__cxa_demangle (const char *mangled_name, char *output_buffer, size_t *length, int *status);