64bitプラットフォームでの構造化例外の使用 – プログラミング – Home

64bitプラットフォームでの構造化例...
 
通知
すべてクリア

[解決済] 64bitプラットフォームでの構造化例外の使用


そうま
 そうま
(@そうま)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

はじめて質問させていただきます。
そうまと申します。宜しくお願いいたします。

現在、VisualStudio2005(言語:C++)を使用してプログラムの開発を行
っております。

そのプログラムにて構造化例外を使用しているのですが、アクセスバイオ
レーションや0除算が発生した場合でも通常のtry catch(__try __catch
ではなく)でエラー情報を取得できるように以下のようなクラスを定義し
て使用しています。
(これは、AdvancedWindows改定第4版の894ページ以降の記述を参考にし
て作成しました。)

class CSeh
{
public:

  static _se_translator_function MapSEtoCE(){ return(_set_se_translator(
TranslateSEtoCE )); }
  static void MapSEtoCE(_se_translator_function p_func){ _set_se_translator(
p_func ); }
  operator DWORD(){return(m_er.ExceptionCode);}

private:
  CSeh(PEXCEPTION_POINTERS pep)
  {
    m_er = *pep->ExceptionRecord;
    m_context = *pep->ContextRecord;
  }
  static void _cdecl TranslateSEtoCE( UINT dwEC, PEXCEPTION_POINTERS pep )
  {
    throw CSeh(pep);
  }

  CSeh operator= ( CSeh & );
private:
  EXCEPTION_RECORD m_er; //CPUに依存しない例外情報
  CONTEXT m_context; //CPUに依存する例外情報
};

上記クラスを作成して使用した場合32bitプラットフォームだと問題なく動作します。
ちなみに動作を確認した環境は2000Serverと2003Serverです。

しかし、プラットフォームを64bit環境(OSは2003Serverです)にした場合、うまく
動作しません。
通常のエラー情報をthrowした場合は正常にcatchしているのですが、アクセスバイオ
レーションや0除算が発生した場合にcatchしれくれないのです。
MSDNを調べたり色々と検索等も行ったのですが有力な情報を得ることはできませんで
した。

64Bit環境で構造化例外が使用できないとは思えず、なにかしらの設定に問題があるの
ではと思っていますが原因を解明できずにいます。
どうすれば64Bit環境でも正常にアクセスバイオレーションや0除算などの例外をcatch
できるのでしょうか?
※ちなみに上記のクラスを使用することを前提としております。

ご存知の方、ご教授の程宜しくお願いいたします。


引用未解決
トピックタグ
Multi Posting
 Multi Posting
(@Multi Posting)
ゲスト
結合: 19年前
投稿: 15
 

http://m--takahashi.com/bbs/default.aspx?c=14018

> ■ マルチポストについて
>
> マルチポストとは、「同じ内容の質問などを複数の掲示板等に書き込むこと」です。
>この行為は
> マナー違反として嫌われています。マルチポストは行わないで下さい。
>
>
> 誤ってマルチポストしてしまった場合には、必ず全ての掲示板にどのように
> 解決したかを記述し、かつお礼を書き込んで下さい。


返信引用
そうま
 そうま
(@そうま)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

申し訳ありません。
以後、注意いたします。


返信引用
そうま
 そうま
(@そうま)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

追記です。
本件に関してですが、いまだ解決しておりません。
ご教授のほど宜しくお願いいたします。


返信引用
kure
 kure
(@kure)
ゲスト
結合: 19年前
投稿: 48
 

参考になるかわかりませんが

↓の記事を読むと

http://blogs.msdn.com/cbrumme/archive/2003/10/01/51524.aspx

64bit環境と32bit環境では例外処理のアーキテクチャそのものが異なるらしく
32bit用の構造化例外をそのまま適用することはできなさそうです。

で、その代わりに64bit環境でも使用できるようにVectoredExceptionHandlingの
機構を用意してるらしいとのこと。

ためしにAddVectoredExceptionHandler辺りを調べてみると何かいいことがあるかも?

# 参考までにWin32の例外処理についての記事を
# http://msdn.microsoft.com/msdnmag/issues/01/09/hood/


返信引用
そうま
 そうま
(@そうま)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

kure様ありがとうございます。
早速記事を読んでみることにします。

