assert などのインターセプト – プログラミング – Home

assert などのインターセプト
 
通知
すべてクリア

[解決済] assert などのインターセプト

固定ページ 1 / 2

熱血
 熱血
(@熱血)
ゲスト
結合: 15年前
投稿: 100
Topic starter  

MFC VC++6.0 XP
エディターを作成中なのですが、assertなどでプログラムがストップする場合に、先に
編集中のファイルをテンポラリファイルにセーブしてから、プログラムを終了するよう
に、一度assertをインターセプトするようなことは、できないのでしょうか?
お詳しい方、よろしくお願いします。


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

正常終了(exit)なら atexit で終了時のハンドラを登録できますが、
assertによる異常終了はこれでもハンドルされません。


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

既にあるようにトラップは標準的な方法では無理ですが、C言語であれば
assertで呼ばれるabortがファイルストリームをフラッシュすることは
言語仕様に規定があるので(ISO/IEC9899:1999)、
assertするような処理の前に常にテンポラリファイルに吐き続けていれば、
それはおそらく残るかと。

# そもそも、assert/abortなんて実行時に起きたらいけないものなわけで、
# 起きないようにデバッグする方を考えるべきだと思いますが。


返信引用
熱血
 熱血
(@熱血)
ゲスト
結合: 15年前
投稿: 100
Topic starter  

επιστημηさん、bunさん、レスありがとうございます。
上司の男の方に聞くと、昔は瞬間停電とかの対策で、
なんか、マシンが落ちる前に、なんらかの処理が必要だったそうですが、
そういうことは、もう考える必要がないんですね。
エディターが編集途中で落ちちゃうと致命的なので、がんばってバグとりすることにし
ます。ありがとうございました。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

質問の意図が分からないのでなんともですが、

Banさんが言われている通り、assertが出ない状態にまでするのが前提ですし、
あと、Releaseモードではassertが出るような状態になっても出ずに走ってしまうので
その場では落ちなくても先々でおかしくなるとかそういう事になります。
なのでassertはむしろありがたい物なんです。

デバッグ中に関してはassertで止まった時は仕方が無いとあきらめるしか無いと
思いますよ。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

あと、瞬間停電とassertを一緒にしてはいけません。
瞬間停電はプログラマの責任では有りませんが、
assertが起きるのはプログラマの責任です。

それに瞬間停電を恐れるのであれば、
今は無停電電源装置が割りと安く出回っていますから
そっちで対策で来ますよね。


返信引用
熱血
 熱血
(@熱血)
ゲスト
結合: 15年前
投稿: 100
Topic starter  

PATIOさん、レスありがとうございます。
エディタを作っていて、落ちまくります。実際編集していて、落ちて、編集内容がパー
になってしまうと、たいがいへこみます。
なんとか、簡単にそこのところだけでも、対策できないかなぁ・・・と質問してみたの
ですが、どうも、まず、バグとりに励むしかないようですね。
ありがとうございました。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

ランタイム内で落ちてるとだめだけど、自分で入れたアサートないし、
コードインクルードなら当該のコードを{__asm int 3}で
置き換えるとデバッグできます。何度も救われていますint 3 には(^^;)。


返信引用
maru
 maru
(@maru)
ゲスト
結合: 17年前
投稿: 358
 

そんなことしなくても、[再試行(R)]を選択すればデバッグブレークしてくれますけど。
強制的にデバッグブレークをするなら _CrtDbgBreak(); でもいいし。
第一 int 3 割り込みでプログラムを停止させるならそこにブレークポイント仕掛ければ
いいことだし。

そんなことを言っているのではない?


返信引用
熱血
 熱血
(@熱血)
ゲスト
結合: 15年前
投稿: 100
Topic starter  

仲澤@失業者 さん、maru さん、レスありがとうございます。
仲澤@失業者 さんのレス内容についてちょっとしらべてみました。

__asm は、インラインアセンブラの記述で、
> INT 3 命令は、デバッグ例外ハンドラをコールすることを目的とする特別な
> 1 バイト・オペコード(CC)を生成する。
となっていますね・・・。
いまひとつ、どうやって使うのか、わからないんですが・・・
よろしければ、アドバイスをいただければ、幸せです。


返信引用
maru
 maru
(@maru)
ゲスト
結合: 17年前
投稿: 358
 

int 3
3番目の割り込み(interrupt)を発生させるX86のオペコード(命令)です。
3番目の割り込みはデバッグ例外ハンドラと呼ばれ一般にデバッガで使用されます。
デバッグ例外ハンドラが起動されると、そのOSにインストールされたデバッガが起動
されるようにOSが設定されています。VCがインストールされている環境ではVCが起動
され、その命令が実行された場所のデバッグが出来るようになります。

私が書いた_CrtDbgBreak();も内部では同じことをやっているはずですが、こちらは
デバッグモードでコンパイルしたプログラムしかデバッグブレークしません。

デバッガでブレークポイントを仕掛けて実行すると、その位置でプログラムが停止し
ますが、実はデバッガがその位置の命令を int 3 に置き換えて実行しているんです。
つまり、仲澤@失業者さんがやっていることはデバッガでブレークポイントを設定し
ているのとほぼ同じことをやっているわけです。


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

>エディタを作っていて、落ちまくります。実際編集していて、落ちて、編集内容がパー
>になってしまうと、たいがいへこみます。
>なんとか、簡単にそこのところだけでも、対策できないかなぁ・・・と質問してみたの
>ですが、どうも、まず、バグとりに励むしかないようですね。

一応下記のようにあらゆる例外をキャッチするようにしておけば
実行時の強制終了まで補足されてしまいます。

try {
//処理
}
catch(...) {
//ここでエディタの内容を保存?
throw;
}


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

>実行時の強制終了まで補足されてしまいます。
補足じゃなくて捕捉です。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

maruさん、わざわざ説明してもらってすみません。

少し補足すると、既にコード済みのアサート相当コード
「MyAssert(n)」に対して

#define MyAssert(n) if(n){__asm int 3}

みたいなコードををプリコンパイルヘッダに入れると、
便利ですよと言いたかったわけです。
この方法の良いところはプリコンパイル以外はいじらなくても
また、いちいち手動でブレークポイントを設定しなくても
アサート抜けを全てブレークできることです。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

assert っつのは「プログラムがバグっていることの証明」なわけで、
assert したときに「データを正しく保存する」ことが可能かどうかなど不明。

だって明らかにバグっていることがわかった状態なわけだぜ。
・エディタが保持しているデータが破壊されている
・保存すべきファイル名が破壊されている
その他、何が正しくて何が破壊されているか、なんてことはわかりっこない。
俺ならば「不正なデータは保存しないほうが安全だ」と思うわけだ。

その意味で assert が出ないようにバグ修正するなんてのは必須なのであって
assert が出たときに何か対処する方策がないか?なんて調べるのは道を外れている。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

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