昔の最近の出来事(2012.05)

2012/05/31

遅めに帰着。

眠くて急速停止。

2012/05/30

早くも無く遅くも無く。

ちょろりコーディング。

gdc。DMD2.058マージ版以降、更新が少し活発になっている気が。うれしい事です。

2012/05/29

早くも無く遅くも無く。

もそもそとコーディング。

2012/05/28

早くも無く遅くも無く。

もそもそとコーディング。

gdc。キューに置かれていた Daniel Green氏の DMD2.058マージ版がtrunkに合流した模様。 ただ、MinGW向けには少し変更が足りないような気も。

2012/05/27

AM中に起床。

もそもそとコーディング。

2012/05/26

AM中に起床。

gdc。オプティマイズ不具合の件。最初に壊れているのに気づいた のはbitbucketの 6f10e575ee76。 このバージョンは色々壊れていたので、この時は別件の方を調べてました。 DMD2.057を取り込んだすぐ後くらいの版では問題無かったので、この間 に加えられた変更で壊れています。でも、変更点が大量にありすぎて見当が付かず。
で、どのオプティマイズオプションが効いているのか調べてみたり。 すると、omit-frame-pointerが効いている事が判明しました。 具体的に「-O0 -fomit-frame-pointer」ではダメ、一方「-O1 -fno-omit-frame-pointer」では 大丈夫という感じ。

gccへのパッチの問題かと思い、d/patches の中のファイルを見てみたのですが、 同じgccのバージョンに対して、パッチ自体がやたら変わっているのと、 パッチファイル同士を単純にdiffで比較するのでは違いが出まくりで何がなんだか よく判らなかったり。

そういえば、githubの各プロジェクトページに「Network」なるボタンが付いています。 いろんな人のfork具合を可視化してくれるので、trunk(本流)とは別の所で機能の追加 や良さげな修正を行っている具合が判ります。現在、GDCはtrunkの更新が停滞してる感じなの が少し残念。

extern(C)な関数呼び出しがうまくいってない件。wintab32.dll内に含まれる WTPacketsGet()を、Dで「extern(C) export int WTPacketsGet ( HCTX hCtx, int cMaxPkts, LPVOID lpPkts ) ;」 な感じで宣言してから使用しています。wintab32.dllの方はDLLしか無いので、再コンパイルする 事ができません。そんな感じなので、dll呼び出しでズッコケ再現させる 最小コードが書けないかと試してみたり。

$ cat test_cfunc.c
#include <stdlib.h>
#include <stdio.h>

int testprint(int a, int b)
{
  printf("test print a=%d, b=%d\n",a,b) ;
  return(0) ;
}

$ cat test.d
import std.stdio ;
import std.string ;

extern (C) int testprint(int a, int b) ;

void main()
{
  int i=testprint(1,2) ;
  writef("i=%d\n",i) ;
}

$ gcc -shared -O2 -o libtest.dll test_cfunc.c

$ gdc -O2 test.d libtest.dll

$ ldd ./a.exe
        ntdll.dll => /cygdrive/c/WINDOWS/system32/ntdll.dll (0x7c940000)
        kernel32.dll => /cygdrive/c/WINDOWS/system32/kernel32.dll (0x7c800000)
        msvcrt.dll => /cygdrive/c/WINDOWS/system32/msvcrt.dll (0x77bc0000)
        SHELL32.DLL => /cygdrive/c/WINDOWS/system32/SHELL32.DLL (0x7d5b0000)
        ADVAPI32.dll => /cygdrive/c/WINDOWS/system32/ADVAPI32.dll (0x77d80000)
        RPCRT4.dll => /cygdrive/c/WINDOWS/system32/RPCRT4.dll (0x77e30000)
        Secur32.dll => /cygdrive/c/WINDOWS/system32/Secur32.dll (0x77fa0000)
        GDI32.dll => /cygdrive/c/WINDOWS/system32/GDI32.dll (0x77ed0000)
        USER32.dll => /cygdrive/c/WINDOWS/system32/USER32.dll (0x77cf0000)
        SHLWAPI.dll => /cygdrive/c/WINDOWS/system32/SHLWAPI.dll (0x77f20000)
        libtest.dll => /home/tane/develop/dlang/test/dll_linktest/libtest.dll (0x62640000)   #生成したdllが必要

