連続都市伝説シリーズ:try~catchで落ちなくなる

背筋も凍る伝説を紹介します。

Windowsアプリケーションの開発者の間で今も綿々と語り継がれる対処法のようです。

対処法名称:

アプリが落ちないようにするコーディング

この対処が効く"落ち方":

例外処理 (初回) は xxxxxxxxx.exe にあります: 0xC0000005: Access Violation。

対処内容:

アプリ実行中に落ちてしまうWin32API呼び出しやMFCのメンバ関数呼び出しをtry~catchで囲めばよい。

対処例:

try{ 
  //load "MapCOM32.DLL"
  filepath = OfwPath + "\\program\\MapCOM32.dll";
  m_hInstance = LoadLibraryEx(filepath,NULL,0);

  void* (*NewCommand)(char* fileName);

  //get pointer of new function
  NewCommand = (void* (*)(char*))GetProcAddress  (m_hInstance,"newCmd");
  m_pEqCom = (EquipmentCOM *)NewCommand(fileName
}

catch ( ... ){
  LogExceptionAny( __FILE__, __LINE__ );

  return E_PLC_UNEXPECTED;
}

Insider.NETの投稿から引用

対処レベル:

ジョーシキ度:★★★★★

お勧め度:★★★★★

これと全く同じことをやってるコードをメンテさせらました。毎日気がめいりました。どうせまともなテストプロセスも無いようなので、全体的に直したいのですが、

できるだけ今回と関係の無いところは触らないようにしましょう!

という理解不能の制限をかけられて困っています。後の人の為にバグをとっておくのが礼儀だそうです。

さて、外部のライブラリを呼び出す部分に、try~catchが多数後付してあり、catch節の中では"何もしない"という。普通エラーログぐらいは出しておかないと、デバッガで見ない限りどこで例外が飛んでいるかさえわからないわけですが。

私自身、例外はほとんど利用したことがありませんが、アクセス違反(AV)をtry~catchするのが正しい対処だとはとても思えず、調べてみました。

Hardcode  try to catch … access violation

それってば、VC2005以降では使えないって知ってた?

A Visual C++ Exception FAQ

それはVC5~VC2003の"バグ"なんですよw

How to trap all exceptions  Visual C++ General  [LOC] MSDN Forums

MSFTの人って、やっぱ何にもわかってないのな。

あとは雑多なリンク:

[Insight-users] Please help with access violation error!!! (partly solved)

Visual C++ exception handling » Semicolon

とにかく先にあげたInsider.NETのコメントに激しく同意します。

ただ、アクセス違反をtry-catchしますかねぇ・・・

APIを呼び出して、帰り値をチェックしておかしければAPIの使い方に問題があるのが第一です。第二が環境依存のコードになってること。第十くらいでAPIのバグを考えます。

AVが出るからといって、"とりあえずtry~catchで囲っておけ"というのは、やってはいけない対処だと思います。

さらに進んで、

"API呼び出しの前後にtry~catchを入れていないってどういうことスカ。デフォルトでいれておくもんでしょ。

AVで落ちたら責任とれるんスカ。"

とほざく人の阿呆面を見るのが最近心の底からいやになってきました。

このtry~catchが蔓延した部分を直さないと、VC6から別の開発環境に移行しただけで、AVがでまくることが予想されます。

# AVが出る根本原因を放置して、

# 暗黙的なリトライ動作を実装しているカタチになっているため

ちなみに、急場しのぎのコードが残存している、というレベルではありません。そこらじゅうにあります;;


リンク
(非)連続都市伝説