Skip to content

Commit

Permalink
main: support "bleopt debug_xtrace"
Browse files Browse the repository at this point in the history
  • Loading branch information
akinomyoga committed Jun 10, 2022
1 parent 5fb42c2 commit 022d38b
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 21 deletions.
4 changes: 2 additions & 2 deletions README.md
Expand Up @@ -128,8 +128,8 @@ I started working on the enhancement of the completion in August, 2018 and relea

Some user configurations or other Bash frameworks may conflict with ble.sh. For example,

- `ble.sh` need to assume that common variable names and environment variables (such as `LC_*`) are not used for the global readonly variables.
In Bash, global readonly variables take effect in any scope including the local scope of the function, which means that we cannot even define a local variable that have the same name as a global variable constants.
- `ble.sh` assumes that common variable names and environment variables (such as `LC_*`) are not used for the global readonly variables.
In Bash, global readonly variables take effect in any scope including the local scope of the function, which means that we cannot even define a local variable that have the same name as a global readonly variable.
This is not the problem specific to `ble.sh`, but any Bash framework may suffer from the global readonly variables.
It is generally not recommended to define global readonly variables in Bash except for the security reasoning
(Refs. [[1]](https://lists.gnu.org/archive/html/bug-bash/2019-03/threads.html#00150), [[2]](https://lists.gnu.org/archive/html/bug-bash/2020-04/threads.html#00200), [[3]](https://mywiki.wooledge.org/BashProgramming?highlight=%28%22readonly%22%20flag,%20or%20an%20%22integer%22%20flag,%20but%20these%20are%20mostly%20useless,%20and%20serious%20scripts%20shouldn%27t%20be%20using%20them%29#Variables)).
Expand Down
92 changes: 90 additions & 2 deletions ble.pp
Expand Up @@ -321,9 +321,95 @@ function ble/variable#copy-state {
fi
}

# BASH_XTRACEFD は書き換えると勝手に元々設定されていた fd を閉じてしまうので、
# 元々の fd を dup しておくなど特別な配慮が必要。
{
_ble_bash_xtrace=()
_ble_bash_xtrace_debug_enabled=
_ble_bash_xtrace_debug_filename=
_ble_bash_xtrace_debug_fd=
_ble_bash_XTRACEFD=
_ble_bash_XTRACEFD_set=
_ble_bash_XTRACEFD_dup=
} 2>/dev/null # set -x 対策
# From src/util.sh (ble/fd#is-open and ble/fd#alloc/.nextfd)
function ble/base/xtrace/.fdcheck { builtin : >&"$1"; } 2>/dev/null
function ble/base/xtrace/.fdnext {
(($1=${_ble_util_openat_nextfd:-30},1))
while ble/base/xtrace/.fdcheck "${!1}"; do (($1++,1)); done
}
function ble/base/xtrace/adjust {
local level=${#_ble_bash_xtrace[@]}
if [[ $- == *x* ]]; then
_ble_bash_xtrace[level]=1
else
_ble_bash_xtrace[level]=
fi
set +x

((level==0)) || return 0
_ble_bash_xtrace_debug_enabled=
if [[ ${bleopt_debug_xtrace:-/dev/null} == /dev/null ]]; then
if [[ $_ble_bash_xtrace_debug_fd ]]; then
builtin eval "exec $_ble_bash_xtrace_debug_fd>&-" || return 0
_ble_bash_xtrace_debug_filename=
_ble_bash_xtrace_debug_fd=
fi
else
if [[ $_ble_bash_xtrace_debug_filename != "$bleopt_debug_xtrace" ]]; then
_ble_bash_xtrace_debug_filename=$bleopt_debug_xtrace
[[ $_ble_bash_xtrace_debug_fd ]] || ble/base/xtrace/.fdnext _ble_bash_xtrace_debug_fd
builtin eval "exec $_ble_bash_xtrace_debug_fd>>\"$bleopt_debug_xtrace\"" || return 0
fi

_ble_bash_XTRACEFD=${BASH_XTRACEFD-}
_ble_bash_XTRACEFD_set=${BASH_XTRACEFD+set}
if [[ ${BASH_XTRACEFD-} =~ ^[0-9]+$ ]] && ble/base/xtrace/.fdcheck "$BASH_XTRACEFD"; then
ble/base/xtrace/.fdnext _ble_bash_XTRACEFD_dup
builtin eval "exec $_ble_bash_XTRACEFD_dup>&$BASH_XTRACEFD" || return 0
builtin eval "exec $BASH_XTRACEFD>&$_ble_bash_xtrace_debug_fd" || return 0
else
_ble_bash_XTRACEFD_dup=
local newfd; ble/base/xtrace/.fdnext newfd
builtin eval "exec $newfd>&$_ble_bash_xtrace_debug_fd" || return 0
BASH_XTRACEFD=$newfd
fi
_ble_bash_xtrace_debug_enabled=1
set -x
fi
}
function ble/base/xtrace/restore {
local level=$((${#_ble_bash_xtrace[@]}-1))
((level>=0)) || return 0
if [[ ${_ble_bash_xtrace[level]-} ]]; then
set -x
else
set +x
fi
builtin unset -v '_ble_bash_xtrace[level]'

((level==0)) || return 0
if [[ $_ble_bash_xtrace_debug_enabled ]]; then
_ble_bash_xtrace_debug_enabled=
if [[ $_ble_bash_XTRACEFD_dup ]]; then
# BASH_XTRACEFD の fd を元の出力先に繋ぎ直す
builtin eval "exec $BASH_XTRACEFD>&$_ble_bash_XTRACEFD_dup" &&
builtin eval "exec $_ble_bash_XTRACEFD_dup>&-" || ((1))
else
# BASH_XTRACEFD の fd は新しく割り当てた fd なので値上書きで閉じて良い
if [[ $_ble_bash_XTRACEFD_set ]]; then
BASH_XTRACEFD=$_ble_bash_XTRACEFD
else
builtin unset -v BASH_XTRACEFD
fi
fi
fi
}

function ble/base/.adjust-bash-options {
builtin eval -- "$1=\$-"
set +exvukT -B
set +evukT -B
ble/base/xtrace/adjust

[[ $2 == shopt ]] || local shopt
if ((_ble_bash>=40100)); then
Expand All @@ -345,12 +431,12 @@ function ble/base/.restore-bash-options {
local set=${!1} shopt=${!2}
[[ :$shopt: == *:nocasematch:* ]] && shopt -s nocasematch
[[ :$shopt: == *:extdebug:* ]] && shopt -s extdebug
ble/base/xtrace/restore
[[ $set == *B* ]] || set +B
[[ $set == *T* ]] && set -T
[[ $set == *k* ]] && set -k
[[ $set == *u* ]] && set -u
[[ $set == *v* ]] && set -v
[[ $set == *x* ]] && set -x
[[ $set == *e* ]] && set -e # set -e は最後
return 0
} 2>/dev/null # set -x 対策
Expand Down Expand Up @@ -1476,6 +1562,8 @@ function ble-update {
#%x inc.r|@|src/def|
#%x inc.r|@|src/util|

bleopt/declare -v debug_xtrace ''

ble/bin/.freeze-utility-path "${_ble_init_posix_command_list[@]}" # <- this uses ble/util/assign.
ble/bin/.freeze-utility-path man
ble/bin/.freeze-utility-path groff nroff mandoc gzip bzcat lzcat xzcat # used by core-complete.sh
Expand Down
14 changes: 11 additions & 3 deletions blerc
Expand Up @@ -227,8 +227,8 @@
## percentage of the CPU core usage in integer, which can be calculated by
## "(usr+sys)*100/real". The other values are all in unit of milliseconds.

#bleopt/declare -v exec_elapsed_mark $'\e[94m[ble: elapsed %s (CPU %s%%)]\e[m'
#bleopt/declare -v exec_elapsed_enabled 'usr+sys>=10000'
#bleopt exec_elapsed_mark=$'\e[94m[ble: elapsed %s (CPU %s%%)]\e[m'
#bleopt exec_elapsed_enabled='usr+sys>=10000'


## The following setting controls the exit when jobs are remaining. When an
Expand Down Expand Up @@ -934,7 +934,15 @@ blehook/eval-after-load keymap_vi blerc/vim-load-hook
## syntax analysis information and the syntax tree. This is only effective in
## devel versions.

#bleopt_syntax_debug=
#bleopt syntax_debug=


## When a non-empty value is specified to this option, xtrace (set -x) is
## enabled for the internal processing of ble.sh. The value is used for the
## xtrace output log filename. [ Caution: The file size of the log file can
## soon grow up to hundred megabytes or to gigabytes. ]

#bleopt debug_xtrace=~/blesh.xtrace


## [The setting "openat_base" needs to be set before ble.sh is loaded or
Expand Down
3 changes: 2 additions & 1 deletion docs/ChangeLog.md
Expand Up @@ -257,7 +257,7 @@
- complete: do not attempt an independent rhs completion for arguments (reported by rsteube) `#D1787` f8bbe2c
- history: fix the unsaved history in the detached state `#D1795` 344168e
- edit: fix an unexpected leave from the command layout on `read` `#D1800` 4dbf16f
- history: work around possible dirty prefix `*` in the history output `#D1808` XXXXXXX
- history: work around possible dirty prefix `*` in the history output `#D1808` 64a740d

## Documentation

Expand Down Expand Up @@ -376,6 +376,7 @@
- make: update lint check `#D1709` 7e26dcd
- test: save the test log to a file `#D1735` d8e6ea7
- benchmark: improve determination of the base time `#D1737` ad866c1
- main: support `bleopt debug_xtrace` (requested by SuperSandro2000) `#D1810` XXXXXXX

## Contrib

Expand Down
114 changes: 102 additions & 12 deletions note.txt
Expand Up @@ -3238,18 +3238,6 @@ bash_tips
の二層構造になっているがそれをもっと動的に変化できる様に改良するという手
も考えられる。

* main: BASH_XTRACEFD による出力の抑制?

| 更に set -x についてもまた駄目になっているかもしれない。→試してみた所
| attach 部分で無駄なメッセージが沢山表示される様になっていたが実行自体には
| 問題はない様である。然し、BASH_XTRACEFD を使った方が良いのではないか。こ
| れについてはまた別の機会について考える事にする。

現在の手法だと必要なエラーまで抑制してしまうし、標準エラー出力を抑制する為
に結構無理な事をしている。BASH_XTRACEFD を使って実装した方が綺麗になるので
はないか。然し、また色々と実装上の不都合が生じるかもしれないので取り敢えず
後でゆっくり対処する事にする。

2021-05-21

* progcolor: 取り敢えず builtin から始めるのが良いのではないかという気がする。
Expand Down Expand Up @@ -6402,6 +6390,108 @@ bash_tips
Done (実装ログ)
-------------------------------------------------------------------------------

2022-06-10

* [棄却] 2021-05-23 main: BASH_XTRACEFD による set -x 出力の抑制? [#D1811]

| | 更に set -x についてもまた駄目になっているかもしれない。→試してみた所
| | attach 部分で無駄なメッセージが沢山表示される様になっていたが実行自体には問
| | 題はない様である。然し、BASH_XTRACEFD を使った方が良いのではないか。これに
| | ついてはまた別の機会について考える事にする。
|
| 現在の抑制の手法だと必要なエラーまで抑制してしまうし、標準エラー出力を抑制す
| る為に結構無理な事をしている。BASH_XTRACEFD を使って実装した方が綺麗になるの
| ではないか。然し、また色々と実装上の不都合が生じるかもしれないので取り敢えず
| 後でゆっくり対処する事にする。
|
| →改めて確認してみたが、BASH_XTRACEFD は代入すると元々設定されていた fd が勝
| 手に閉じられてしまう。
|
| a なので元々設定されていた fd を保存する等の対処が必要になるがその為には様々
| なコマンドを呼び出す必要がある。だとすると結局現在の位置よりも上に
| BASH_XTRACEFD の書き換えのコードを移動することはできないので、現状使ってい
| る { ... } 2>/dev/null による set -x 対策を置き換えるには至らない。
|
| b BASH_XTRACEFD が設定されていなかった時にだけ BASH_XTRACEFD を使って set -x
| を抑制する
|
| % この様にしても BASH_XTRACEFD が既に指定されていた場合の為に { ... }
| % 2>/dev/null の対策は外す事ができない? と思ったが、既に BASH_XTRACEFD が設
| % 定されているのだとしたら {} 2>/dev/null としても意味がない (つまり 2 に出
| % 力される訳ではないので結局全て BASH_XTRACEFD に書き込まれてしまう)。
|
| うーん。然し、BASH_XTRACEFD を一時的に /dev/null に設定するとしても、どの値
| に設定するのかというのが結局問題になる。下手な fd を設定してしまうと変な所
| に書き込まれて問題になる。自分で fd を開くにしても空いている fd を探す必要
| がある。探す為には結局色々とコマンドを呼び出す必要がある。
|
| 色々考えると、単に BASH_XTRACEFD に値を設定するという話ではない。元々設定され
| ている BASH_TRACEFD を待避するのにも、出力先の /dev/null を開くのにも、空いて
| いる fd を探すのにコマンドを呼び出す必要がある。という事を考えると、結局現在
| set +x を実行している位置までは { ... } 2>/dev/null に頼る必要がある。なので、
| 現在行っている対策を減らす効果はない。
|
| 一方で必要なエラーまで抑制してしまっている事についてはどうか。例えば { ... }
| 2>/dev/null を単に除去してしまう。そうすれば set -x の出力も通常のエラーも全
| て表示される様になる。然し、結局 set -x の出力を抑制する方法が他にないので、
| やはり現在の位置までは { ... } 2>/dev/null で対策しておくしかない。

[結論] 当初使えるかもしれないと思ったのは BASH_XTRACEFD への設定が (設定に影
響を受けない) 変数代入だけで行えると考えたからであったが、その前に空いている
fd を探索して更にその fd に対して /dev/null を開く為に builtin を呼び出す必要
がある。従って adjust-builtin-wrappers 以前は結局今までの対策を使う必要があり、
それは現在の対策範囲と変わらない。

* 2022-04-15 ble.sh 内部に対する xtrace (set -x) を有効にする方法 (requested by SuperSandro2000) [#D1810]
https://github.com/akinomyoga/ble.sh/issues/186#issuecomment-1099696862

うーん。取り敢えず無理やり実装してしまって良い気がする。

* 設定 interface をどうするか

と思ったが interface をどのようにするかが微妙である。取り敢えず提案された様
に BLESH_DEBUG 等の環境変数経由で設定する事にするべきか。と思ったが、bleopt
で設定するべきの気がする。例えば、以下の設定がある時には set -x をしないと
いう事。

bleopt debug_xtrace=ファイル名

うーん。これに対応する為にはユーザーの設定した BASH_XTRACEFD を何処かに保存し
ておく必要がある。そしてその為にはファイルディスクリプタの探索等を実装する必
要がある。などなど色々考えると、ロードした瞬間に実行するには処理として複雑す
ぎる。そう思うと BASH_XTRACEFD は切り替えずにそのままユーザーが設定した物に出
力するというので良いのではないか。

* というより元々の 2021-05-23 の項目の意図は set -x の抑制を BASH_XTRACEFD を
使ってできないかという事だった様な気がする。つまり、今回の ble.sh に対する
デバグの目的で BASH_XTRACEFD を設定するという話とは違う話なのではないか。

とは言いつつ set -x を抑制する為に /dev/null に設定するのを、debug_xtrace
が指定されている場合には代わりにそのファイルに BASH_XTRACEFD を設定するべき
だろう。という事を考えれば全く関係ない訳でもない。

取り敢えずこちらを先に対応してから、2021-05-23 の項目に対して set -x 対策で
強制的に抑制している範囲を減らす事ができないか検討するという事で良い気がす
る。

取り敢えず簡単に作って試してみた。あっという間に数百MBに達するので実際にこれ
を使って debug する事が現実的なのかは疑問であるが、本当にクラッシュする時など
には便利かもしれない。然し、幾らか問題点がある。

* fixed: 元々 BASH_XTRACEFD に設定されていた fd を別の番号に dup しておく必要
がある。何故なら BASH_XTRACEFD が変更される瞬間にその fd は閉じられてしまう
から。然しその為には空いている fd を確実に探し出す必要がある。

* fixed: 現在 context を switch する度にファイルを開いているが、debug_xtrace
が設定された時に fd を開いておいて以降はそれを dup するべきなのではないか。
毎回開き直すのは大変だし、ファイル名が相対パスで指定されていた場合、ディレ
クトリ毎にファイルが作られて面倒な事になる。

x 実際に試してみると set -x した時の抑制に失敗している → 何かと思ったら
adjust/restore options は入れ子で呼び出す事を許容しているのだった。対応した。

もっと複雑化と思ったが上記に対応したら原理的な問題ももうない気がする。

2022-06-09

* compat: Oh My Posh と組み合わせると動かないという質問が reddit にある (reported by abyss6166) [#D1809]
Expand Down
2 changes: 1 addition & 1 deletion src/util.sh
Expand Up @@ -3280,7 +3280,7 @@ fi

## @fn ble/fd#is-open fd
## 指定したファイルディスクリプタが開いているかどうか判定します。
function ble/fd#is-open { : >&"$1"; } 2>/dev/null
function ble/fd#is-open { builtin : >&"$1"; } 2>/dev/null

_ble_util_openat_nextfd=
function ble/fd#alloc/.nextfd {
Expand Down

0 comments on commit 022d38b

Please sign in to comment.