日付け越え少し前に帰着。
鉄拳やったりして終了。
日付け越え少し前に帰着。
何気に見ていた「ネギま!」の最終回。途中これ、どうなるのかと思って
いたけど、最後全員がしゃべって無理矢理つなげたという感じでしたが
まぁ。
日付け越え。
ちょろっとディスプレイを分解して、様子を見たのですが、やっぱ
ブラウン管が反応していない様子。
日付け越え。
なんもできないので、鉄拳やって寝たり。
昼過ぎに起きてぐうたら過ごしたり。
何気にディスプレイをつけっぱのまま他の事をやってたら、急に画面が暗くなって
何も映らなくなったり。新手のウイルスか?と思ったのですが、調べてみると
ディスプレイの設定画面なんかも出なくて、ブラウン管のビームが出ていない
という感じ。むーん。
分解して調べようと思ったのですが、夜も遅いので諦めたり。
何気に見ていた「まほらば」が最終回だったり。多重人格のキャラクタのヒロインを
どうやって扱うのか興味深いところだったのですが、最後はうまい感じに収まった
ように感じました。
朝から裏のアパートの取り壊し工事が行なわれていてうるさくて起こされたり。
でも、ぐうたら過ごしてあっという間に夕方。
脳の記憶についてのTV番組をやってたり。その中でルービックキューブの
すごいのを見たり。回すのをパターン化しているという事でしたが、見て
すぐにどう回すのか判断できるものなのか?と思ったり。でも、見てどう
反応する以外に、バラバラの状態を覚えた後、目隠しで色を揃えるという
のは、テクニックでどうにかなるという感じではないような?と思ったり。
以前、将棋の名人が100手以上の詰め将棋の答えを出すのに、頭の中だけで
詰める手順を考えていたというのを思い出しましたが、何かしらの流れで
覚えるというか、動かした手順を覚えるというか、そういう事なのかしら?
反復によって記憶されるというような事を言ってましたが、それは確かに
と思ったり。いきなりやった事の無い事を最初からうまくできる事って
あんま無くて、何度かやっているうちにそのコツを掴むというのは良く
ある事だと思います。そしてコツを掴めば、大体何度やってもうまくいく
という感じ。経験による学習というのは、あまりかっこ良く無いようにも
見えるのですが、大体の問題は反復で得た経験で解決するものなのかも。
例えば「直感」は、全く見た事の無い問題に対しては殆ど働きませんが、
経験した事のあるのと似た問題に対しては、すぐにここが変とは判らなく
ても、「何か変」というのにはなんとなく気づくという事はよくあります。
何度も繰り返すというのは、アホっぽいですが一番確実に会得する方法
なのかも知れません。
日付け越え。
ちょろっと追いかけ続き。これという感じの反応は見つけられず。
日付け越え。
何気にDなソースで書いた実行ファイルをgdbを使って起動してみた所、
いつの間にかデバッガが使える様になっている予感。ただし、
Windowsアプリなのはダメ。これはCなソースのそれも同じなので、
まぁ。これでSegfaultが再現してくれれば一番良いのですが、
世の中うまくいかないものです。
で、追いかけの続き。使っているハズの領域を開放するかどうかを
判定している部分があり、そこを観察してみた所、そこんところで
は既に開放されたように見えている予感。原因はもっと手前か?
日付け越え少し前に帰着。
fullGCを一度でも実行するとおかしくなるという事から、意図的に
fullGCを実行させれば簡単に再現プログラムが作れるのでは?と思って、
適当にクラスを割り当てては捨ててを繰り返した後、
関数fullCollect() を実行してみた所、何故か空きブロック回収が
一度も発生できず。fullGC自体は動作しているのですが、GC後、
回収できたページ数が何故か0という結果ばかり。むーん。
明示的にnullを突っ込めばfullGCでゴミ回収ができるようになってみたり。
少し前までは、delete文を使用すれば、デアロケータを起動できるという
仕様だったみたいですが、連想配列のハッシュキーを消すのにもdelete文
を使うようになってました。ところが連想配列のキーの方はremove()
メソッドで消すようになったのですが、その時からdelete文を使うと
コンパイラが「キーを消すにはremove()を使え」というエラーを出すように
なってしまい、デアロケータとして動かす事もできなくなってしまった
という感じ。むー、なんだそれ?よう判らん。
さておき、肝心のfullGCとアロケータの関係を、パターンを変えながら少し見てみた
のですが、使っているメモリ領域を誤って開放してしまうような事は
ありませんでした。うーん。
日付け越え。
GCおっかけの続き。
gcc/d/phobos/internal/gc/gcx.dの構造体Gcx内のメンバー関数である所の、
fullcollect()がfullGCの本体で、ここんとこにprintfを入れまくって
動きやデータを観察してみました。この中では、何やらメモリブロックの
具合をチェックした後、使われていないと判断されると、B_FREEという属性
を付け、最後に持っていたブロック全てをなめなおして、B_FREEでないメモリ
ブロックだけをバケットに繋ぎとめるという事を行なっているようです。
で、B_FREEの属性を付けるメモリブロックを見ていると、まだ割り当てて
参照があるハズのメモリブロックが何故か空きだとみなされて、
B_FREE属性を付けられてしまっているようでした。不具合の一連の動きから
想像した空きの誤認識がまさにここで起こっているという感じ。
いつもより早めに帰着。
先日ビルドを仕掛けたgdcをインストール。でも、phobos内のgcx.dは
013の時と同じなので、fullGCによる問題はそのまま。
全部潰してあったfullGCを実行するコードをちょっとずつ元に戻しながら
一回だけfullGCを実行して変になるパターンにしてみたり。
丁度以前調べた、同じポインタが二重に割当たる再現パターンで、
二重にポインタが割当たる直前に一度だけfullGCを実行した感じに
なったので、ここんところで空きではない領域を間違って空きだと
している部分に辿りつければ直せるかも。
昼頃起床。
Mr.インクレディブルのコメンタリーを観たり。コメンタリーが2種類
あったので、少々観るのに(聞ければ良いのですが英語なので(^^;)疲れましたが、
なかなか面白かったです。髪の毛や布のシミュレーションの苦労やら、
主役以外のキャラクタの作り方など色々。一番驚いたのが、髪の毛の動きは
物理シミュで付けたようで、重力やら風やらを設定して後は祈るという感じ
だったという所。それ本当?ってのが第一印象でしたが、ガイド的なもので
補正すると逆に不自然に動いたりするという事だったのかしら?と思ったり。
あまりにも自然に仕上がっているので、凄さが判らないくらいという感じ。
他、やっぱり物量の多さが普通じゃなかったようで、ほんの少ししか映らない
シーン(でもモデリングは必要)とかもかなりあった模様。ファインディング
ニモで20シーンくらいだった
のが100以上という事だったのですが、インクレディブルでの多さよりも、
ニモの方の少なさの方が意外に思ったり。
そういや、人間を描く事の難しさについて終始話をされていました。
デフォルメの魚や虫であれだけ動かせれば、人がそれほど問題になるとも
思えなかったのですが、そういうものでは無いみたい。特に3DCGの場合だと
人と人形の差が微妙なラインにくるようで、ライトの当て方一つで
人形になったりする点などは難しさの一つに挙げられるみたい。
GCのコードをいじって反応を見たり。fullGC自体は実行しなくても動く
もののようなので、動かし所の問題なのか?と思い、色々パターンを
作ってみたのですが、結局fullGCを動かすと変になるというのが結論
の模様。ずっこけの秘密を解明するには、fullGCのやり方をやっぱり
よく見てみるしかない模様。
gdc-0.14が出ている模様。最近更新率が高いのはなんで?
暑くてぐったり気味。
CD屋に行ったり鉄拳やったりしてぐうたら過ごしたり。
GCのコードを読んだり。4096byte以下の割り当てでは、最小単位が
4096byteのブロックそのものなので、fullcollectする必要は無いような
予感。fullGCがどのような契機で働くのか調べたり色々。
「Mr.インクレディブル」を観たり。ヒーロー世界と日常生活を融合
すると、ダウンタウンのやるコントみたいなのを連想してしまうTANEなの
ですが、アメコミヒーローでは日常と非日常の狭間で苦悩するというのは
意外と多いような気も。普通に面白かったです。異常な物量が気になった所
です。
電池切れ気味で日付け越え前に帰着。
GCのコードを読んでみることにしたり。GCというかまずはアロケータの方から。
割り当てサイズが4096byteよりも小さい場合、gcx.bucketと呼ばれるメモリブロック
のリストから、該当するサイズの空きを探し出し、空きがあればそれをポインタ
として返す感じ。pagetableの中から切り売りしているような感じなのですが、
まだ動きがよく判らず。
日付け越え少し前に帰着。
狼少年でやってた「これじゃないロボ」。バカっぽくて良いです。
どう実装するかなぁと考えてたら眠くて死亡。
日付け越え少し前に帰着。
取りあえずGCを追いかけるのは置いといて、箱庭の実装を考えてみたり。
そういや殆どBGV代わりに観ている「ネギま!」のアニメですが、先週から
なにやら変な空気になってて、みててムズムズする感じ。この感覚、
昔やってた「ラブひな」の終り近い頃と同じような気が。なんていうか、
キャラに合わない変にシリアスな展開がどうも肌に合わないみたい。
回復できず一日休業。
先日の実行結果、よく考えてみますにGCによるゴミ回収が発生したとして、
vtx[]に対する領域はまだ掴んだままな訳ですから、そこを二重に指すと
いうのはアロケータのバグの様に思えてきました。
で、追跡してみたところ、次のような感じになっているようです。
GCクラスのmalloc()メソッドの中では、更にmallocNoSync()というメソッド
を呼び出していて、これがメモリ割り当て作業を行なう一番上位のメソッド
のようです。このmallocNoSync()の中では、割り当てサイズに応じて動作
が分かれるようで、割り当てサイズを引数として、gcx.findBin(size)と
いうのを実行すると、何かしらのサイズが返るようで、そのサイズが
B_PAGE以下の場合とそれ以上の場合とで動作が切り替わるという事のようです、
で、先日の頂点配列の割り当てはB_PAGEよりサイズが大きい場合の動作
を行なっているようで、その場合はgcx.bigAlloc(size)でメモリ割り当て
を行なっているようでした。このbigAlloc()を実行するケースというのは
あまり無いようで(今回のコードだと頂点配列割り当て以前に一度だけ
実行されるだけでそれ以降頂点配列割り当てまで一度も実行されてません)、
これが今回のハマリどころのようです。ただ、具体的に
どこがどうバグっているかという所までは追跡できてません。
単純にbigAlloc()を踏むとエラーするというのならば話は簡単なのですが、
ほんの少しコードを変更するとbitAlloc()を実行してもエラーしなくなったり
する為、あまり簡単な話では無いようです。
結局、今回のSegfaultずっこけは二つのバグを踏んでいました。一つはbigAlloc()
の問題、もうひとつは、構造体をstatic宣言で割り当てるの二つ。
違う話を同時に踏んだので、なにがなんだか訳が判らないという感じでした。
bigAlloc()の方はコンパイラに原因があるのではなくGCのコードに原因がありそうな
予感がしなくもないで、どっかで似た現象を踏んでいる人が居てもよさそうに
も思えますがどうでしょう。
もう少しだけ追いかけ。bigAlloc()のコードを少し読んでみたり。
手順としては、「(1)fullcollectshell()というゴミ回収を一度試みる。
(2)メモリを割り当てる。」という感じ。先日のエラーの状態で、一度
アドレスが若い方に戻っているのは、ゴミ回収を試みているからという
感じだったのかも。ただ、そこに誤りがあり、まだゴミになっていない領域
をゴミだと誤認識した為、先日のような二重割り当てという結果になったの
ではないかと推測しました。そこで、fullcollectshell()を実行するのを
辞めてみた所、先日のメモリ重なり現象は出なくなりました。でも、
やっぱりSegfaultで死ぬ模様。で、mallocNoSync()でbigAlloc()を
実行しない方も見てみました。こちらもゴミ回収を試みた後、実際
のメモリ割り当てを行なうという手順のようだったので、
fullcollectshell()を実行しないようにしてみました。すると、
Segfaultでずっこけることは無くなりました。という訳で、
アロケータというよりは、ゴミ回収の方に問題があるという事の
ような予感。fullcollectshell()の中も少し眺めてみたのですが、
ここはコードが大きい為、ぱっと見ではよく判らず。
調子が悪くてほんの少し早めに帰着。
ガベージコレクタのソースを眺めていると、デバッグprintが仕込まれて
いるようだったので、メモリ割り当ての様子を少し眺めてみる事に
してみました。
ソースはgcc/d/phobos/internal/gc/gc.dで、この中の _d_new()や、
_d_newarrayi()といった関数が「new」に対応する形で呼ばれるようです。
この関数の中ではGCというガベージコレクタクラスのmalloc()というメソッド
を呼び出しているだけで、見かけ上、必要なサイズ分をmalloc()で得ている
だけという感じ。デバッグプリントを生かして、コードをコンパイル&実行
してみた所、以下のような感じで怪しげな感じになってみたり。
_d_newarrayi(length = 8192, size = 32) .... p = 0x843c2000 #←ここ vtx.length=8192 _d_newarrayi(length = 8192, size = 32) .... p = 0x84403000 nml.length=8192 _d_newarrayi(length = 8192, size = 16) .... p = 0x84444000 uvm.length=8192 _d_new(length = 8192, size = 16) .... p = 0x84465000 fcV.length=8192 _d_new(length = 8192, size = 16) .... p = 0x843c2000 #←ここ fcN.length=8192 _d_new(length = 8192, size = 16) .... p = 0x843e3000 fcT.length=8192
vtx = new vec3D[8192] ; printf("vtx.length=%d\n",vtx.length) ; nml = new vec3D[8192] ; printf("nml.length=%d\n",nml.length) ; uvm = new vec2D[8192] ; printf("uvm.length=%d\n",uvm.length) ; faceV = new face3D[8192] ; printf("fcV.length=%d\n",faceV.length) ; faceN = new face3D[8192] ; printf("fcN.length=%d\n",faceN.length) ; faceT = new face3D[8192] ; printf("fcT.length=%d\n",faceT.length) ;
起きたら夕方。
ぐうたら鉄拳5などをしながら過ごしたり。
gdc-0.13を入れてみたり。すると、何故かエラー。なにやら連想配列の
keyを消すのに、今までdelete文を使用してたのを、remove()メソッドを
使用してkeyを消すようになったみたい。そこを直して取りあえずコンパイル
できたのですが、何故か実行してみると、ArrayBoundsエラーとか出るように
なってみたり。うーむ、何がなにやら。もっと小さい再現プログラムを作らないと
なんだか訳が判らないといった感じ。
再現プログラムはイマイチ。色々試していて少し判った事。
Segfaultになる直接の原因はインスタンス化したクラスのメソッド呼び出しを
まさに行なおうという部分。この時、コンストラクタ内でメソッド呼び出しを
行なってもNG。メソッド呼び出しの手前で、構造体で構成される頂点データ配列
を割り当てていますが、これをやめるとメソッド呼び出しはできる。
まとめると、配列割り当てを行ったとき、インスタンス化したクラスがぶっ壊れて
いるという感じに見えなくもありません。
腹が減った感がして起きたらバク天が始まっていて驚いたり(汗;
鉄拳やったりしてたら一日終了。そういや先日、Extraコスチュームから
元に戻らないと言っていた話。スタート時のボタンを変えれば良いだけ
でした(^^; 普段の動きがパターン化され過ぎ。
どうにもお手上げ状態のgdcですが、0.13と、Cygwinパッケージで、
3.4.4にgdcとgdcのmingw対応版が含まれたようなので、ダウンロードして
みたり。でも、やっぱり現象変わらず。
0.13のビルドを行ないながら、あれこれ試した所、ついに反応する点を
見つけたり。WindowsAPIで使用している、PAINTSTRUCTやPOINTといった
構造体ですが、こいつをstaticにすると大丈夫になってみたりしました。
これらは別に配列でもなんでもないので、文法上はnewとかを使って
領域を割り当てている訳では無いのですが、何故かどこかの領域と
重なっているような予感。で、頂点リストの配列割り当てサイズが大きかった
ので、ちょっと小さくしようと、値を変えたらまた動かなくなったり。
もう何がなんだか。
日付け越え。少し前に帰着
取りあえず、以前動いていた状態まで戻そうとしたのですが、
どうにも元に戻らなくなってみたり(汗;コンパイラのバージョンを
0.12まで戻しても変わらず。なぜ?
日付け越え。
そういや
以前、構造体の中で
動的配列宣言をすると、何故かstaticを付けないと原因不明のシステム
フリーズに陥るという現象がありました。もしや、動的配列に限らず
なのでは?と思い、staticを付けてみた所、少しずっこける位置が
変わるようになったのですが、やっぱりずっこけは変わらず。
しばらく追ってみたのですが、何故か配列の内容がすり替わっている
ような現象が見られていて、もう何がなにやら。
日付け越え少し前に帰着。
先日のビルドは結局ずっこけてたり。なにやらgdcのコンパイル結果を
食ったアセンブラでのエラーのようで、恐らく同じ話と思われる話題が
CygwinのMailingListにあがっていたので、ML内のやり取りの中にあった、
取りあえずなパッチをあててみた所、ビルドできました。
記録の為、パッチをコピペ。
--- d-codegen.cc.orig Tue Jun 7 14:10:57 2005 +++ d-codegen.cc Tue Jun 7 14:11:55 2005 @@ -1757,7 +1757,7 @@ char buf[256]; #if defined (TARGET_IS_PE_COFF) - if (DECL_ONE_ONLY (function)) + // if (DECL_ONE_ONLY (function)) return function; #endif
日付け越え。
先日のビルドはずっこけてたり。なにやらコマンドがみつからないとか
でエラーした後のソースのコンパイルに失敗していたり。
gcc/d/target-ver-syms.shというスクリプトの実行に失敗したようなの
ですが、このスクリプトの行頭が「#」のみとなっていて、
シェルが起動できなかったという感じ。行頭に#!/bin/shと書き加えて
再度makeを実行したら、取りあえず先に進んでみたり。むーん。
日付け越え。
Segfaultの原因を調べようと思ったところ、何故かgdcの新しいのが出ていたので
そちらを試してみることに。ビルドを仕掛けてほったらかし。
少しランブルローズの方はお休みで、再び鉄拳5に戻ってみたり。
ところで、Extraコスチュームをゲットしたのは良いのですが、少し飽きた
ので、ノーマルコスチュームに戻そうと思ったところ、はて、戻し方が
判らず。何をやっても変化が見られない所を見ると、もしかしてExtraコスチュームを
戻す事はできなかったり?むーん。
いいとも時間に起床。風邪は治る気配が見えず、ぐうたら過ごしたり。
少し動けるところで本屋に行ってファミ通WaveDVDなど買ってきたり。
帰って食事をしながら鑑賞。ソウルキャリバー3キター!そんな感じ。
そういや、2の時はPS2,GC,Xboxの三機種同時移植でしたが、3は今の所
PS2だけみたい。最近はそういうのもあまり聞かなくなった気もしますが。
他、ぺリボーグ
。バカっぽい....てゆーか、バカです。これ。
起きたら夕方。寝過ぎ。
なんだか風邪気味で絶不調。
3Dの頂点を構造体の配列で扱っているのですが、この配列の初期サイズを
変えると、ずっこける場所が変わったり。それでもメソッド呼び出し時点
でこけているのには変わり無いようで、なにかしら変に書き換えられている
という感じがしなくもない予感。
SAIの新しいのが出てたり。
日付け越え。
Segfaultの原因を調べてみることに。今の所、ダメなケースは、
Regexクラスのメソッド呼び出しでSegfaultになるというものでしたが、
今回はそこん所を通過してずっこけている予感。デバッガが使用できない
ので、無限ループやprintfを挟みながら死ぬ場所を特定したところ、
以前とは違って全く別のクラスのメソッド呼び出しでずっこけている
事が判りました。自分で作成したクラスの中での出来事なので、少し
書き換えてみたりしながら様子を見たのですが、どうもメソッドの呼び出し
自体がうまくできていない様で、メソッドの中にデバッグコードを埋め込んでも、
そこまで到達できない模様。なんで?
日付け越え前に帰着。
地面をモデリングして読み込んでみたところ、何故かSegfaultで死亡。
むーん。
日付け越え前に帰着。
先日のgdcビルドはエラー終了していたり。原因は
以前ハマったversion(cygwin)を
通過できずにenum定義が行なわれず、その先でエラーになるというもの。
そこんところを前と同じように直して一応ビルド完了。make installして、
適当なソースをコンパイルしてみたところ、何故かリンクでエラー。
よく見てみると、libphobosが lib'g'phobos になっていたのですが、
Windowsアプリを書くのにコンパイラがリンカに渡す引数とは別に
libphobosを再指定していたため、
libgphobosとlibphobosの両方を指定した状態になり、
関数が衝突してリンクに失敗するという感じでした。再指定する方も
libgphobosを使用することで無事リンク完了。取りあえずは動いてそうな予感。
物理シミュの箱庭モデルの続き。と言ってもまだ悩み中。悩んでいるのは
重力が常にかかっているとしたとき、地面の上の物体をどうやって止める
か?という点。物理的には水平な地面に接した物体は、重力と同じ大きさの力が
重力と反対方向に働いて相殺した結果、
動かないように見えるという感じになります。結局、地面に接触したこと
を判定しないことには、重力と反対に働く力を加えて良いのかどうかが判らない
ので、斜面を転がることも、反射して弾むことも判定できないという結論に
達してみたり。