$ ./a.exe
test print a=1, b=2
i=0

再現できず。
DLLの中に含まれる関数をextern(C)宣言してDから呼んでいる コードとして、OpenALのalut.dllを使っている手持ちコードがあるのですが、 そちらは特に問題無さげです。DLL自体に何かしらの違いがあるのかなぁ?と思ったり。

深堀隆介という人を知ったり。立体的で超リアルな金魚作品がスゲー (オフィシャルサイト)。

2012/05/25

日付け越え前に帰着。

gdc。手持ちコードの一つがオプティマイズオプションを付けてコンパイルするとSegfaultする 実行ファイルが生成される件を調べてみたり。 どうやら、とあるextern(C)な関数呼び出しがうまくいってない模様。 gdbでスタックトレースをSegfault後に表示しようとすると、スタック自体がメチャクチャ に壊れてしまっている様子からも確からしい。

眠くて死亡。

2012/05/24

遅めに帰着。

ちょろりコーディング。

2012/05/23

早めに帰着。

あまりの眠さに急速停止。

2012/05/22

早くも無く遅くも無く。

ちょろりコーディング。

2012/05/21

遅めに帰着。

gmp/mpfrのマルチスレッドビルドもできるのかしら?と思い、先日gdcをビルドした ついでに生成されるgccを使って実験してみたり。ビルドしたあと、 マンデルブロ集合プログラムのMPFR使用版のループを std.parallelism使用 にしてみたのですが、やっぱりNG。ちぇっ。

2012/05/20

AM中に起床。

gdc。-mwindowsを付けるとWinMainから始めるようにしたのは、Daniel Green氏の パッチだからなのですが(以前の話)、 それだと具合が悪いのでgcc/d/d-spec.cをいじって -mwindowsが指定されても 変数include_dmainを変更しないようにしてみたり。 因みに、WinMainから始めたい場合は -fno-dmain を使えば良いかも。

手持ちコードの殆どはビルドも実行も問題なさそうなのですが、一つだけダメなのが あったり。ゲフっ。
少し調べてみると、配列のサイズを変更するコードにおいて、配列サイズを大きく しようとしたときにGCの中でずっこけているという感じ。GCをdisableにすると エラーせずに動くのですが根本的な解決にはならず。ずっこけ箇所となっているクラス は他のアプリでも使っているのですが、ずっこけるのは一つだけという点が 納得いかない。

DanielGreen版gdc(venix1-GDC-5338397 + gcc-4.6.3)ではいくつかの不具合が 解消されています。


変わらない、もしくは新しく増えた不具合は以下の様な感じ。


概ね良い感じなのですが、binutilsやMinGW本体の方にもパッチを当てなくては ならないのはちと大変。

配列サイズ変更でずっこける件を少し追いかけ。どうやら、 以前調べたこの話と同じでした。 前と同じく libdruntime/gc/gcx.dのGcx.fullcollect(void *stackTop) で、変数running を1にセットしているのですが、1にセットするのをやめるとずっこけなくなったり。 Segfaultするのは onInvalidMemoryOperationError()を無限に呼び続けてスタックオーバーフロー しているというという事なのですが、無限ループに飛び込んだ理由の方がよく判らずのまま。 結局、fullcollectの開始で変数runningを1にしているのですが、その変数を参照している 数箇所の中に、実は参照してはいけない箇所があるという感じなのかも。

次のような感じか?スタックトレースを見たところ、無限ループの開始は以下のように なってました。

