Skip to content

Commit

Permalink
history: work around broken timestamps in HISTFILE
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Jul 5, 2022
1 parent 4d24f84 commit 5ef28eb
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 38 deletions.
1 change: 1 addition & 0 deletions docs/ChangeLog.md
Expand Up @@ -359,6 +359,7 @@
- util: work around old `vte` not supporting `DECSCUSR` yet setting `TERM=xterm` (reported by dongxi8) `#D1785` 70277d0
- progcomp: work around the cobra V2 description hack (reported by SuperSandro2000) `#D1803` 71d0736
- complete: work around blocking `_scp_remote_files` and `_dnf` (reported by iantra) `#D1807` a4a779e 46f5c13
- history: work around broken timestamps in `HISTFILE` `#D1831` XXXXXXX

## Internal changes and fixes

Expand Down
13 changes: 13 additions & 0 deletions memo/D1831.bashrc
@@ -0,0 +1,13 @@
# bashrc -*- mode: sh; mode: sh-bash -*-

if [[ ! -f out/ble.sh ]]; then
echo 'memo/D1831.bashrc: out/ble.sh not found.' >&2
return 2
fi

cp -f memo/D1831.history{,.tmp}
HISTFILE=$PWD/memo/D1831.history.tmp
HISTFILESIZE=
HISTSIZE=
HISTTIMEFORMAT=%s
source out/ble.sh --norc -o vbell_duration=5000
10 changes: 10 additions & 0 deletions memo/D1831.history
@@ -0,0 +1,10 @@
#1656625044
echo 1
#1656625044
echo 2
#1647948811646449694
echo a
#1656625044
echo b
#1656625044
echo c
111 changes: 106 additions & 5 deletions note.txt
Expand Up @@ -1823,13 +1823,17 @@ bash_tips

2022-07-04

* ext: trueline と組み合わせた時に問題が起こるとのこと。
https://github.com/lecramyajiv/Emptydeeds/commit/b57e8354cc350d71c655d93c32112427ec8addda#diff-0a1c1083789380c5f4b4aaebd19b6a4b2431ae808f8b456cf865825cfb93b9dfR2527
* [保留] debug_xtrace を bash-4.0 以下でも対応する?

* bash: history timestamp に問題がある時に history の初期化が正しくない
debug_xtrace が bash-3.2 で動いていない。と思ったらそもそも BASH_XTRACEFD
は bash-4.1 以降の機能だったのだ。bash-4.0 以下では 2 を redirect する事に
よって実現する? と思ったが 2 は ble.sh が出力するのに使っている気がする。特
に ble/util/buffer.flush で使っている。更に他にも様々なエラーメッセージが 2
に出力されるのではないか。という事を考えると 2 を xtrace に使うのは余り良い
ことではない様な気がする。取り敢えず保留という事にする。

bash がエラーメッセージを出力する (bash-5.0+) または segfault する
(bash-4.4-)。現状ではエラーメッセージがそのまま履歴に混入してしまっている。
* ext: trueline と組み合わせた時に問題が起こるとのこと。
https://github.com/lecramyajiv/Emptydeeds/commit/b57e8354cc350d71c655d93c32112427ec8addda#diff-0a1c1083789380c5f4b4aaebd19b6a4b2431ae808f8b456cf865825cfb93b9dfR2527

2022-06-28

Expand Down Expand Up @@ -6451,6 +6455,103 @@ bash_tips

2022-07-05

