Gtkアプリ3 開発する上での注意点
開発運用していた時に、起きたこと気がついたことを随時更新してきます。
UIを更新する際は同期処理の方がよい
非同期処理にすると更新する際に落ちることがある。
起きたこと
Timer関数でWebAPIのデータを非同期処理で取得後、UI(ラベルなど)の更新を非同期で処理したら落ちることがある。
対策
UIの情報の更新を同期処理に切り替えたら安定した。awaitやasyncを外した。
ボタンイベントに非同期処理をつけて連打すると落ちることがある
private async void on_test_clicked(object sender , EventArgs e)
↓
private void on_test_clicked(object sender , EventArgs e)
対策
UI処理理に使っていたTask、asyncを外した。
Gtk.ListStoreを何度もClearするとクラッシュすることがある
Gtk.ListStore testStore = new Gtk.ListStore (typeof (testModel));
testStore.AppendValues (testModel);
#Gtk.ListStoreをクリアする
treeView1.Model = null;
ListStore.Clear()
対策
Clearの後にtreeViewのModelをnullをいれる
Modelをnullをした後でClearする
try catchでエラーハンドリングする前にクラッシュするエラーが起こりlog4に出力できない
起きたこと
C言語のGtkライブラリ側でエラーが起き、C#側のcatchでエラーハンドリングできない
対策
Gtk3アプリをターミナルから起動させるとターミナルも一緒に起動する。
ターミナルで内でログを出力させる。Console.WriteLine();などを使う
ターミナル内ではC言語側のエラーログも出力できる
現在の行数を取得する
var stackFrame = new StackFrame(1, true);
string num = stackFrame.GetFileLineNumber().ToString();
Console.WriteLine(memo + "行番号 " + num );
メモリ関連のエラー 1
メモリを消費し続けて開放されていないとエラーが起こる
エラー free(): invalid next size (fast)
long currentSet = Environment.WorkingSet
Console.WriteLine("現在のメモリ使用量は{0}byteです。", currentSet.ToString("N0"));
// → 現在のメモリ使用量は38,432,768byteです。と表示される。
メモリが使用量を消費し続けているプログラムを調査する
対策
メモリの使用量が増え続けている箇所を修正する
メンバー変数をローカル変数にする
Task関数をメンバー変数からローカル変数にすると安定した
メモリ関連のエラー 2
メモリの二重解放エラー
メモリの開放がCloseとDisposeで二重に行われていた。
P.Close()
P.Dispose()
エラー double free or corruption
対策
Dispose系をfinallyで実行する
try{
}catch (Exception e){
Console.WriteLine(e);
}finally{
if (P != null){
P.Dispose();
}
}
ダンプファイルを出力し検証する
C言語側のライブラリでクラッシュが発生したら、ダンプファイルを出力させ中身を検証することができる。
エラー Segmentation fault (コアダンプ)
コアダンプを有効にする
ulimit -c unlimited
コアダンプが有効になっているか確認する
ulimit -a
生成されたダンプファイルをデバッグする
gdbコマンドを使う
gdb ./ダンプファイル.out core