あと、根本的なことを記述していませんでしたので追記します。
現在作成中のプログラムはexeではなく、dllです。
javaからコールできるように作成しています。
今、色々と試しているのですがexe(最小のプログラムを作成して検証
しました。)だと同じように独自のクラスを使用した場合でもアクセス
バイオレーションなどをcatchしてくれました。
dllだからとか、その辺の兼ね合いがあるのでしょうか?

宜しくお願いいたします。


返信引用
kure
 kure
(@kure)
ゲスト
結合: 19年前
投稿: 48
 

んー?
dllを呼び出して使うスレッドが複数あったりましませんか?
_se_set_translatorは変換を必要とするすべてのスレッドで
呼び出しておく必要があります。

どこかでWin XPの64bit版のCPP版だとWow64をかませないとSEHをとれないとか
って記事を見たような気がしますが、そんなことなさそうだし。。。


返信引用
そうま
 そうま
(@そうま)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

kure様に教えていただいた記事を参照しました。
英語ができない身ですから翻訳サイトを活用しましたがイマイチ理解できなかった
です。せっかくの情報を活かしきれず申し訳ありません。

昨日に引き続き色々と試している最中ですが現段階で以下のことが解っています。

構造化例外をキャッチするexeプログラムを実行した場合、64bit環境でもキャッチ
できる。→これは前にも書いたとおりです。

次に構造化例外を発生させキャッチする関数部分をdllにし、それをexe側から呼ん
だ場合の動作を検証。(このdllはJNIではありません)
→これも正常にキャッチされました。

最後に上記で作成したdllをJNIにしてjava側から呼んだ場合、構造化例外がキャッチ
されずプログラムが異常終了しました。

以上のことからJNIを作成する上で何か問題があるのではと思えました。
java側に何かしら設定がいるのか?そこら辺りはさっぱりですが。
なので、もう少し調べて解らなければjava側の方で質問をと考えております。

本件に関しては解決とはせず、このままにしておこうと思います。
※java側等で解決した際にこちらも解決にしようと思います。

引き続き何か有力な情報等ございましたらご教授くださいますようお願い致します。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

64BIT版の知識はないのですが、javaって32BITじゃないですか?
OS対応して32BIT⇔64BITに対応できるならいいのですが......
JNI使うにも相手のjavaがどんな常態か(32BITなのか64BITなのか)知る必要が
あるとおもいます。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

64BIT版のjavaも正式版じゃないのがダウンロードできるみたいですね。
でも、32BIT版が主流だとするとそこら辺のI/Fを考えないといけなそうですね。


返信引用
そうま
 そうま
(@そうま)
ゲスト
結合: 18年前
投稿: 6
Topic starter  

本件解決することができました。

さて、詳細ですが当時JAVAは64bit版(JDK1.5.0.5)を使用しておりました。
64bit環境にはベクトル化例外ハンドラ(VEH)というものがあるそうです。
ベクトル化例外ハンドラは、構造化例外ハンドラ(SHE)が呼び出される前に
呼び出されるそうです。これによりNULL参照などした場合にSEHより先にVEH
が例外情報をとってしまいプログラムが異常終了していました。

VEHを使用するように処理を変更する手もありましたが、今回はやめました。
というのもJDK1.5.0.8ではこのVEHを使用しないよう修正されています。
これにより現状の処理をそのまま使用することができるようになりました。

意見を下さった方、ありがとうございました。


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

http://m--takahashi.com/bbs/default.aspx?c=14018

> ■ マルチポストについて
 -- snip --
> 誤ってマルチポストしてしまった場合には、必ず全ての掲示板にどのように
> 解決したかを記述し、かつお礼を書き込んで下さい。


返信引用
kure
 kure
(@kure)
ゲスト
結合: 19年前
投稿: 48
 

JVMの実装によって挙動が変わるネイティブコードねぇ。。。
(JVMの実装で挙動が変わるJavaコードならわからんでもないが)
そんなん仕事でもってこられたら即つっぱねるけどなぁ。

前にあげた記事の2つ目読んでもらえばわかると思うんだけど、
VEHはプロセス単位で仕込むことができるし、
たぶん(やってみてないからわからん)だが
JVMのVEHを横取りもできるっぽいわけで。
なにより、64bit環境ではVEH使うのが筋らしいことを鑑みれば
VEHを使わないのが正しいとはとても思えないんだが。。。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました