mltermのなかでtmuxをうごかしていて、ログをがばっと出力するときによく暴走するので調べてみた。

  • truss -pでみてもsyscallは発行していない。
  • gdbでアタッチして関数をみると奥深いところでクルクルしてるっぽい。
  • ソースコードからつくってgdbの中で実行→暴走させてC-cで止めてみると
    • flush_scroll_cache()がml_term_set_modified_lines()を呼び出すときの第3引数がデカい。
      • screen->scroll_cache_boundary_start = 27
      • screen->scroll_cache_boundary_end = 44
      • screen->scroll_cache_rows = 76
      • となってたので 仮引数 end = 4294967264。

対症療法:

diff --git a/xwindow/x_screen.c b/xwindow/x_screen.c
--- a/xwindow/x_screen.c
+++ b/xwindow/x_screen.c
@@ -755,6 +755,7 @@
 			/*
 			 * scrolling upward.
 			 */
+			if (screen->scroll_cache_boundary_end >= screen->scroll_cache_rows)
 			ml_term_set_modified_lines( screen->term , screen->scroll_cache_boundary_start ,
 				screen->scroll_cache_boundary_end - screen->scroll_cache_rows) ;
 		}
@@ -763,6 +764,7 @@
 			/*
 			 * scrolling downward.
 			 */
+			if (screen->scroll_cache_boundary_start >= screen->scroll_cache_rows)
 			ml_term_set_modified_lines( screen->term ,
 				screen->scroll_cache_boundary_start - screen->scroll_cache_rows ,
 				screen->scroll_cache_boundary_end) ;

mltermの新しいのにしたらこのへんのコードがかわってた。でも同じだった。

(gdb) p screen->scroll_cache_boundary_start
$1 = 39
(gdb) p screen->scroll_cache_boundary_end
$2 = 76
(gdb) p screen->scroll_cache_rows
$3 = 0
(gdb) p scroll_cache_rows
$6 = 87

暴走させるコツがわかってきた。

  • こんなスクリプトを用意しておく(ファイル名は仮にhoge.shとして保存しとく)
#!/bin/sh
I=100
while : ; do
    echo $I
    I=$((I+1))
done
  • mltermをたちあげて広くする。全画面とか。手元の環境では 92 rows; 153 columns; になる (stty -a調べ)
  • tmuxをたちあげる。
  • tmux split
  • tmux set sync
  • sh ./hoge.sh
  • 一丁あがり!

mltermの最新版をビルドしようとしたらlinkでエラーになった。FreeBSDの問題なのかmltermの問題なのかわからんがパッチ:

diff --git a/main/dexport.map b/main/dexport.map
--- a/main/dexport.map
+++ b/main/dexport.map
@@ -2,6 +2,9 @@
 global:
        x_imagelib_load_file ;
        x_get_opened_displays ;
+       # KOIEMEMO: /usr/bin/ld: mlterm: local symbol `__progname' in /usr/lib/crt1.o is referenced by DSO
+       __progname ;
+       environ ;
 local:
        * ;
 } ;

[2012-09-18 12:39]


作者さんから直ったとの連絡をいただきました!

http://mlterm.sourceforge.net/mlterm-3.1.3post-fixscroll.patch のパッチを /usr/ports/x11/mlterm/files/patch-mlterm-3.1.3post-fixscroll に置いて make clean && make && make deinstall && make reinstall で入れ替え。

koie