C++でcatchの中でどこからthrowされたか見る方法はあるのか。
C++でcatchの中でどこからthrowされたか見る方法はあるのかっていうこと。
コンパイラ依存とかはあんまり気にしない。
色々調べた結果、多分できなくはないっぽいが、やる意味がないと思われるという結論に達した。
可能であることの説明。
とりあえずVC++6のデバッガで見ていたのだがcatchの中ではESPの値はまだ巻き戻されていないっぽい。
void test() { printf("throw!"); throw std::exception("aaa"); } void main() { int a = 0; try { test(); } catch(std::exception &e) { printf("%d %p",a,&e); } }
ESP とかをデバッガで追っていくとこんな感じになります。
void test() { printf("throw!"); //ここの直前 //ESP = 0012FEB8 EBP = 0012FF14 EIP = 00401085 throw std::exception("aaa"); } void main() { int a = 0; try { //ここの直前 //ESP = 0012FF1C EBP = 0012FF80 EIP = 004010FF test(); } catch(std::exception &e) { //ここの直前 //ESP = 0012F894 EBP = 0012FF80 EIP = 00401106 printf("%d %p",a,&e); } }
ESP は上に伸びるので、スタックに詰まれるたびに値が減っていく。
//try句の中での関数コール直前
ESP = 0012FF1C
↓
//throwの直前
ESP = 0012FEB8
↓
//catchの中
ESP = 0012F894
スタックは伸びていて巻き戻されていない。
と、いうことは、関数のコールスタックはまだ追跡可能である。
ここで、スタックトレースなどを行ってスタックをトレースすればどこで throw されたかわかるはずだ。
余談ですが、伸びたESPがどこでリセットされるかっていうのは、 catchした関数からreturnしたときだと思う。
この場合、main関数の最後になる。
要するに関数を呼び出したときにプロローグで push ebp; mov ebp,esp; しているわけで、
関数を抜けるときに mov esp,ebp; pop ebp; で ESP を復元するわけぢゃないですか。それに便乗してESPが復元される。
スタックを見てみると、こんな感じになった。
0012F894 67 69 40 00 00 00 00 gi@.... 0012F89B 00 00 00 00 00 B0 F8 .....ー. 0012F8A2 12 00 74 FF 12 00 00 ..t.... 0012F8A9 00 00 00 80 FF 12 00 ....... 0012F8B0 E8 F8 12 00 A2 19 40 顏..「.@ 0012F8B7 00 06 11 40 00 74 FF ...@.t. 0012F8BE 12 00 00 01 00 00 00 ....... 0012F8C5 00 00 00 00 00 00 00 ....... 0012F8CC 00 00 00 00 7A 9F 80 ....z麾 0012F8D3 7C 30 F9 12 00 C0 19 |0...タ. 0012F8DA 40 00 78 67 42 00 74 @.xgB.t 0012F8E1 FF 12 00 01 00 00 00 ....... 0012F8E8 40 F9 12 00 C5 64 40 @...ナd@ 0012F8EF 00 74 FF 12 00 78 67 .t...xg 0012F8F6 42 00 06 11 40 00 00 B...@.. 0012F8FD 00 00 00 00 01 00 00 ....... 0012F904 00 00 00 00 00 00 00 ....... 0012F90B 00 00 00 00 00 08 FF ....... 0012F912 12 00 06 11 40 00 1C ....@.. 0012F919 FF 12 00 00 00 00 00 ....... 0012F920 00 00 00 00 00 00 00 ....... 0012F927 00 04 F9 12 00 AC 18 .....ャ. 0012F92E 40 00 54 FA 12 00 50 @.T...P 0012F935 7F 40 00 F0 5B 42 00 .@.B. 0012F93C 01 00 00 00 6C F9 12 ....l.. 0012F943 00 1A 64 40 00 28 FB ..d@.(. 0012F94A 12 00 74 FF 12 00 48 ..t...H 0012F951 FB 12 00 78 67 42 00 ...xgB. 0012F958 06 11 40 00 00 00 00 ..@.... 0012F95F 00 00 01 00 00 1C FF ....... 0012F966 43 03 74 FF 12 00 D0 C.t...ミ 0012F96D F9 12 00 F9 5F 40 00 ...@. 0012F974 28 FB 12 00 74 FF 12 (...t.. 0012F97B 00 48 FB 12 00 FC FA .H...・ 0012F982 12 00 78 67 42 00 C0 ..xgB.タ 0012F989 67 42 00 58 67 42 00 gB.XgB. 0012F990 A8 67 42 00 00 00 00 ィgB.... 0012F997 00 00 00 00 00 00 00 ....... 0012F99E 00 00 A0 F0 9A 7C FF ...|. 0012F9A5 FF FF FF 00 00 00 00 ....... 0012F9AC 01 00 00 00 01 00 00 ....... 0012F9B3 00 C0 67 42 00 94 66 .タgB.杷 0012F9BA 42 00 00 00 00 00 A8 B.....ィ 0012F9C1 67 42 00 01 00 00 00 gB..... 0012F9C8 00 F9 12 00 00 00 00 ....... 0012F9CF 00 00 FA 12 00 C3 5D .....テ] 0012F9D6 40 00 28 FB 12 00 74 @.(...t 0012F9DD FF 12 00 48 FB 12 00 ...H... 0012F9E4 FC FA 12 00 78 67 42 ・..xgB 0012F9EB 00 00 FB 12 00 00 00 ....... 0012F9F2 00 00 00 00 00 00 00 ....... 0012F9F9 00 00 00 EC F9 12 00 ...・.. 0012FA00 3C FA 12 00 0C 19 40 <.....@ 0012FA07 00 28 FB 12 00 74 FF .(...t. 0012FA0E 12 00 48 FB 12 00 FC ..H.... 0012FA15 FA 12 00 78 67 42 00 ...xgB. 0012FA1C 00 00 00 00 00 00 00 ....... 0012FA23 00 00 00 00 00 00 00 ....... 0012FA2A 00 00 00 00 00 00 00 ....... 0012FA31 00 00 00 78 67 42 00 ...xgB. 0012FA38 0A D8 94 7C 60 FA 12 .リ培`.. 0012FA3F 00 A8 32 94 7C 28 FB .ィ2培(. 0012FA46 12 00 74 FF 12 00 48 ..t...H 0012FA4D FB 12 00 FC FA 12 00 ...・.. 0012FA54 74 FF 12 00 BC 32 94 t...シ2. 0012FA5B 7C 74 FF 12 00 10 FB |t..... 0012FA62 12 00 7A 32 94 7C 28 ..z2培( 0012FA69 FB 12 00 74 FF 12 00 ...t... 0012FA70 48 FB 12 00 FC FA 12 H...・. 0012FA77 00 30 3B 41 00 A8 FE .0;A.ィ. 0012FA7E 12 00 28 FB 12 00 74 ..(...t 0012FA85 FF 12 00 0F AA 96 7C ....ェ翻 0012FA8C 28 FB 12 00 74 FF 12 (...t.. 0012FA93 00 48 FB 12 00 FC FA .H...・ 0012FA9A 12 00 30 3B 41 00 A8 ..0;A.ィ 0012FAA1 FE 12 00 28 FB 12 00 ...(... 0012FAA8 A8 FE 12 00 00 00 14 ィ...... 0012FAAF 00 61 01 00 50 0F 93 .a..P.. 0012FAB6 95 7C 00 00 00 00 54 怖....T 0012FABD FF 12 00 00 00 14 00 ....... 0012FAC4 A8 A9 AA AB F8 FC 12 ィゥェォ. 0012FACB 00 20 E9 94 7C A0 F0 . 髞|.. 0012FAD2 9A 7C FF FF FF FF 7C 嘶....| 0012FAD9 F0 9A 7C 00 00 14 00 |.... 0012FAE0 DC F8 12 00 61 01 00 ワ...a.. 0012FAE7 50 1C FD 12 00 20 E9 P.... . 0012FAEE 94 7C 18 93 95 7C FF 培.燈|. 0012FAF5 FF FF FF 0F 93 95 7C ....燈| 0012FAFC 21 8F 95 7C 00 00 14 !助|... 0012FB03 00 00 00 13 00 00 E0 ....... 0012FB0A 12 00 01 00 00 00 68 ......h 0012FB11 FE 12 00 8A E4 94 7C ...贋培 0012FB18 00 00 00 00 48 FB 12 ....H.. 0012FB1F 00 28 FB 12 00 48 FB .(...H. 0012FB26 12 00 63 73 6D E0 01 ..csm.. 0012FB2D 00 00 00 00 00 00 00 ....... 0012FB34 FB 2A 81 7C 03 00 00 .*−... 0012FB3B 00 20 05 93 19 08 FF . ..... 0012FB42 12 00 98 66 42 00 3F ..惑B.? 0012FB49 00 01 00 00 00 00 00 ....... 0012FB50 00 00 00 00 00 00 00 ....... 0012FB57 00 00 00 00 00 00 00 ....... 0012FB5E 00 00 00 00 00 00 7F ....... 0012FB65 02 FF FF 00 00 FF FF ....... 0012FB6C FF FF FF FF 00 00 00 ....... 0012FB73 00 00 00 00 00 00 00 ....... 0012FB7A 00 00 00 00 FF FF 00 ....... 0012FB81 00 00 00 00 00 00 00 ....... 0012FB88 00 00 00 00 00 00 00 ....... 0012FB8F 00 00 00 00 00 00 00 ....... 0012FB96 00 00 00 00 00 00 00 ....... 0012FB9D 00 00 00 00 00 00 00 ....... 0012FBA4 00 00 00 00 00 00 00 ....... 0012FBAB 00 00 00 00 00 00 00 ....... 0012FBB2 00 00 00 00 00 00 00 ....... 0012FBB9 00 00 00 00 00 00 00 ....... 0012FBC0 00 00 00 00 00 00 00 ....... 0012FBC7 00 00 00 00 00 00 00 ....... 0012FBCE 00 00 00 00 00 00 00 ....... 0012FBD5 00 00 00 3B 00 00 00 ...;... 0012FBDC 23 00 00 00 23 00 00 #...#.. 0012FBE3 00 A8 FE 12 00 A8 FE .ィ...ィ. 0012FBEA 12 00 00 C0 FD 7F 63 ...タ..c 0012FBF1 73 6D E0 00 00 00 00 sm..... 0012FBF8 18 FE 12 00 68 FE 12 ....h.. 0012FBFF 00 FB 2A 81 7C 1B 00 ..*−.. 0012FC06 00 00 06 02 00 00 14 ....... 0012FC0D FE 12 00 23 00 00 00 ...#... 0012FC14 7F 02 00 00 00 00 00 ....... 0012FC1B 00 00 00 00 00 00 00 ....... 0012FC22 00 00 00 00 00 00 00 ....... 0012FC29 00 FF FF 80 1F 00 00 ....... 0012FC30 00 00 00 00 00 00 00 ....... 0012FC37 00 00 00 00 00 00 00 ....... 0012FC3E 00 00 00 00 00 00 00 ....... 0012FC45 00 00 00 00 00 00 00 ....... 0012FC4C 00 00 00 00 00 00 00 ....... 0012FC53 00 00 00 00 00 00 00 ....... 0012FC5A 00 00 00 00 00 00 00 ....... 0012FC61 00 00 00 00 00 00 00 ....... 0012FC68 00 00 00 00 00 00 00 ....... 0012FC6F 00 00 00 00 00 00 00 ....... 0012FC76 00 00 00 00 00 00 00 ....... 0012FC7D 00 00 00 00 00 00 00 ....... 0012FC84 00 00 00 00 00 00 00 ....... 0012FC8B 00 00 00 00 00 00 00 ....... 0012FC92 00 00 00 00 00 00 00 ....... 0012FC99 00 00 00 00 00 00 00 ....... 0012FCA0 00 00 00 00 00 00 00 ....... 0012FCA7 00 00 00 00 00 00 00 ....... 0012FCAE 00 00 00 00 00 00 00 ....... 0012FCB5 00 00 00 00 00 00 00 ....... 0012FCBC 00 00 00 00 00 00 00 ....... 0012FCC3 00 00 00 00 00 00 00 ....... 0012FCCA 00 00 00 00 00 00 00 ....... 0012FCD1 00 00 00 00 00 00 00 ....... 0012FCD8 00 00 00 00 00 00 00 ....... 0012FCDF 00 00 00 00 00 00 00 ....... 0012FCE6 00 00 00 00 00 00 00 ....... 0012FCED 00 00 00 00 00 00 00 ....... 0012FCF4 00 00 00 00 00 00 00 ....... 0012FCFB 00 00 00 00 00 00 00 ....... 0012FD02 00 00 00 00 00 00 00 ....... 0012FD09 00 00 00 00 00 00 00 ....... 0012FD10 00 00 00 00 00 00 00 ....... 0012FD17 00 00 00 00 00 00 00 ....... 0012FD1E 00 00 00 00 00 00 00 ....... 0012FD25 00 00 00 00 00 00 00 ....... 0012FD2C 00 00 00 00 00 00 00 ....... 0012FD33 00 00 00 00 00 00 00 ....... 0012FD3A 00 00 00 00 00 00 00 ....... 0012FD41 00 00 00 00 00 00 00 ....... 0012FD48 00 00 00 00 00 00 00 ....... 0012FD4F 00 00 00 00 00 00 00 ....... 0012FD56 00 00 00 00 00 00 00 ....... 0012FD5D 00 00 00 00 00 00 00 ....... 0012FD64 00 00 00 00 00 00 00 ....... 0012FD6B 00 00 00 00 00 00 00 ....... 0012FD72 00 00 00 00 00 00 00 ....... 0012FD79 00 00 00 00 00 00 00 ....... 0012FD80 00 00 00 00 00 00 00 ....... 0012FD87 00 00 00 00 00 00 00 ....... 0012FD8E 00 00 00 00 00 00 00 ....... 0012FD95 00 00 00 00 00 00 00 ....... 0012FD9C 00 00 00 00 00 00 00 ....... 0012FDA3 00 00 00 00 00 00 00 ....... 0012FDAA 00 00 00 00 00 00 00 ....... 0012FDB1 00 00 00 00 00 00 00 ....... 0012FDB8 00 00 00 00 00 00 00 ....... 0012FDBF 00 00 00 00 00 00 00 ....... 0012FDC6 00 00 00 00 00 00 00 ....... 0012FDCD 00 00 00 00 00 00 00 ....... 0012FDD4 00 00 00 00 00 00 00 ....... 0012FDDB 00 00 00 00 00 00 00 ....... 0012FDE2 00 00 00 00 00 00 00 ....... 0012FDE9 00 00 00 00 00 00 00 ....... 0012FDF0 00 00 00 00 00 00 00 ....... 0012FDF7 00 00 00 00 00 00 00 ....... 0012FDFE 00 00 00 00 00 00 00 ....... 0012FE05 00 00 00 00 00 00 00 ....... 0012FE0C 00 00 00 00 00 00 00 ....... 0012FE13 00 98 51 42 00 63 73 .浪B.cs 0012FE1A 6D E0 01 00 00 00 00 m...... 0012FE21 00 00 00 FB 2A 81 7C ....*− 0012FE28 03 00 00 00 20 05 93 .... .. 0012FE2F 19 08 FF 12 00 98 66 .....惑 0012FE36 42 00 00 C0 FD 7F 28 B..タ..( 0012FE3D 00 00 00 00 00 00 00 ....... 0012FE44 2F 00 00 00 A8 10 38 /...ィ.8 0012FE4B 00 68 FE 12 00 B9 20 .h...ケ 0012FE52 40 00 04 00 00 00 01 @...... 0012FE59 00 00 00 00 00 00 00 ....... 0012FE60 00 00 00 00 C8 10 38 ....ネ.8 0012FE67 00 A8 FE 12 00 59 1D .ィ...Y. 0012FE6E 40 00 63 73 6D E0 01 @.csm.. 0012FE75 00 00 00 03 00 00 00 ....... 0012FE7C 9C FE 12 00 14 FF 12 ....... 0012FE83 00 00 00 00 00 63 73 .....cs 0012FE8A 6D E0 01 00 00 00 00 m...... 0012FE91 00 00 00 00 00 00 00 ....... 0012FE98 03 00 00 00 20 05 93 .... .. 0012FE9F 19 08 FF 12 00 98 66 .....惑 0012FEA6 42 00 14 FF 12 00 A6 B.....ヲ 0012FEAD 10 40 00 08 FF 12 00 .@..... //00 A6 10 40 → 004010A6 0012FEB4 98 66 42 00 70 FF 12 惑B.p.. 0012FEBB 00 00 00 00 00 00 C0 ......タ 0012FEC2 FD 7F CC CC CC CC CC ..フフフフフ 0012FEC9 CC CC CC CC CC CC CC フフフフフフフ 0012FED0 CC CC CC CC CC CC CC フフフフフフフ 0012FED7 CC CC CC CC CC CC CC フフフフフフフ 0012FEDE CC CC CC CC CC CC CC フフフフフフフ 0012FEE5 CC CC CC CC CC CC CC フフフフフフフ 0012FEEC CC CC CC CC CC CC CC フフフフフフフ 0012FEF3 CC CC CC CC CC CC CC フフフフフフフ 0012FEFA CC CC CC CC CC CC CC フフフフフフフ 0012FF01 CC CC CC 98 60 42 00 フフフ倭B. 0012FF08 48 50 42 00 C8 10 38 HPB.ネ.8 0012FF0F 00 01 00 00 00 80 FF ....... 0012FF16 12 00 04 11 40 00 00 ....@.. 0012FF1D 00 00 00 00 00 00 00 ....... 0012FF24 00 C0 FD 7F CC CC CC .タ..フフフ 0012FF2B CC CC CC CC CC CC CC フフフフフフフ 0012FF32 CC CC CC CC CC CC CC フフフフフフフ 0012FF39 CC CC CC CC CC CC CC フフフフフフフ 0012FF40 CC CC CC CC CC CC CC フフフフフフフ 0012FF47 CC CC CC CC CC CC CC フフフフフフフ 0012FF4E CC CC CC CC CC CC CC フフフフフフフ 0012FF55 CC CC CC CC CC CC CC フフフフフフフ 0012FF5C CC CC CC CC CC CC CC フフフフフフフ 0012FF63 CC CC CC CC CC 08 FF フフフフフ.. 0012FF6A 12 00 00 00 00 00 1C ....... 0012FF71 FF 12 00 B0 FF 12 00 ...ー... 0012FF78 30 3B 41 00 01 00 00 0;A.... 0012FF7F 00 C0 FF 12 00 79 1F .タ...y. 0012FF86 40 00 01 00 00 00 30 @.....0 0012FF8D 11 38 00 A8 11 38 00 .8.ィ.8. 0012FF94 00 00 00 00 00 00 00 ....... 0012FF9B 00 00 C0 FD 7F 01 00 ..タ.... 0012FFA2 00 00 06 00 00 00 94 ....... 0012FFA9 FF 12 00 2E 2A 62 80 ....*b. 0012FFB0 E0 FF 12 00 50 7F 40 ....P.@ 0012FFB7 00 A8 51 42 00 00 00 .ィQB... 0012FFBE 00 00 F0 FF 12 00 77 ......w 0012FFC5 70 81 7C 00 00 00 00 p−.... 0012FFCC 00 00 00 00 00 C0 FD .....タ. 0012FFD3 7F ED D6 54 80 C8 FF .臭T.ネ. 0012FFDA 12 00 38 33 09 88 FF ..83 .. 0012FFE1 FF FF FF D8 9A 83 7C ...リ噬| 0012FFE8 80 70 81 7C 00 00 00 .p−... 0012FFEF 00 00 00 00 00 00 00 ....... 0012FFF6 00 00 90 1E 40 00 00 ....@.. 0012FFFD 00 00 00 41 63 74 78 ...Actx
これではよく分からないと思うので、大事な場所のピックアップ。
0012FE9F 19 08 FF 12 00 98 66 .....惑 0012FEA6 42 00 14 FF 12 00 A6 B.....ヲ 0012FEAD 10 40 00 08 FF 12 00 .@..... //00 A6 10 40 → 004010A6 0012FEB4 98 66 42 00 70 FF 12 惑B.p.. 0012FEBB 00 00 00 00 00 00 C0 ......タ
ここに throw std::exception("aaa") したときの次のEIPが記録されているみたい。
VC++6では、throwするときにはこんな処理が行われるらしい。
9: throw std::exception("aaa"); 00401085 mov dword ptr [ebp-10h],offset string "aaa" (00426098) 0040108C lea eax,[ebp-10h] 0040108F push eax 00401090 lea ecx,[ebp-0Ch] 00401093 call exception::exception (004014b0) 00401098 push offset __TI1?AVexception@@ (00426698) 0040109D lea ecx,[ebp-0Ch] 004010A0 push ecx 004010A1 call __CxxThrowException@8 (00401d20) 10: } //例外の次の行 004010A6 pop edi //ここのアドレスが記録されるらしい 004010A7 pop esi 004010A8 pop ebx
push offset __TI1?AVexception@@ (00426698)とcall __CxxThrowException@8 (00401d20)に注目かなぁと。
callしているということは、現在のEIPがスタックに入っているわけですよ。
そして、それは __TI1?AVexception@@ 関数のアドレスの近くにあると。
__TI1?AVexception@@ のアドレスの求め方がよく分からないのはとりあえず置いといて、、、
えーと、つまり、、がんばればできるかもしれないということですネ。
ただ、これは自分で throw した場合ぢゃないですか。
VC++には構造化例外ってありますよね。不正なメモリ参照とかでおきるアレです。
構造化例外処理の詳しい説明はこちらのページが参考になります。
http://www.ne.jp/asahi/hishidama/home/tech/vcpp/seh.html
これはまた別バラです。
void test() { printf("throw!"); *(int*)(0) = 72; //ここで例外 } void main() { int a = 0; try { test(); } catch(...) { printf("%d",a); } }
VC++ では、バグ?仕様?で、あるバージョンまでは構造化例外が catch(...)でとれます。
途中からコンパイルオプションを指定しなければいけなっかりするそうです。
詳しいことはこちらのページをご覧ください。
http://msdn.microsoft.com/ja-jp/library/1deeycx5%28VS.80%29.aspx
で、ESPとかを追っていくとこんな感じになりました。
void test() { printf("throw!"); //ESP = 0012FECC EBP = 0012FF18 EIP = 00401055 *(int*)(0) = 72; } void main() { int a = 0; try { //ESP = 0012FF20 EBP = 0012FF80 EIP = 004010BF test(); } catch(...) { //ESP = 0012F91C EBP = 0012FF80 EIP = 004010C6 printf("%d",a); } }
例外を発生させる部分をアセンブラでみるとこんな感じです。
9: *(int*)(0) = 72; 00401055 mov dword ptr ds:[0],48h 10: } 0040105F pop edi
もちろん__CxxThrowExceptionとかを直接呼び出しているないです。
catch句の中をスタックを見てみるとこんな感じです。
0012F8DD F8 12 00 00 00 00 00 ....... 0012F8E4 1E 02 02 00 3B CC 81 ....;フ. 0012F8EB 7C 07 00 00 00 00 00 |...... 0012F8F2 00 00 44 FA 12 00 7C ..D...| 0012F8F9 00 98 00 02 00 00 00 ....... 0012F900 A0 0F 00 00 84 0F 00 ....... 0012F907 00 20 B0 02 00 00 00 . ー.... 0012F90E 00 00 00 00 00 00 1E ....... 0012F915 02 02 00 00 01 00 00 ....... 0012F91C 47 41 40 00 00 00 00 GA@.... 0012F923 00 00 00 00 00 38 F9 .....8. 0012F92A 12 00 74 FF 12 00 00 ..t.... 0012F931 00 00 00 80 FF 12 00 ....... 0012F938 70 F9 12 00 82 14 40 p.....@ 0012F93F 00 C6 10 40 00 74 FF .ニ.@.t. 0012F946 12 00 00 01 00 00 00 ....... 0012F94D 00 00 00 00 00 00 00 ....... 0012F954 00 00 00 00 00 36 38 .....68 0012F95B 00 B8 F9 12 00 A0 14 .ク..... 0012F962 40 00 70 64 42 00 74 @.pdB.t 0012F969 FF 12 00 01 00 00 00 ....... 0012F970 C8 F9 12 00 A5 3C 40 ネ...・<@ 0012F977 00 74 FF 12 00 70 64 .t...pd 0012F97E 42 00 C6 10 40 00 00 B.ニ.@.. 0012F985 00 00 00 00 01 00 00 ....... 0012F98C 00 00 00 00 00 00 00 ....... 0012F993 00 00 00 00 00 87 14 ....... 0012F99A 00 00 C6 10 40 00 20 ..ニ.@. 0012F9A1 FF 12 00 00 00 00 00 ....... 0012F9A8 00 00 00 00 00 00 00 ....... 0012F9AF 00 8C F9 12 00 8C 13 .勾.... 0012F9B6 40 00 10 FB 12 00 10 @...... 0012F9BD 76 40 00 58 54 42 00 v@.XTB. 0012F9C4 01 00 00 00 F4 F9 12 ..... 0012F9CB 00 FA 3B 40 00 E4 FB ..;@.蕘 0012F9D2 12 00 74 FF 12 00 00 ..t.... 0012F9D9 FC 12 00 70 64 42 00 ...pdB. 0012F9E0 C6 10 40 00 00 00 00 ニ.@.... 0012F9E7 00 00 01 00 00 18 FF ....... 0012F9EE 12 00 74 FF 12 00 34 ..t...4 0012F9F5 FA 12 00 57 39 40 00 ...W9@. 0012F9FC E4 FB 12 00 74 FF 12 蕘..t.. 0012FA03 00 00 FC 12 00 B8 FB .....ク. 0012FA0A 12 00 70 64 42 00 B8 ..pdB.ク 0012FA11 64 42 00 00 00 00 00 dB..... 0012FA18 A0 64 42 00 00 00 00 .dB.... 0012FA1F 00 00 00 00 00 01 00 ....... 0012FA26 00 00 00 00 00 00 A0 ....... 0012FA2D 64 42 00 01 00 00 00 dB..... 0012FA34 8C FA 12 00 37 38 40 厚..78@ 0012FA3B 00 E4 FB 12 00 74 FF .蕘..t. 0012FA42 12 00 00 FC 12 00 B8 ......ク 0012FA49 FB 12 00 70 64 42 00 ...pdB. 0012FA50 00 00 00 00 00 00 00 ....... 0012FA57 00 00 00 00 00 61 01 .....a. 0012FA5E 00 50 0F 93 95 7C 00 .P.燈|. 0012FA65 00 00 00 00 00 00 00 ....... 0012FA6C 00 00 00 00 23 03 95 ....#.. 0012FA73 7C 70 34 41 00 00 00 |p4A... 0012FA7A 40 00 00 00 40 00 D8 @...@.リ 0012FA81 00 40 00 00 FA 12 00 .@..... 0012FA88 00 00 00 00 BC FA 12 ....シ.. 0012FA8F 00 A3 35 40 00 E4 FB .」5@.蕘 0012FA96 12 00 74 FF 12 00 00 ..t.... 0012FA9D FC 12 00 B8 FB 12 00 ...ク... 0012FAA4 70 64 42 00 00 FB 12 pdB.... 0012FAAB 00 00 00 00 00 00 00 ....... 0012FAB2 00 00 00 00 00 00 A8 ......ィ 0012FAB9 FA 12 00 F8 FA 12 00 ..... 0012FAC0 EC 13 40 00 E4 FB 12 ..@.蕘. 0012FAC7 00 74 FF 12 00 00 FC .t..... 0012FACE 12 00 B8 FB 12 00 70 ..ク...p 0012FAD5 64 42 00 00 00 00 00 dB..... 0012FADC 00 00 00 00 00 00 00 ....... 0012FAE3 00 00 00 00 00 00 00 ....... 0012FAEA 00 00 00 00 00 00 70 ......p 0012FAF1 64 42 00 0A D8 94 7C dB..リ培 0012FAF8 1C FB 12 00 A8 32 94 ....ィ2. 0012FAFF 7C E4 FB 12 00 74 FF |蕘..t. 0012FB06 12 00 00 FC 12 00 B8 ......ク 0012FB0D FB 12 00 74 FF 12 00 ...t... 0012FB14 BC 32 94 7C 74 FF 12 シ2培t.. 0012FB1B 00 CC FB 12 00 7A 32 .フ...z2 0012FB22 94 7C E4 FB 12 00 74 培蕘..t 0012FB29 FF 12 00 00 FC 12 00 ....... 0012FB30 B8 FB 12 00 70 34 41 ク...p4A 0012FB37 00 18 FF 12 00 E4 FB .....蕘 0012FB3E 12 00 74 FF 12 00 0F ..t.... 0012FB45 AA 96 7C E4 FB 12 00 ェ翻蕘.. 0012FB4C 74 FF 12 00 00 FC 12 t...... 0012FB53 00 B8 FB 12 00 70 34 .ク...p4 0012FB5A 41 00 18 FF 12 00 E4 A...... 0012FB61 FB 12 00 00 00 00 00 ....... 0012FB68 6C 6D 6E 6F 00 00 00 lmno... 0012FB6F 00 74 75 76 77 78 79 .tuvwxy 0012FB76 7A 5B 5C 5D 5E 5F 60 z[\]^_` 0012FB7D 61 62 63 64 65 66 67 abcdefg 0012FB84 68 69 6A 6B 6C 6D 6E hijklmn 0012FB8B 00 70 71 72 73 74 75 .pqrstu 0012FB92 76 77 78 79 7A 7B 7C vwxyz{| 0012FB99 7D 7E 7F 80 20 20 20 }~.. 0012FBA0 20 20 20 20 00 00 38 ..8 0012FBA7 00 A4 F9 12 00 20 20 .、... 0012FBAE 20 20 E4 FD 12 00 20 .... 0012FBB5 E9 94 7C 18 93 95 7C 髞|.燈| 0012FBBC FF FF FF FF 00 00 13 ....... 0012FBC3 00 00 E0 12 00 94 FE ....... 0012FBCA 12 00 18 FF 12 00 8A ....... 0012FBD1 E4 94 7C 00 00 00 00 苳|.... 0012FBD8 00 FC 12 00 E4 FB 12 ....蕘. 0012FBDF 00 00 FC 12 00 05 00 ....... 0012FBE6 00 C0 00 00 00 00 00 .タ..... 0012FBED 00 00 00 55 10 40 00 ...U.@. //55 10 40 00 → 00401055 0012FBF4 02 00 00 00 01 00 00 ....... 0012FBFB 00 00 00 00 00 3F 00 .....?. 0012FC02 01 00 00 00 00 00 00 ....... 0012FC09 00 00 00 00 00 00 00 ....... 0012FC10 00 00 00 00 00 00 00 ....... 0012FC17 00 00 00 00 00 7F 02 ....... 0012FC1E FF FF 00 00 FF FF FF ....... 0012FC25 FF FF FF 00 00 00 00 ....... 0012FC2C 00 00 00 00 00 00 00 ....... 0012FC33 00 00 00 FF FF 00 00 ....... 0012FC3A 00 00 00 00 00 00 00 ....... 0012FC41 00 00 00 00 00 00 00 ....... 0012FC48 00 00 00 00 00 00 00 ....... 0012FC4F 00 00 00 00 00 00 00 ....... 0012FC56 00 00 00 00 00 00 00 ....... 0012FC5D 00 00 00 00 00 00 00 ....... 0012FC64 00 00 00 00 00 00 00 ....... 0012FC6B 00 00 00 00 00 00 00 ....... 0012FC72 00 00 00 00 00 00 00 ....... 0012FC79 00 00 00 00 00 00 00 ....... 0012FC80 00 00 00 00 00 00 00 ....... 0012FC87 00 00 00 00 00 00 00 ....... 0012FC8E 00 00 3B 00 00 00 23 ..;...# 0012FC95 00 00 00 23 00 00 00 ...#... 0012FC9C 18 FF 12 00 00 00 00 ....... 0012FCA3 00 00 F0 FD 7F 80 7D ......} 0012FCAA 42 00 80 7D 42 00 06 B..}B.. 0012FCB1 00 00 00 18 FF 12 00 ....... 0012FCB8 55 10 40 00 1B 00 00 U.@.... // 55 10 40 00 → 00401055 0012FCBF 00 06 03 01 00 CC FE .....フ. 0012FCC6 12 00 23 00 00 00 7F ..#.... 0012FCCD 02 00 00 00 00 00 00 ....... 0012FCD4 00 00 00 00 00 00 00 ....... 0012FCDB 00 00 00 00 00 00 00 ....... 0012FCE2 FF FF 80 1F 00 00 00 ....... 0012FCE9 00 00 00 00 00 00 00 ....... 0012FCF0 00 00 00 00 00 00 00 ....... 0012FCF7 00 00 00 00 00 00 00 ....... 0012FCFE 00 00 00 00 00 00 00 ....... 0012FD05 00 00 00 00 00 00 00 ....... 0012FD0C 00 00 00 00 00 00 00 ....... 0012FD13 00 00 00 00 00 00 00 ....... 0012FD1A 00 00 00 00 00 00 00 ....... 0012FD21 00 00 00 00 00 00 00 ....... 0012FD28 00 00 00 00 00 00 00 ....... 0012FD2F 00 00 00 00 00 00 00 ....... 0012FD36 00 00 00 00 00 00 00 ....... 0012FD3D 00 00 00 00 00 00 00 ....... 0012FD44 00 00 00 00 00 00 00 ....... 0012FD4B 00 00 00 00 00 00 00 ....... 0012FD52 00 00 00 00 00 00 00 ....... 0012FD59 00 00 00 00 00 00 00 ....... 0012FD60 00 00 00 00 00 00 00 ....... 0012FD67 00 00 00 00 00 00 00 ....... 0012FD6E 00 00 00 00 00 00 00 ....... 0012FD75 00 00 00 00 00 00 00 ....... 0012FD7C 00 00 00 00 00 00 00 ....... 0012FD83 00 00 00 00 00 00 00 ....... 0012FD8A 00 00 00 00 00 00 00 ....... 0012FD91 00 00 00 00 00 00 00 ....... 0012FD98 00 00 00 00 00 00 00 ....... 0012FD9F 00 00 00 00 00 00 00 ....... 0012FDA6 00 00 00 00 00 00 00 ....... 0012FDAD 00 00 00 00 00 00 00 ....... 0012FDB4 00 00 00 00 00 00 00 ....... 0012FDBB 00 00 00 00 00 00 00 ....... 0012FDC2 00 00 00 00 00 00 00 ....... 0012FDC9 00 00 00 00 00 00 00 ....... 0012FDD0 00 00 00 00 00 00 00 ....... 0012FDD7 00 00 00 00 00 00 00 ....... 0012FDDE 00 00 00 00 00 00 00 ....... 0012FDE5 00 00 00 00 00 00 00 ....... 0012FDEC 00 00 00 00 00 00 00 ....... 0012FDF3 00 00 00 00 00 00 00 ....... 0012FDFA 00 00 00 00 00 00 00 ....... 0012FE01 00 00 00 00 00 00 00 ....... 0012FE08 00 00 00 00 00 00 00 ....... 0012FE0F 00 00 00 00 00 00 00 ....... 0012FE16 00 00 00 00 00 00 00 ....... 0012FE1D 00 00 00 00 00 00 00 ....... 0012FE24 00 00 00 00 00 00 00 ....... 0012FE2B 00 00 00 00 00 00 00 ....... 0012FE32 00 00 00 00 00 00 00 ....... 0012FE39 00 00 00 00 00 00 00 ....... 0012FE40 00 00 00 00 00 00 00 ....... 0012FE47 00 00 00 00 00 00 00 ....... 0012FE4E 00 00 00 00 00 00 00 ....... 0012FE55 00 00 00 00 00 00 00 ....... 0012FE5C 00 00 00 00 00 00 00 ....... 0012FE63 00 00 00 00 00 00 00 ....... 0012FE6A 00 00 00 00 00 00 00 ....... 0012FE71 00 00 00 00 00 00 00 ....... 0012FE78 00 00 00 00 00 00 00 ....... 0012FE7F 00 00 00 00 00 00 00 ....... 0012FE86 00 00 00 00 00 00 00 ....... 0012FE8D 00 00 00 00 00 00 00 ....... 0012FE94 00 00 00 00 00 00 00 ....... 0012FE9B 00 00 00 00 00 00 00 ....... 0012FEA2 00 00 00 00 00 00 00 ....... 0012FEA9 00 00 00 00 00 00 00 ....... 0012FEB0 00 00 00 00 00 00 00 ....... 0012FEB7 00 00 00 00 00 00 00 ....... 0012FEBE 00 00 00 00 00 00 00 ....... 0012FEC5 00 00 00 00 00 00 00 ....... 0012FECC 70 FF 12 00 00 00 00 p...... 0012FED3 00 00 F0 FD 7F CC CC .....フフ 0012FEDA CC CC CC CC CC CC CC フフフフフフフ 0012FEE1 CC CC CC CC CC CC CC フフフフフフフ 0012FEE8 CC CC CC CC CC CC CC フフフフフフフ 0012FEEF CC CC CC CC CC CC CC フフフフフフフ 0012FEF6 CC CC CC CC CC CC CC フフフフフフフ 0012FEFD CC CC CC CC CC CC CC フフフフフフフ 0012FF04 CC CC CC CC CC CC CC フフフフフフフ 0012FF0B CC CC CC CC CC CC CC フフフフフフフ 0012FF12 CC CC CC CC CC CC 80 フフフフフフ. 0012FF19 FF 12 00 C4 10 40 00 ...ト.@. 0012FF20 00 00 00 00 00 00 00 ....... 0012FF27 00 00 F0 FD 7F CC CC .....フフ 0012FF2E CC CC CC CC CC CC CC フフフフフフフ 0012FF35 CC CC CC CC CC CC CC フフフフフフフ 0012FF3C CC CC CC CC CC CC CC フフフフフフフ 0012FF43 CC CC CC CC CC CC CC フフフフフフフ 0012FF4A CC CC CC CC CC CC CC フフフフフフフ 0012FF51 CC CC CC CC CC CC CC フフフフフフフ 0012FF58 CC CC CC CC CC CC CC フフフフフフフ 0012FF5F CC CC CC CC CC CC CC フフフフフフフ 0012FF66 CC CC CC CC CC CC 00 フフフフフフ. 0012FF6D 00 00 00 20 FF 12 00 ... ... 0012FF74 B0 FF 12 00 70 34 41 ー...p4A 0012FF7B 00 01 00 00 00 C0 FF .....タ. 0012FF82 12 00 C9 19 40 00 01 ..ノ.@.. 0012FF89 00 00 00 30 11 38 00 ...0.8. 0012FF90 A8 11 38 00 00 00 00 ィ.8.... 0012FF97 00 00 00 00 00 00 F0 ....... 0012FF9E FD 7F 01 00 00 00 06 ....... 0012FFA5 00 00 00 94 FF 12 00 ....... 0012FFAC 2E 2A 62 80 E0 FF 12 .*b.... 0012FFB3 00 10 76 40 00 40 51 ..v@.@Q 0012FFBA 42 00 00 00 00 00 F0 B...... 0012FFC1 FF 12 00 77 70 81 7C ...wp− 0012FFC8 00 00 00 00 00 00 00 ....... 0012FFCF 00 00 F0 FD 7F ED D6 .....臭 0012FFD6 54 80 C8 FF 12 00 20 T.ネ... 0012FFDD 50 ED 87 FF FF FF FF P簁.... 0012FFE4 D8 9A 83 7C 80 70 81 リ噬|.p. 0012FFEB 7C 00 00 00 00 00 00 |...... 0012FFF2 00 00 00 00 00 00 E0 ....... 0012FFF9 18 40 00 00 00 00 00 .@.....
怪しいところをピックアップするとこんな感じかなぁと。
0012FBDF 00 00 FC 12 00 05 00 ....... 0012FBE6 00 C0 00 00 00 00 00 .タ..... 0012FBED 00 00 00 55 10 40 00 ...U.@. //55 10 40 00 → 00401055 0012FBF4 02 00 00 00 01 00 00 ....... 0012FBFB 00 00 00 00 00 3F 00 .....?. 0012FCAA 42 00 80 7D 42 00 06 B..}B.. 0012FCB1 00 00 00 18 FF 12 00 ....... 0012FCB8 55 10 40 00 1B 00 00 U.@.... // 55 10 40 00 → 00401055 0012FCBF 00 06 03 01 00 CC FE .....フ. 0012FCC6 12 00 23 00 00 00 7F ..#....
一応情報はあるみたいです。
何とかなりそうな気もします。
別にがんばらなくてもよくないか?
どこでthrowされたか分からないとサポート対応で死ぬので、
通常の throw で投げるときは、 __FILE__ と __LINE__ コンパイラが許すのであれば __FUNC__ とかを渡すと思います。
//std::string で printfもどき static std::string format(const char* format,...) { char buffer[1024]; _vsnprintf(buffer,sizeof(buffer),format,(char*)(&format+1)); buffer[sizeof(buffer) - 1] = '\0'; return buffer; } //エラー追跡が楽にできるようにする #define ETRACE format("%s:%d" , __FILE__ , __LINE__) //std::string で情報を保持したいので自前例外クラスを作っておく class MyException { public: MyException(std::string inMessage) { this->Message = inMessage; } std::string getMessage() const { return this->Message; } private: std::string Message; }; void test() { throw MyException(ETRACE + " よく分からないエラーが発生"); } void main() { int a = 0; try { test(); } catch(MyException &e) { printf("%d %p",a,&e); } }
で、自分でthrow できない構造化例外なんですが、 _set_se_translator でフックして自前で throw することができます。
//std::string で printfもどき static std::string format(const char* format,...) { char buffer[1024]; _vsnprintf(buffer,sizeof(buffer),format,(char*)(&format+1)); buffer[sizeof(buffer) - 1] = '\0'; return buffer; } //エラー追跡が楽にできるようにする #define ETRACE format("%s:%d" , __FILE__ , __LINE__) //std::string で情報を保持したいので自前例外クラスを作っておく class MyException { public: MyException(std::string inMessage) { this->Message = inMessage; } std::string getMessage() const { return this->Message; } private: std::string Message; }; void test() { *(int*)(0) = 72; } //構造化例外が発生するとこの関数が呼ばれる void se_translator_function(unsigned int code, struct _EXCEPTION_POINTERS* ep) { throw MyException(format("se_exception CODE:%p ADDRESS:%p" , ep->ExceptionRecord->ExceptionCode, ep->ExceptionRecord->ExceptionAddress)); } void main() { _set_se_translator(se_translator_function); int a = 0; try { test(); } catch(MyException &e) { printf("%d %p",a,&e); } }
さすがに __FILE__ や __LINE__ を差し込むことは無理ですが、少なくともアドレスは分かります。
余談ですが、投げる例外クラスを工夫したり、フラグを持たせれば、それが構造化例外なのか、通常の例外なのかも判別可能です。
当初の目的である、どこで例外が呼ばれたか?の答えがコレです。
アドレスだけでわかるかボケーという人は、、、googleでwindbgかワトソン博士の使い方を調べるか、ここら辺の本を買って読めばよく分かります。
別の方法 __except でGetExceptionInformationな方法は多分この用途には向かない
__except の中でのみ使える GetExceptionInformation 関数があります。
GetExceptionInformation を唱えると、 例外の情報や例外が送信されたときのコンテキストがまとめて取れます。
void test() { *(int*)(0) = 72; } void main() { int a = 0; _EXCEPTION_POINTERS* info; __try { test(); } __except (info = GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) { printf("Address: %p\r\n",info->ExceptionRecord->ExceptionAddress); printf("Code: %p\r\n",info->ExceptionRecord->ExceptionCode); }; }
結果はこんな感じになります。
Address: 00401046
Code: C0000005
00401046っていうのが、 例外が発生した *(int*)(0) = 72; の直前のアドレスです。
00401046 rep stos dword ptr [edi] 9: *(int*)(0) = 72; 00401048 mov dword ptr ds:[0],48h 10: }
なんと素晴らしい。。。
ですが、ユーザが throw で例外をなげるとわけわかめなアドレスを返してきます。
void test() { throw std::exception("aaa"); //C++のthrow で投げてみる } void main() { int a = 0; _EXCEPTION_POINTERS* info; __try { test(); } __except (info = GetExceptionInformation(), EXCEPTION_EXECUTE_HANDLER) { printf("Address: %p\r\n",info->ExceptionRecord->ExceptionAddress); printf("Code: %p\r\n",info->ExceptionRecord->ExceptionCode); }; }
Address: 7C812AFB
Code: 900014C2
7C812AFBってどこだよ。
コールスタックが見たい!!
この方法では無理。
throw する exceptionクラスの中でスタックトレースを行うぐらい?
面倒なら、minidumpしてしまうのも手かも。
あとは、最初に出したスタックを自前で追いかけるしかないかも。
throw が必ずコールスタックが必要ではないと考えると、catchの中でやったほうが効率的ではあると思う。
個人的には、場所さえ分かればいいかなと思うんだけど、やっぱりコールスタックって需要があるんだろうか。
それと、そもそも論で悪いんですが、catch書いたら負けだと思うんですよ。
例外はガチで例外のときのみ呼ばれるべしっていうのが私の例外に対するポリシーなんですよ。参考:れいがい!
http://prezi.com/1jolcfw5y71g/exception/
catchかかなければプログラムが落ちて core が取れるぢゃないですか。
そしたら、コールスタックもすべて保存されていてデバッグが行えますよ。ほら問題ないでしょ?w
自分でminidumpしてもいいんですけどね。
なに?サーバアプリを書いているから落ちたらダメなんだよバーカって?
落ちてはダメだったら、ふつーは自前監視して、落ちたら立ち上げなおす(ザオリク)プログラムでラップするだろうJKと。
mysqld に対する mysqld_safe みたいな感じです。
アプリが死ぬとザオリクでよみがえらせます。なんで個人的にザオリクアプリ、この構成をザオリクパターンと読んでいます。広まるといいな。。。