バグ:エラーメッセージの取得ではどのAPIを使うべきか

Posted: 2013年06月03日

文字列操作(エラーメッセージの取得)で書いてしまうバグを紹介します。

プログラムプログラム:

 #include <stdio.h>

 int main(int argc, char *argv[])
 {
    char szErrorMsg[256];
    int nErrorNo;

    // 処理

    _strerror_s(szErrorMsg, 256, nErrorNo);
    puts(szErrorMsg);

    return 0;
 }

このプログラムにどのように文字列操作(書式文字列の取得)にバグが存在すると思いますか?

  • strerrorでは、よりもFormatMessageのほうが広範囲のエラーメッセージを取得できる

改善版プログラム改善版プログラム:

 #include <stdio.h>

 int main(int argc, char *argv[])
 {
    char szErrorMsg[256];
    int nErrorNo;

    // 処理

    FormatMessage(
            FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            nErrorNo,
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
            (LPTSTR) &szErrorMsg,
            sizeof(szErrorMsg) / sizeof(TCHAR),
            NULL);
    puts(szErrorMsg);

    return 0;
 }

解説解説:

strerrorとFormatMessageでは、エラーメッセージの内容は同じだが
一部strerrorでは、取得できないエラーコードが存在します。

strerrorは、標準関数で
FormatMessageは、Windows用関数のため
違いが出ていると考えられます。

私としては、標準関数をなるべく使用したほうが
依存するAPIが変更されても影響がないためおすすめと思っていますが

このように動作が異なる場合は、
仕方なく専用関数を使用したほうがいいでしょう

エラーメッセージが取得できないで
問題解決に時間がかかるよりも、
修正するリスクを含んでも解決する工数が短くなれば
絶対メリットがあると思うからです。

ちなみにエラー番号の取得は、
GetLastErrorやerrnoグローバル変数を用いて取得ができます。

カテゴリー: バグ, プログラム | タグ: , , | コメント無し »

コメント