* bash: history timestamp に問題がある時に history の初期化が正しくない [#D1831]
https://github.com/akinomyoga/ble.sh/issues/202

bash がエラーメッセージを出力する (bash-5.0+) または segfault する
(bash-4.4-)。現状ではエラーメッセージがそのまま履歴に混入してしまっている。
うーん。stderr も読み取ってしまっているのかと思ったが実際に試してみるとエラー
メッセージが stdout に出力されている。

% これは後で bash に提出する。
%
% * reject: bug-bash: HISTTIMEFORMAT=%s history でエラーメッセージが stdout
% に混入するエラーメッセージは stderr に出力するべきなのではないか。
%
% と思ったがこの文字列はエラーメッセージとしてではなく履歴時刻の文字列の代
% わりに埋め込まれているという事が判明した。という事はやはり history の出力
% の中にメッセージを埋め込むべきという事なのかもしれない。

取り敢えず問題のエラーメッセージは正規表現によるパターンで除去する事にする。

* fixed: 更に履歴を書き込む時にも問題になっている。これも修正した。

* done: 履歴読み込み時に invalid timestamp を検出したらそれを vbell で報告
する様にする。

これで bash-5.0+ 以降でエラーメッセージが履歴に紛れ込むのは修正した。一方で
bash-4.4 以下で segfault してしまうのに対する対策は難しいのではないか。一応
終了ステータスを確認する事で segfault した事は検出できるが、もし検出したと
してどの様に対処するのが良いか。例えば、HISTTIMEFORMAT なしで改めて履歴を読
み直す事にする? 履歴行の境をどの様に判定するべきだろうか。或いは、エラーを
検出した時に vbell に表示してしまって、history の状態は壊れた状態でも仕方が
ないという事にする? それが良い気がする。

* 実際にエラーになった時に問題の行を指摘したい。

どの様な形式の時にエラーになるのか調べようとしたがよく分からない。先ず、
そもそも数字でない場合には timestamp 行として認識されない。数字の後にごみ
が入っていてもそれらは単に無視される。得に巨大な数が指定された時に於いて
問題が生じる様である。問題が起こる最小の整数を探索すると
67768036191644399 であった。これは16進数で見ても特に特別な数ではない
(0xf0c2ab7c542aef)。検索してみたらどうもやはり時刻関係で特別な数字の様で
はある。

> https://mevius.5ch.net/test/read.cgi/unix/1590454119/
>
> 115名無しさん@お腹いっぱい。2020/06/01(月) 17:52:40.57
> macos での限界
> $ date -r 67768036191644399
> 2147485547年 12月31日 水曜日 23時59分59秒 JST
> $ date -r 67768036191644400
> date: localtime: Value too large to be stored in data type

実際手許の date で試してみても同様である。

$ date --date=@67768036191644399
$ date --date=@67768036191644400

これは一体何が決めているのだろうか。と思ったらどうも 2147485547 年という
のは1900 + 0x7FFFFFFF らしい。つまり localtime で時刻構造体に変換する時に
代入できないという状態になるという事だ。

https://www.wdic.org/w/TECH/21%E5%84%844748%E4%B8%875548%E5%B9%B4%E5%95%8F%E9%A1%8C

67768036191644399 で検索して日本語のページが幾つかしか出てこないのは
upper bound が TZ に依存するからである。

さて、TZ に依存するのだとすればこの数値を threshold に選ぶ事はできない。
それに正規表現で判定できなければ問題の行の検出に於いて不都合である。更に、
この上限の値は time.h の実装にも依存するのではないだろうか。

更に bash-3.2 以下では無限ループになる。関係ない無限ループかもしれないと思っ
たが実際に履歴の timestamp に問題がある時にのみ無限ループになる。何処で無限
ループになっているか確認する。

→実際に ble.sh なしで試して見た所、単に history を実行しただけで無限ループ
になって固まってしまう。これに対する対策は難しい気がする。。builtin history
を呼び出すあらゆる操作で問題が起こる可能性があるという事になるのであるから。

* done: bash-3.2: history の読み出しに使っている部分だけ conditoinal-sync で呼び出す。

conditional-sync で timeout を設定してみたがやはり 100% になってしまう。
という事は関係ない別の history -n 等でも全て無限ループになっているという
事か。と思ったが手許で実行している限りは特に無限ループにはならない。

→と思ったら分かった。.get-min で history | head -1 を呼び出している。こ
の history で無限ループになっている。

? ok: 実際に conditional-sync で呼び出してみたところ timeout よりも断然早く
中断する。何かと思ったら conditional-sync 経由で呼び出した時には無限ルー
プにならずに 300ms 程度でちゃんと終了する様である。何故だろうか。

もしかすると conditional-sync を使わなくても subshell ならばちゃんと終了
する可能性? と思ったが、元より問題になる箇所では subshell を使っていた。
なので、bg で動かした時にだけ無限ループにならないという事だろうか。だとし
たらやはり conditoinal-sync 経由で呼び出して置くのが楽である。

取り敢えず bash-3.2 でも固まらなくなった。OK

* edit: プロンプト評価時に LINENO は一時的に現在の行番号に設定するべき [#D1830]

→これは DEBUG を PREEXEC に使っている設定でも重要になる。
Expand Down

0 comments on commit 5ef28eb

Please sign in to comment.