#32465 0x0045c088 in onInvalidMemoryOperationError () at ../../../../gcc-4.6.3/libphobos/libdruntime/core/exception.d:517
#32466 0x00477709 in gc.gcx.GC.mallocNoSync (this=..., size=41, bits=8, alloc_size=0x22e528) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gcx.d:483
#32467 0x004780ed in gc.gcx.GC.malloc() (this=..., size=41, bits=8, alloc_size=0x22e528) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gcx.d:463
#32468 0x00461e94 in gc.gc.gc_qalloc (ba=8, sz=41) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gc.d:210
#32469 gc.gc.gc_qalloc (sz=41, ba=8) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gc.d:205
#32470 0x0042828e in _d_newarrayT (ti=..., length=1) at ../../../../gcc-4.6.3/libphobos/libdruntime/rt/lifetime.d:819
#32471 0x004246ed in _d_throw (obj=...) at ../../../../gcc-4.6.3/libphobos/libdruntime/gcc/deh.d:153
#32472 0x0045c088 in onInvalidMemoryOperationError () at ../../../../gcc-4.6.3/libphobos/libdruntime/core/exception.d:517
#32473 0x00470ff9 in gc.gcx.GC.freeNoSync (p=0x1131c00, this=...) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gcx.d:932
#32474 gc.gcx.GC.free (this=..., p=0x1131c00) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gcx.d:912
#32475 0x00462009 in gc.gc.gc_free (p=0x1131c00) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gc.d:248
#32476 gc.gc.gc_free (p=0x1131c00) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gc.d:245
#32477 0x004289cf in _d_delclass (p=0x10f6d0c) at ../../../../gcc-4.6.3/libphobos/libdruntime/rt/lifetime.d:198
#32478 0x00410922 in OBJ3D.OBJ3D.__dtor() (this=...) at OBJ3D.d:76
#32479 0x00428a81 in rt_finalize_gc (p=0x10f6d00) at ../../../../gcc-4.6.3/libphobos/libdruntime/rt/lifetime.d:1198
#32480 0x00475ecc in gc.gcx.Gcx.fullcollect() (this=..., stackTop=0x22e80c) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gcx.d:2963
#32481 0x0047642b in gc.gcx.Gcx.fullcollectshell (this=...) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gcx.d:2649
#32482 gc.gcx.GC.fullCollect() (this=...) at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gcx.d:1346
#32483 0x00461cc5 in gc.gc.gc_collect () at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gc.d:156
#32484 gc.gc.gc_collect () at ../../../../gcc-4.6.3/libphobos/libdruntime/gc/gc.d:152
#32485 0x00406961 in GameFrame.GameFrame.init() (this=..., pb=...) at GameFrame.d:72

まず、スタック#32482でfullcollect()を実行します。ここで変数running=1となります。続いて、 スタック#32479で rt_finalize_gc()が実行されてます。更にこの続きとしてスタック#32474で free()を実行しようとするのですが、スタック#32473のgc.gcx.GC.freeNoSync() でrunningが1の場合は onInvalidMemoryOperationError() を呼んでしまいます。 ここで例外が飛ぶのですが、例外の為のメモリ割り当てである スタック#32467でもrunningが1の場合だったらonInvalidMemoryOperationError() を呼ぶ コードになっていて、この時点で例外呼び出しの無限ループに陥ります。 そもそもfullcollect()する前に、どのスレッドでもGCが走っていないことを保証した 上でスレッドを停止しておけば、こんな妙なフラグを用意する必要は無いように思う のですが、そうなっていないのかしら?てか、runningフラグの操作をやめれば動いている 時点で大丈夫なんじゃないか?という気も。

2012/05/19

昼過ぎ起床。寝すぎ。

gdc追いかけ。結局、「--disable-sjlj-exceptions」とか 「--disable-sjlj-exceptions --with-dwarf2」とか試してみたのですが OKにはならずという感じ。NGではあるものの、動きはちょっとずつ違って いるのがタチが悪いという感じ。

