[Windows11, MinGW g++ 9.2.0, FLTK 1.3.8, NO IDE]
MacOSから移植中のカラーアプリについてWindows環境のみでアプリが落ちる現象が発覚しましたので、早速GDBデバッガで調査しました。
コンパイル時に-Ogオプションを追加しないとオブジェクトファイルのデバッグへの最適化ができないので要注意です。実際に-Ogオプションなしでコンパイルすると関数指定や行数指定のブレークポイント設定が正確にできませんでした。
DEBUG = -Og -g
“b btnAction.cpp:showColor”コマンドでbtnAction.cppのshowColor関数にブレークポイントを設定し、rコマンドでアプリを実行しました。nコマンドでは関数はスキップして次の行に進み、sコマンドでは関数にも入り込んで次の行に進みます。
調査の結果、自製ライブラリColorConvertのZeroToRGB関数にあるstoi関数辺りに原因があることが判明しました。
対策:
invalid argumentエラーを例外処理するようにした。
clang++ではデフォルトで例外処理を包含しているようです。stoi関数の引数がNULLでもエラーになりません。clang++が甘々なのか、MinGWが厳しいのか。
int red;
int green;
int blue;
try{
red = stoi(red0);
green = stoi(green0);
blue = stoi(blue0);
}catch(const std::invalid_argument& e){
cout << "invalid argument" << endl;
}
>gdb ColorSample.exe
Reading symbols from ColorSample.exe...done.
(gdb) b btnAction.cpp:showColor
Breakpoint 1 at 0x406510: btnAction.cpp:showColor. (2 locations)
(gdb) r
Starting program: ColorSample.exe
[New Thread 6864.0x4334]
[New Thread 6864.0x968]
[New Thread 6864.0x2350]
[New Thread 6864.0x44b4]
locale Japanese_Japan.932
Japan detect
[New Thread 6864.0x43c0]
[New Thread 6864.0x3258]
[New Thread 6864.0x3bd8]
Breakpoint 1, showColor () at C:/FLTK/fltk-1.3.8/include/FL/Fl_Button.H:102
102 char value() const {return value_;}
(gdb) s
516 input_code = code_input->value();
(gdb) s
value (this=0xf485e0) at C:/FLTK/fltk-1.3.8/include/FL/Fl_Input_.H:244
244 const char* value() const {return value_;}
(gdb) n
showColor () at .\src\btnAction.cpp:516
516 input_code = code_input->value();
(gdb) n
517 if (input_code == ""){
(gdb) n
533 if (onoff_zero == 1){
(gdb) s
534 ToZeroConvert();
(gdb) s
ToZeroConvert () at .\src\btnAction.cpp:196
196 const char* input_code0 = code_input->value();
(gdb) p input_code0
$1 = <optimized out>
(gdb) s
value (this=0xf485e0) at C:/FLTK/fltk-1.3.8/include/FL/Fl_Input_.H:244
244 const char* value() const {return value_;}
(gdb) s
ToZeroConvert () at .\src\btnAction.cpp:197
197 input_code = string(input_code0);
(gdb) p input_code
No symbol "input_code" in current context.
(gdb) s
basic_string<> (__a=..., __s=0xf5f498 "0x483D", this=0xdaf334) at .\src\btnAction.cpp:197
197 input_code = string(input_code0);
(gdb) p input_code
No symbol "input_code" in current context.
(gdb) s
_Alloc_hider (__a=..., __dat=0xdaf33c "\375\023爽リ\023爽蝗^ツ\032 \r", this=0xdaf334)
at c:/mingw/lib/gcc/mingw32/9.2.0/include/c++/ext/new_allocator.h:83
83 new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { }
(gdb) s
basic_string<> (__a=..., __s=0xf5f498 "0x483D", this=0xdaf334)
at c:/mingw/lib/gcc/mingw32/9.2.0/include/c++/bits/basic_string.h:527
527 { _M_construct(__s, __s ? __s + traits_type::length(__s) : __s+npos); }
(gdb) n
ToZeroConvert () at .\src\btnAction.cpp:197
197 input_code = string(input_code0);
(gdb) n
199 if (input_code.find("#") != string::npos){
(gdb) n
230 } else if (input_code.find("0x") != string::npos){
(gdb) n
[New Thread 6864.0x3a8c]
232 code_zero = input_code;
(gdb) s
operator= (__str=..., this=0x52f094 <code_zero[abi:cxx11]>) at .\src\btnAction.cpp:232
232 code_zero = input_code;
(gdb) s
assign (__str=..., this=0x52f094 <code_zero[abi:cxx11]>)
at c:/mingw/lib/gcc/mingw32/9.2.0/include/c++/bits/basic_string.h:1364
1364 assign(const basic_string& __str)
(gdb) s
_fu21___ZSt4cout () at .\src\btnAction.cpp:235
235 baseColor = CC.ZeroToRGB(input_code);
(gdb) s
basic_string (__str=..., this=0xdaf3c4) at .\src\btnAction.cpp:235
235 baseColor = CC.ZeroToRGB(input_code);
(gdb) s
_Alloc_hider (__a=<optimized out>, __dat=0xdaf3cc "\a", this=0xdaf3c4)
at c:/mingw/lib/gcc/mingw32/9.2.0/include/c++/ext/new_allocator.h:83
83 new_allocator(const new_allocator&) _GLIBCXX_USE_NOEXCEPT { }
(gdb) s
basic_string (__str=..., this=0xdaf3c4) at c:/mingw/lib/gcc/mingw32/9.2.0/include/c++/bits/basic_string.h:451
451 { _M_construct(__str._M_data(), __str._M_data() + __str.length()); }
(gdb) s
_M_data (this=<optimized out>) at c:/mingw/lib/gcc/mingw32/9.2.0/include/c++/bits/basic_string.h:186
186 _M_data() const
(gdb) s
basic_string (__str=..., this=0xdaf3c4) at c:/mingw/lib/gcc/mingw32/9.2.0/include/c++/bits/basic_string.h:936
936 length() const _GLIBCXX_NOEXCEPT
(gdb) s
451 { _M_construct(__str._M_data(), __str._M_data() + __str.length()); }
(gdb) s
_M_construct<char*> (__end=0x53b0fa <input_code[abi:cxx11]+14> "", __beg=0x53b0f4 <input_code[abi:cxx11]+8> "0x483D",
this=0xdaf3c4) at c:/mingw/lib/gcc/mingw32/9.2.0/include/c++/bits/basic_string.h:451
451 { _M_construct(__str._M_data(), __str._M_data() + __str.length()); }
(gdb) s
_M_construct_aux<char*> (__end=0x53b0fa <input_code[abi:cxx11]+14> "",
__beg=0x53b0f4 <input_code[abi:cxx11]+8> "0x483D", this=0xdaf3c4)
at c:/mingw/lib/gcc/mingw32/9.2.0/include/c++/bits/basic_string.h:263
263 _M_construct(_InIterator __beg, _InIterator __end)
(gdb) n // ここでアプリが落ちた
[New Thread 6864.0x2a54]
[New Thread 6864.0x24c4]
terminate called after throwing an instance of 'std::invalid_argument'
what(): stoi
[Inferior 1 (process 6864) exited with code 03]
(gdb) quit
![](https://mowareblog.net/wp-content/uploads/2022/10/ff7a8a737a7f60ad5dd24715fea5996f.jpg)