差分表示


*&date(Y-n-j[lL],2009/11/26); 〔D言語〕Ddbgの再コンパイル

Ddbg(Descent,CB)を使って変数表示がおかしくなるのは、
どうも Ddbgコマンドの lsv が使われた時みたい...
なので、そこそこ状況限定されるから、なんとなくバグとれそうな
気がしてしまったで、
ソースのsvnリポジトリ[[r1094>https://svn.mainia.de/svn/ddbg/trunk]]
をみると実は公開exe(v.0.11.3)よりも新しいv0.12(2008-3-26)のソースがコミットされているようなのでした。
(コミットログにはbasic hardware breakpoint support-minor changesと)

で、とりあえず Ddbg をコンパイルしてみたのですが...
そこはD言語、やっぱり泥沼にはまったのでした。

Ddbg 自体はD1で作られていて、
最新のD1でコンパイルしても今まで見過ごされていたバグが
検出される程度(すぐ修正可能)だったのですが、
問題は、bud とパーサージェネレートに使われてる Apaged.

budはエラーがでるため、apagedは配布サイトにソースしかないため、
ツール自体の再コンパイルを行ったのですが、まさにドツボ。~
dmdのバージョンやtangoのバージョン等罠にはまりまくりで、最終的には断念。~

結局、budについては、ソース構成割り出してバッチで処理,
apagedに関してはふと apaged.exe を検索したら[[こちら>http://www.dsource.org/projects/arclib/browser/trunk/arclib/arc_hybrid/hybrid/apaged.exe?rev=1525]]で見つかったので
それを用いることでなんとか.

ただ apaged 自体の文法に変更があったり、
ジェネレートされたルーチンの関数引数が変わってるため
Ddbg側もそれに合わせて必要だったり、と結構疲れました.

あと win32 bindingも、今のdmdだと依存関係でひっかかり、ちょっと嫌な修正.
udis86-1.4部分もたいしたことないけど
(こいつも perl でソースジェネレートとかあって、それをさけるため)
makefile若干弄ったりとか.


~

で、肝心の Ddbg lsv のバグですが、~
ddbgcli.d の evalScopeSymbols() 内

 StackSymbol[] locals_args = scope_sym.symbols.stack_symbols;
 auto psym = cast(ProcedureSymbol)scope_sym;
 if  ( psym !is null )
     locals_args ~= psym.arguments.stack_symbols;
 foreach ( sym; locals_args.sort )
 {

の部分で、関数内ローカル変数一覧に関数引数変数を追加して
ソートし出力してるのですが、locals_args がコピーでなく実体
を指しているため、追加&ソートにより scope_sym.symbols.stack_symbols が
破壊されてしまっていたようです.~
(main(char[][] args) { int i=0; ... } て感じに引数が中のローカル変数より
若い名前だと、デバッガの変数一覧で args が複数表示され他の変数がなくなる、
という状態)

とりあえず .dup つけて
 StackSymbol[] locals_args = scope_sym.symbols.stack_symbols.dup;
[CR]
で直るよう.
~
(.dup抜けって D言語の落とし穴の代表例の一つだよなあ、って気も)


弄った Ddbg をさらしておきます. 

[[[download>http://www.6809.net/tenk/html/lib/ddbg_r1094_a.zip]]]

>>>※どうも元配布のDdbg.exeは実行ファイル圧縮されているぽくexe小さいのですが、これはそんなことしていないので、ちょっと太めです.

~

*** ついでにbudのバグもメモ.~

文字列インポートとしての import("file.txt") に未対応のよう.

source.d の void doImport (in string pFileText, inout int pPos) 中の

 bool	first = true;                             //@@@
 while ((lSavedPos = pPos,
         lCurrentToken = GetNextToken (pFileText, pPos)) !is null
            && (lCurrentToken != ";"))
 {
     if ( lCurrentToken == "(" && first) return;   //@@@
     first = false;                                //@@@
     if ( lCurrentToken == ",")

のwhile付近に //@@@ の処理を追加すればとりあえずなんとかなるぽい.~
(あとbuild.d (1450) のreturnの戻り値不要)

(自分のコンパイルしたexeを使って出るエラーの原因が不明なんでexe無)


----

と書いててて思い出した.

dmd自体の仕様変更かバグかしらないけど、
ddbg の再コンパイルではまった件として、-Jsrc 状態で import("cli\ddbg_help.txt") が使われてもソース無いって起こられてた.~
とりあえず -Jsrc\cli にして import("ddbg_help.txt") にすることで回避.


----
#comment