Daniel Green氏(==venix1氏)のfork版のgdcがアップデートされているっぽい のを知り、そちらのビルドを試してみたり。 ベースgccは4.6.x向けなのですが、エラー無くビルドする事ができたり。 で、make installしてみるのですが、mingwex関連の関数と、TLS関連の関数が 見つからずリンクに失敗。mingwexの方はモジュール自体を外す事で対応 できそうだったのですが、TLS関連の関数(__emutls_v._tls_start, __emutls_v._tls_end) はgccの方に関係しそうだったので、どうしたもんか困ったり。

TLS関連の修正が色々行われているのですが、binutilsやmingw本体の方にも パッチを当てる必要がありました。今回はおおよそ次のような流れで対応。


これでビルドしたgdcでひとまず手持ちソースをコンパイルできました。

手持ちソースで対応の必要だったのは以下のような点。

2012/05/18

早めに帰着。

あまりの眠さに急速停止。

2012/05/17

早くも無く遅くも無く。

gdcの追いかけ。先日の再ビルド後、使ってみるのですがやっぱりNG。

2012/05/16

早めに帰着。

gdcの追いかけ。MinGWとLinuxとでコンパイル後の命令列って違うんだっけ? と思い、コンパイルオプションを揃えてlibphobosをコンパイルし、 MinGWでSegfaultとなるコードについてobjdumpの逆アセンブル結果を 見比べてみたり。関数呼び出し部分は少し違いがあるものの、基本的には 同じコードになっているような気が。

Segfaultとなるコードの中に、途中でポインタ値がいつの間にか変わって しまっているという動きになっているものがあったので、命令単位実行を してMinGWとlinuxとでレジスタ値とかを見比べてみたり。すると何やら 命令列の様子が違っているところがあったり。

なんとなくこれかも。configureオプションに --enable-sjlj-exceptions を 入れてビルドしていたのですが、どうもこれに関係するlibgccのコードを呼び出した 後に保持していた値が壊れてしまっているような感じだったり。

そんな訳で--enable-sjlj-exceptionsを外して再ビルドしてみる訳ですが 終わらず。

2012/05/15

遅めに帰着。

gdcを少し追いかけ。libdruntime/gc/gcx.d を -freleaseを付けずに コンパイルするとgcx.d内でSegfaultするという現象に遭遇。 -freleaseを付けるとエラーしない。また、-O0、-O1、-O2で動きが 変わったり。なんだこりゃ?

2012/05/14

気持ち早めに帰着。

gdcを少し追いかけてみることにしてみたり。でも原因究明に至らず。

2012/05/13

昼ごろ起床。

先日のgdc(95407e97ee)のMinGWビルド。libphobosで使用するzlibをgccのアーカイブに 含まれているソースを使うように変更されたようなのですが、 zlib/gzio.cに含まれる関数がバラされたファイルになっているものと してコンパイルするようになっててエラー。 他にもlibphobos内でコンパイルエラーになるソースがいくつかありましたが make二度打ちで先に進んでなんとなくビルド完了。

で、使ってみる訳ですがやっぱりダメ。てか、修正されるような変更が 行われた訳でも無いので、状況変わらずという事ですが。

$ cat hello.d
import std.stdio;
import std.stream;
import std.string;

int main()
{
  writef("Hello D world\n") ;
  return(0) ;
}

$ gdc -O2 hello.d -o hello

$ gdb hello.exe
GNU gdb (GDB) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from C:\cygwin\home\tane\develop\dlang\test/hello.exe...done.
(gdb) run
Starting program: C:\cygwin\home\tane\develop\dlang\test/hello.exe
[New Thread 1020.0x1454]

Program received signal SIGSEGV, Segmentation fault.
object.ModuleInfo.unitTest (this=) at ../../../../gcc-4.7.0/libphobos/libdruntime/object_.d:1664
1664            if (isNew)
(gdb) Cannot access memory at address 0x23

(gdb) where
#0  object.ModuleInfo.unitTest (this=) at ../../../../gcc-4.7.0/libphobos/libdruntime/object_.d:1664
#1  0x00418e6d in core.runtime.runModuleUnitTests.__foreachbody7 (this=0x7c95741c, __applyArg0=0x23) at ../../../../gcc-4.7.0/libphobos/libdruntime/core/runtime.d:483
#2  0x0040aee0 in object.ModuleInfo.opApply (dg=...) at ../../../../gcc-4.7.0/libphobos/libdruntime/object_.d:1799
#3  0x00418f48 in core.runtime.runModuleUnitTests () at ../../../../gcc-4.7.0/libphobos/libdruntime/core/runtime.d:481
#4  0x00401ce8 in rt.dmain2.main.runAll (this=0x51d) at ../../../../gcc-4.7.0/libphobos/libdruntime/rt/dmain2.d:583
#5  0x00401c44 in rt.dmain2.main.tryExec (this=0x22ff2c, dg=...) at ../../../../gcc-4.7.0/libphobos/libdruntime/rt/dmain2.d:543
#6  0x004023c5 in rt.dmain2.main (argc=1, argv=0x3e2c68) at ../../../../gcc-4.7.0/libphobos/libdruntime/rt/dmain2.d:594
(gdb) Cannot access memory at address 0x23

それにしても、zlibの方は、まっさらからビルドすればダメだって気づきそうな もんですが、そういう確認をせずにコミットしているのだろうか?

Fedora16でもgdcのビルドを試してみたり。zlibのエラーがダメな件以外は特に 問題無くビルドできたり。make installしてHelloWorld的なソースをコンパイル &実行してみたのですが、こちらは特に問題無さげ。

2012/05/12

AM中に起床。

GNU Compiler Collection dev history 1989-2012」という動画。 GCCの変更具合をビジュアライズしたものです。30分超という動画 ですが、毎日変更が加えられて巨大化していく様が面白いです。

Gourceという ソフトでビジュアライズされているようで、GCC以外にも色々な フリーソフトのリポジトリをビジュアライズした動画が存在 しているようです。

gdcのビルドを試したり。gcc-4.[56].x は対応されていないので gcc-4.7.0を使用。終わらないのでほっぽらかして寝たり。

2012/05/11

気持ち早めに帰着。

ナウシカ。何度も観てますが、それでも最後まで観てしまうなぁ。

2012/05/10

気持ち早めに帰着。

もそもそとコーディング。

2012/05/09

早めに帰着。

もそもそとコーディング。

2012/05/08

早めに帰着。

合ってない具合を可視化してみたらやっぱり思ったのと違う感じに なってたり。なにか考え違いをしている模様。

解決。グローバル座標になっているつもりがローカル座標のままになって いたのに気づいてなかった。

2012/05/07

早めに帰着。

あまりの眠さに急速停止。

2012/05/06

AM中に起床。今日で連休終了。

もそもそとコーディング。んー、なんか合わない。

2012/05/05

起きたら午後もいい時間。

「バクマン(18)」。平丸の出てくる話は安定して面白いなぁ。

もそもそとコーディング。クォータニオンや回転行列とかを扱っていたら、 正規化されているハズのベクトル同士の演算結果が1.0を越える場合があって、 acos()とかに食わせると非数が返ってメチャクチャになります。 C言語の時はあまり気にした事が無かったのですが、D言語ではちょいちょい この現象にぶつかる気がします。なぜなのやら。

2012/05/04

昼過ぎ起床。

録画消化したり調べ事をしたりコーディングしたり。

ちょろり本屋に。「ONE PIECE(66)」。ひとまず魚人島編は完結。 でも色々な伏線が散りばめられたままになっているかも。 まだまだ続くなぁ。

2012/05/03

昼過ぎ起床。

ぐぅたら過ごして一日終了。

ノイタミナ枠でやっている「つり球」。内容の方はおいといて、背景の絵について。 わたせせいぞうテイストなタッチなのですが、3Dで描かれている感じもあって、 どうやって描いてるんだろうというのが少し気になってます。

2012/05/02

昼過ぎ起床。寝すぎ。

TV観たりコーディングしたりぐうたら過ごしたり。

2012/05/01

早めに帰着。

眠くて死亡。


TOP PREV