昔の最近の出来事(2016.06)

2016/06/30

遅めに帰着。

SwiftShader というCPUベースのOpenGL実装を知ったり。

2016/06/29

遅めに帰着。

NtSetSecurityObject()が遅い件。そもそもファイルがどういう状態になっているんだ? というのを調べたり。 特別なldで生成したファイルを直ぐにchmodすると必ず時間がかかるのですが、 ldで生成したファイルを3分ほどほったらかしにしてからchmodすると 時間がかからないというのを発見したり。 また、ldで生成したてのファイルを、ファイルエクスプローラからファイルの プロパティを開き、セキュリティタブで見ていると、ユーザが何やら 途中で更新される様が見られたり。
理由は良く判りませんが、x86_64-w64-mingw32向けのCygwinクロスldで、 ファイルを書き出した後にchmodで実行権を変更するにあたって、 書き出したファイルが何故かWindowsのファイルシステム上で何かしら 直ぐにchmodできない状態で生成されているという感じに見えます。 それが時間を置けばchmodできるようになるというのは一体どういうこと?

2016/06/28

遅めに帰着。

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

2016/06/27

遅めに帰着。

調べ事をして終了。

2016/06/26

AM中に起床。

掃除したり洗濯したり。

SAI2の2016.06.24版で少しテストしていたら、以下のような不具合に遭遇したのでメモです。


暑いので窓を開けたいのですが、何故か網戸を越えて小っちゃい蜘蛛とかが 入って来るのに困ります。

2016/06/25

昼過ぎ起床。寝過ぎ。

SAI2の2016.06.24版が来ていたのを試したり。未対応のファイルを 食わせた時にそのファイルが掴みっぱなしになる件と、レイヤーリスト内のサムネイル画像 が変になる件は、どちらも修正されていたり。お疲れ様です。

x86_64-w64-mingw32ターゲットのgdcでリンクが遅い件。 chmod()が遅くなるファイルを使って、chmodコマンドのstraceを眺めてみたり。 時間のかかっている箇所をフォーカスすると以下のような感じ。

$ grep -C3 'fhandler_base::close: closing' slow.log nrml.log | cat -n
     1  slow.log-   23   19556 [main] chmod 5288 fhandler_base::open_fs: 1 = fhandler_disk_file::open(\??\C:\cygwin\home\TANE\develop\dlang\opengl_git\3dshoot_opengl\OpenGLtest.exe, 0x10000)
     2  slow.log-   62   19618 [main] chmod 5288 set_posix_access: ACL-Size: 100
     3  slow.log-   29   19647 [main] chmod 5288 set_posix_access: Created SD-Size: 176
     4  slow.log:73218714 73238361 [main] chmod 5288 fhandler_base::close: closing '/home/TANE/develop/dlang/opengl_git/3dshoot_opengl/OpenGLtest.exe' handle 0x304
     5  slow.log-  194 73238555 [main] chmod 5288 chmod: 0 = chmod(/home/TANE/develop/dlang/opengl_git/3dshoot_opengl/OpenGLtest.exe, 0777)
     6  slow.log-  708 73239263 [main] chmod 5288 close: close(1)
     7  slow.log-   99 73239362 [main] chmod 5288 fhandler_base::close_with_arch: not closing archetype
     8  --
     9  nrml.log-   14   17598 [main] chmod 13360 fhandler_base::open_fs: 1 = fhandler_disk_file::open(\??\C:\cygwin\home\TANE\develop\dlang\opengl_git\3dshoot_opengl\OpenGLtest.exe, 0x10000)
    10  nrml.log-   52   17650 [main] chmod 13360 set_posix_access: ACL-Size: 100
    11  nrml.log-   28   17678 [main] chmod 13360 set_posix_access: Created SD-Size: 176
    12  nrml.log:  190   17868 [main] chmod 13360 fhandler_base::close: closing '/home/TANE/develop/dlang/opengl_git/3dshoot_opengl/OpenGLtest.exe' handle 0x320
    13  nrml.log-   59   17927 [main] chmod 13360 chmod: 0 = chmod(/home/TANE/develop/dlang/opengl_git/3dshoot_opengl/OpenGLtest.exe, 0777)
    14  nrml.log-  191   18118 [main] chmod 13360 close: close(1)
    15  nrml.log-   27   18145 [main] chmod 13360 fhandler_base::close_with_arch: not closing archetype

3行目〜4行目でslow.logは異常に時間がかかってますが、それに対応する 11行目〜12行目のnrml.logでは、ほぼ時間はかかっていません。 また、4行目〜6行目の中に含まれるchmod()(cygwin1.dll内の chmod()システムコールのエミュレーション内のデバッグプリント) では時間がかかっていません。 先日調べたところでは、ldの時はchmod()関数で時間がかかる感じに なってましたが、ある特定の操作で遅くなるというよりは、ファイルに 何かが仕込まれていて、その仕込みに触れるような操作をした場合に 遅くなるという事なのかも知れません。

chmodコマンドの代わりに、単純にファイルをopen()してclose()するだけ の実験コードを作成して試してみたり。しかし、それだけだと再現せず。 fchmod()を追加したら再現できたり。straceの結果などからどこで時間 を食っているのか推測すると、 winsup/cygwin/fhandler_disk_file.cc 内の fhandler_disk_file::fchmod()コード内に、WinAPIを使って実際にファイル モードを変更するコードがあり、多分ここら辺だろうと推測したり。

    834   status = NtSetAttributesFile (get_handle (), pc.file_attributes ());
    835   /* MVFS needs a good amount of kicking to be convinced that it has to write
    836      back metadata changes and to invalidate the cached metadata information
    837      stored for the given handle.  This method to open a second handle to
    838      the file and write the same metadata information twice has been found
    839      experimentally: http://cygwin.com/ml/cygwin/2009-07/msg00533.html */
    840   if (pc.fs_is_mvfs () && NT_SUCCESS (status) && !oret)
    841     {
    842       OBJECT_ATTRIBUTES attr;
    843       HANDLE fh;
    844
    845       if (NT_SUCCESS (NtOpenFile (&fh, FILE_WRITE_ATTRIBUTES,
    846                                   pc.init_reopen_attr (attr, get_handle ()),
    847                                   &io, FILE_SHARE_VALID_FLAGS,
    848                                   FILE_OPEN_FOR_BACKUP_INTENT)))
    849         {
    850           NtSetAttributesFile (fh, pc.file_attributes ());
    851           NtClose (fh);
    852         }
    853     }

でも、何故か NtSetAttributesFile() に関する情報がWeb検索しても 全然出てこなくて(うち2件が今回のCygwin内コードのパッチに関するもの 1件目2件目)、 なんだこりゃ?と思ったり。

そんな訳で、前述コード内にデバッグプリントを仕込んでcygwin1.dllをビルドしてみたのですが、 何故か仕込んだメッセージが表示されず。あれ?ハズしたのか? そういやCygwinのコードをあれこれ弄るのは久しぶりなのですが、 Cygwinネイティブのemacs-w32やscreenをガッツリ使うようになったもんですから、 いちいち全部落とさなくてはならないのが面倒臭いです(^^;

ハズしてました。

正しくは少し手前で set_file_sd()という関数を実行してて、その中で時間がかかって るようでした。この関数の中で NtSetSecurityObject()というWinAPIを実行していて、 これが一度失敗。リトライ機構が入ってて、リトライの為にNtOpenFile()を実行した後にもう一度 NtSetSecurityObject()を実行した所で時間がかかっているという感じでした。
ところが、一度chmod()を実行した時間のかからない状態で再度テストしてみたところ、 時間はかからないのですが、リトライは実行されてました。つまり、リトライが時間の かかっている要因ではないという事です。見た目の動きは同じにもかかわらず、何故か NtSetSecurityObject()で時間がかかる場合とそうでない場合があるようです。

----- デバッグプリント(syscall_printf()を使ってますが)を仕込んだset_file_sd()
LONG
set_file_sd (HANDLE fh, path_conv &pc, security_descriptor &sd, bool is_chown)
{
  NTSTATUS status = STATUS_SUCCESS;
  int retry = 0;
  int res = -1;

  for (; retry < 2; ++retry)
    {
      if (fh)
        {
syscall_printf ("start set_file_sd %d   NtSetSecurityObject()",retry) ;
          status = NtSetSecurityObject (fh,
                                        is_chown ? ALL_SECURITY_INFORMATION
                                                 : DACL_SECURITY_INFORMATION,
                                        sd);
syscall_printf ("end   set_file_sd %d   NtSetSecurityObject()=>%llx",retry,status) ;
          if (NT_SUCCESS (status))
            {
              res = 0;
              break;
            }
        }
syscall_printf ("start set_file_sd %d  retry",retry) ;
      if (!retry)
        {
          OBJECT_ATTRIBUTES attr;
          IO_STATUS_BLOCK io;
          status = NtOpenFile (&fh, (is_chown ? WRITE_OWNER  : 0) | WRITE_DAC,
                               fh ? pc.init_reopen_attr (attr, fh)
                                  : pc.get_object_attr (attr, sec_none_nih),
                               &io,
                               FILE_SHARE_VALID_FLAGS,
                               FILE_OPEN_FOR_BACKUP_INTENT);
          if (!NT_SUCCESS (status))
            {
              fh = NULL;
              break;
            }
        }
syscall_printf ("end   set_file_sd %d  retry",retry) ;
    }
  if (retry && fh)
    NtClose (fh);
  if (!NT_SUCCESS (status))
    __seterrno_from_nt_status (status);
  return res;
}

----- 時間のかかる場合
   18   20655 [main] a 2608 fhandler_disk_file::fchmod: start pc.has_acls  step6-1
   21   20676 [main] a 2608 set_file_sd: start set_file_sd 0   NtSetSecurityObject()
   25   20701 [main] a 2608 set_file_sd: end   set_file_sd 0   NtSetSecurityObject()=>C0000022
   20   20721 [main] a 2608 set_file_sd: start set_file_sd 0  retry
  154   20875 [main] a 2608 set_file_sd: end   set_file_sd 0  retry
   23   20898 [main] a 2608 set_file_sd: start set_file_sd 1   NtSetSecurityObject()
75958460 75979358 [main] a 2608 set_file_sd: end   set_file_sd 1   NtSetSecurityObject()=>0
  289 75979647 [main] a 2608 fhandler_disk_file::fchmod: start pc.has_acls  step6-2

----- 時間のかからない場合
   17   19816 [main] a 9116 fhandler_disk_file::fchmod: start pc.has_acls  step6-1
   17   19833 [main] a 9116 set_file_sd: start set_file_sd 0   NtSetSecurityObject()
   22   19855 [main] a 9116 set_file_sd: end   set_file_sd 0   NtSetSecurityObject()=>C0000022
   17   19872 [main] a 9116 set_file_sd: start set_file_sd 0  retry
  162   20034 [main] a 9116 set_file_sd: end   set_file_sd 0  retry
   25   20059 [main] a 9116 set_file_sd: start set_file_sd 1   NtSetSecurityObject()
  122   20181 [main] a 9116 set_file_sd: end   set_file_sd 1   NtSetSecurityObject()=>0
   55   20236 [main] a 9116 fhandler_disk_file::fchmod: start pc.has_acls  step6-2

失敗した時のNtSetSecurityObject()の戻り値はC0000022(STATUS_ACCESS_DENIED)のようですが、 なんのこっちゃ良く判らず。そもそも何故失敗するのか?というのも良く判らず。 Webで検索するも、NtSetSecurityObject()の情報があまり無くてお手上げ。

そういやhtmlを手書きしていると&とか<とか>は&amp;とか&lt;とか&gt;とかに書き換えなくてはならない場合が ありますが、ソースコードを引用した時に毎回置換するのが面倒臭くなったので、 ちょっこりELISPを書いてみたり(既に世の中にはもっと良いのが存在しているかも知れませんが)。

(defun my-replace-html-special-char (&optional arg)
  "Replace html &,>,<,\" char to &amp;,&gt;,&lt;,&quot;."
  (interactive "P")
  (let ((strbuf (substring-no-properties (car kill-ring-yank-pointer)))
        (begpos (region-beginning))
        (endpos (region-end)))
    (setq strbuf (replace-regexp-in-string "&"  "&amp;"  strbuf))
    (setq strbuf (replace-regexp-in-string ">"  "&gt;"   strbuf))
    (setq strbuf (replace-regexp-in-string "<"  "&lt;"   strbuf))
    (setq strbuf (replace-regexp-in-string "\"" "&quot;" strbuf))
    (delete-region begpos endpos)
    (goto-char begpos)
    (insert strbuf)
    ))

ちょっとだけ楽になった気も。

2016/06/24

早めに帰着。

x86_64-w64-mingw32ターゲットのgdcでリンクが遅い件。 リンカ(ld)をgdbで調べてみたり。すると、なんだか妙な 動きをしている気がしたりも。
時間がかかっているのは、最後に開いたファイルを閉じる中で 以下のようなコード。

(gdb) where
#0  _maybe_make_executable (abfd=0x2004e248) at ../../binutils-2.23.1/bfd/opncls.c:660
#1  bfd_close (abfd=0x2004e248) at ../../binutils-2.23.1/bfd/opncls.c:732
#2  0x004cb9d2 in main (argc=109, argv=0x181c19c) at ../../binutils-2.23.1/ld/ldmain.c:445
(gdb) l
655     static inline void
656     _maybe_make_executable (bfd * abfd)
657     {
658       /* If the file was open for writing and is now executable,
659          make it so.  */
660       if (abfd->direction == write_direction
661           && (abfd->flags & (EXEC_P | DYNAMIC)) != 0)
662         {
663           struct stat buf;
664
(gdb) l
665           if (stat (abfd->filename, &buf) == 0
666               /* Do not attempt to change non-regular files.  This is
667                  here especially for configure scripts and kernel builds
668                  which run tests with "ld [...] -o /dev/null".  */
669               && S_ISREG(buf.st_mode))
670             {
671               unsigned int mask = umask (0);
672
673               umask (mask);
674               chmod (abfd->filename,
(gdb) l
675                      (0777
676                       & (buf.st_mode | ((S_IXUSR | S_IXGRP | S_IXOTH) &~ mask))));
677             }
678         }
679     }
680

一見、特にハマリ所は無いように見えるのですが、 chmod()にやたら時間がかかっているのが判ったり。 試しにchmod()を削ってみたところ、ldに時間がかかるのは解消したのですが、 生成されたファイルをchmodコマンドでパーミッションを777にしてみたところ、 コマンドラインのchmodに時間がかかったり。そして再度chmodコマンドで パーミッションを別の値に変えてみたのですが、時間がかかる事無く実行できていたり。 うーん?

$ time chmod 777 OpenGLtest.exe

real    1m20.926s
user    0m0.000s
sys     0m0.015s

$ time chmod 666 OpenGLtest.exe

real    0m0.044s
user    0m0.015s
sys     0m0.015s

なんかldで生成されたファイルが何かおかしな感じになっていて、それが chmodを実行した時に発現するという感じに見えます。訳判らんですが、 cygwinのバグじゃね?って感じがしてきました。
でも、i686-pc-mingw32だと大丈夫なのですが、x86_64-w64-mingw32と同様にCygwin32の クロスコンパイラです。ファイル操作はCygwin32のシステムコールを 経由して行われるハズなので、差が出てくるとは考えにくいのですが....?

2016/06/23

遅めに帰着。

Cygwinの2.5.2がリリースされてますが、WindowsXPがサポート される最後のバージョンとなるっぽい。

2016/06/22

遅めに帰着。

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

2016/06/21

遅めに帰着。

x86_64-w64-mingw32ターゲットのgdcでリンクが遅い件。 ウイルスチェッカーを落とした状態だと、普通の速度でリンクが 終わる場合とそうでない場合があったり。straceでファイルの 読み込みに時間がかかっている箇所があるのは当たりが付いている ものの、システムコールレベルで実行されている事しか判らない ので、実際に何の為にファイルを読み込んでいるのかまでは判って なかったり。

_FWRITEフラグでオープンしたファイルにread()を実行して るような気がしたりも?違うか、O_RDWRしてるから大丈夫かも。

2016/06/20

早めに帰着。

SAI2の2016-06-20版が出ていたり。SAI(Ver1系)フォーマットの読み込みが できるようになってました。他は特に変わりなし。

x86_64-w64-mingw32ターゲットのgdcでリンクが遅い件を少し調べたり。 以前ウイルスチェッカーが原因に あると結論付けたのですが、ウイルスチェッカーを落としておいても 時間がかかる事がある為、本当の所は一体何なのかを調べておこうと 思った次第。
どうもCygwinパッケージインストールした /usr/bin/x86_64-w64-mingw32-ld.exeの 問題じゃないか?という気がしてきたりも。

2016/06/19

AM中に起床。

掃除したり洗濯したり。

SAI2の2016-06-19版が来ていたり。お疲れ様です。
読み込み可能なファイルが増えた様なのでその辺を少し試してみたり。 以下のような不具合があるようだったのでメモです。


SAI1でできていた事はほぼできるようになっている気が。各機能のレベルは SAI1よりも良くなっていると思いますので、SAI1で作業できていた人はSAI2に 乗り換えても問題無い感じじゃないかと思ったりも。

2016/06/18

AM中に起床。

既に終わってますがE3。PS4はVR推しでしたが、HMDは、Wiiリモコン、3Dテレビ、 Kinectなどの仲間で、個人的には色物デバイスの一つという感じです。 これらのデバイスに共通して言えるのは「姿勢を正さないとゲームにならない」 の一点に尽きる訳ですが、スマホゲームのように指を動かす 程度で操作できないのは、今の時代には 入り込む事自体が 難しいだろうと思います。人間が退化し過ぎなのかも知れません(^^;
とはいえ、据え置きゲーム機向けに色々作られているのは 個人的には嬉しいところです。また、何故かPS4向けに2016年度は色々 出る事になっているようで、去年 開発継続されてたのが報じられた「人喰いの大鷲トリコ」が今年出る様ですし、 GT SPORTも2016年秋だしで、PS3時代に感じていたローンチトレーラー発表 から製品が出るまでのラグが長すぎってのが、少し緩和されているように 思ったりも。
4K対応はこの先どうなるのかは良く判らず。 PS4が日本で発売された2014年2月以前だと、4Kディスプレイ自体が 60fps出るものが無かったり、HDMI2.0とかDisplayPortじゃないとダメだったり、 GPU自体の性能も足りなかったり、そもそも4Kテレビ向けに4K放送されてないし、 Ultra HD Blu-rayの規格も無かったしで、しばらくゲーム機には来ないだろう と思っていたのですが、 Xbox One Sとか PS4.5とか 次世代機前の対応は視野に入れてる ように思ったりも。「その為に買うか?」というのが難しい所 のように思います。

アンチャ3。どうにかプロモードでクリア。厳しい戦いでした。

2016/06/17

遅めに帰着。

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

2016/06/16

遅めに帰着。

Web巡回して終了。

調べ事をしていて 「食事する哲学者の問題」 というのを知ったり。

2016/06/15

遅めに帰着。

Web巡回して終了。

2016/06/14

遅めに帰着。

ドラマの「重版出来」最終回を録画で遅れて観たり。 土曜の1話再放送で知ったのですが、全編通して面白かったです。

MinGW-gdc。i686-w64-mingw32とx86_64-w64-mingw32をビルド&インストール して、手持ちコードをいくつかビルドしてみたり。どちらのターゲットも 大丈夫そう。いきなり死んだりはしない感じ。

2016/06/13

遅めに帰着。

MinGW-gdcのビルド。途中であまりの眠さに休息停止。

2016/06/12

起きたら午後も良い時間。寝過ぎ。

アンチャ3。トラウマチャプターその2をどうにか通過。でも、もう一度 やるのはノーサンキュー。そんな感じ。

洗濯したり掃除したり。

MinGW-gdc 2.068をi686-pc-mingw32以外でビルドしてみたり。 所がx86_64-w64-mingw32のlibphobosのビルドでエラー。 core.stdc.stdioでversionに予約文字列を指定している というもの。確かに、MinGW対応という事で以下のようなversion定義を 追加しました。

version( MinGW ){
  version( Win32 ){
    version=CRuntime_DigitalMars ;
  }
  version( Win64 ){
    version=CRuntime_Microsoft ;
  }
}

そもそもMinGWという時点でDisitalMarsでもMicrosoftでもないのですが、 2.067以前はWin32とWin64を使って切り替えていたものを、2.068では Win32はCRuntime_DigitalMarsに、Win64はCRuntime_Microsoftに置き換える という変更が加えられていました。これにMinGWの32と64を加えるとなると 論理演算の使えないversion文では死ぬほど面倒臭い(AとBの論理ORが取れないので A用とB用とで同じ内容だとしても、それぞれ同じものを書かなくてはならない) ので、変更量最小になる様に 不本意ながら前述のような切替えを加えて みたという訳です。所が、CRuntime_DigitalMarsもCRuntime_Microsoftも 予約文字列のハズですが、何故かi686-pc-mingw32とi686-w64-mingw32では version=CRuntime_DigitalMars;はエラーにならず、x86_64-w64-mingw32では version=CRuntime_Microsoft;がエラーになるという謎の挙動を示していたり。 既にversion=CRuntime_Microsoft;が定義されているのか?と思い、 Win64時の定義を消してみたら別にCRuntime_Microsoftが設定されている訳 ではなく。結果的に自分では使ってはいないけど予約文字列だから使うなと、 ただ邪魔をしているだけという。仕方ないので、gcc/d/cond.c内に含まれる version予約文字列からCRuntime_Microsoftを削除してみたり。 それで一応ビルドは通ったり。テストは明日という事で。

なんかversion文字列の扱いが、これってライブラリで定義するんじゃないの? みたいなのがコンパイラで予約定義されていたり、その逆だったり、なんか ポリシーが一貫していないような気がしたりも。あと、 コンパイラが有効としているversion文字列の一覧を取得する方法も無いので、 有効か否かを検査コードを書いて いちいち試してみなくてはならないのが 面倒臭いです。

2016/06/11

昼過ぎ起床。

アンチャ3。ダメだ。道が開けない。

gdc 2.068がgcc-6.1.0向けにマージされたようなので、MinGWターゲットの ビルドを試してみたり。libphobosのMinGW向けコードが なかなかな勢いで壊れている感じだったり。
ひとまずi686-pc-mingw32ターゲットでのビルドは通ったのでインストール &実行。

$ cat iam.d
import std.stdio;
import std.string ;
import std.compiler;

int main()
{
  writef("%s %s %s.%03d (D%s)\n",name,vendor,version_major,version_minor,D_major) ;
  version( GNU     ) writef("I am GNU\n"    ) ;
  version( Unix    ) writef("I am Unix\n"   ) ;
  version( linux   ) writef("I am linux\n"  ) ;
  version( Windows ) writef("I am Windows\n") ;
  version( MinGW   ) writef("I am MinGW\n"  ) ;
  version( MinGW32 ) writef("I am MinGW32\n") ;
  version( MinGW64 ) writef("I am MinGW64\n") ;
  version( cygwin  ) writef("I am cygwin\n" ) ;
  version( Win32   ) writef("I am Win32\n"  ) ;
  version( Win64   ) writef("I am Win64\n"  ) ;
  version( Posix   ) writef("I am Posix\n"  ) ;
  version( X86     ) writef("I am X86\n"    ) ;
  version( X86_64  ) writef("I am X86_64\n" ) ;
  version( ARM_SoftFloat ) writef("I am ARM_SoftFloat\n" ) ;
  version( ARM     ) writef("I am ARM\n"    ) ;
  version( PPC     ) writef("I am PPC\n"    ) ;
  version( PPC64   ) writef("I am PPC64\n"  ) ;
  version( PPC_SoftFloat ) writef("I am PPC_SoftFloat\n" ) ;
  version( PPC_HardFloat ) writef("I am PPC_HardFloat\n" ) ;

  return(0) ;
}

$ i686-pc-mingw32-gdc -O2 iam.d

$ ./a.exe
GNU D gnu 2.068 (D2)
I am GNU
I am Windows
I am MinGW
I am Win32
I am X86

ひとまずHelloWorldレベルのコードはイケた模様。stdio関連が激しく 壊れている感じだったのでイケるかどうか心配でしたが、ひとまずデバッグ はできそうなレベルにある模様。

手持ちのWinアプリコードをコンパイルしてみたり。object.clear()関数が無くなって いる模様。そういえば、以前 DMD2.070.0ではobject.clear()関数が無くなっている事に気づいてましたが、 gdcの2.068では無くなっている模様。clear()の代わりってあるんだっけ?

こちらの説明 によると、clear()の代わりはdestroy()の模様。gdc 2.065から 使えるようになってたっぽいので、ひとまずコードを書き換える方向で。

新しいgdc-2.067での「MinGW-gdcリンク問題」は解決していませんので、 「-lgphobos2 -lgdruntime -lws2_32」を追加する必要があるままになってますが、 ひとまずWinアプリコードのコンパイルに成功。いきなり死んだりはしない模様。

以下のようなコードのコンパイルでエラーするようになったり。

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

void main(string args[]){

  int    argc = cast(int)(args.length);
  char** argv = cast(char**)(new char*[argc]) ;

  for( int i=0 ; i<argc ; i++ ){
    argv[i] = (args[i].dup).ptr ;
  }
  return ;
}

$ i686-pc-mingw32-gdc gdc2068_cant_string_dup.d
gdc2068_cant_string_dup.d:10:15: error: no property 'dup' for type 'string'
     argv[i] = (args[i].dup).ptr ;
               ^

どうやらstringをdupできなくなった模様。どうすんだ?と思ったのですが、 std.utfの toUTFzテンプレートを使って、

    argv[i] = toUTFz!(char*)(args[i]) ;

てな感じにするのが良いっぽい。

そういやobject.clear()の以外にも何かあるかな?と思って、 Deprecated Featuresを 見ていたところ、将来deleteが無くなる予定になっている模様。 てか、destroy()が代用だと書いてあるけど、これ、大丈夫か? clear()はdelete()の代わりにならなかったのですが、その理由に clear()は即効性が無いというのがあります。また、clear()はクラスにしか 使えないので、巨大な動的配列をメモリの穴が開く前に開放したい場合 にはdelete()しか使えませんでした。代わりの方法はあるのだろうか?

2016/06/10

遅めに帰着。

アンチャ3。プロモードの戦闘は死にまくりで全然先に進めず。

2016/06/09

遅めに帰着。

Web巡回して終了。

2016/06/08

遅めに帰着。

gdcの 2.068がいきなりmasterにマージされててビビった。 6.1向けのブランチにマージされたらMinGWターゲットのビルドを 試してみる事にしよう。

2016/06/07

遅めに帰着。

gdc 2.068の新しいのが来てたのでFedoraの方でビルドしてみたり。 前回の様にビルド途中でICEズッコケ する事無くビルド成功。HelloWorldレベルの簡単なコードの コンパイルは特に問題無し。
ただし、wstring文字列リテラルの終端問題はそのまま移植 されている(つまり直ってはいない)模様。でも、アセンブラ コードの雰囲気がちょっと違っているような気が。

$ cat str_literal.d
import std.stdio;
import std.string ;
import std.compiler;

int main()
{
  writef("%s %s %s.%03d (D%s)\n",name,vendor,version_major,version_minor,D_major) ;

  wstring str="test_string" ;
  for( int i=0 ; i<=str.length ; i++ ){
    writef("%c %x\n",str[i],str[i]) ;
  }

  return(0) ;
}

$ gdc -frelease -S str_literal.d

$ gdc -v
Using built-in specs.
COLLECT_GCC=gdc
COLLECT_LTO_WRAPPER=/usr/local/gdc_2068_700/libexec/gcc/x86_64-pc-linux-gnu/7.0.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-7-20160424/configure --with-pkgversion='gdc-7 da83994fc6(DMD2.068)' --enable-languages=c,c++,d --prefix=/usr/local/gdc_2068_700 --disable-bootstrap --disable-nls --with-bugurl=http://bugzilla.gdcproject.org --enable-checking=yes --disable-libgomp --disable-libmudflap
Thread model: posix
gcc version 7.0.0 20160424 (experimental) (gdc-7 da83994fc6(DMD2.068))

$ grep -A18 '^\.LC0' str_literal.s
.LC0:
        .string "%s %s %s.%03d (D%s)\n"
        .align 2
.LC1:
        .string "t"
        .string "e"
        .string "s"
        .string "t"
        .string "_"
        .string "s"
        .string "t"
        .string "r"
        .string "i"
        .string "n"
        .string "g"
        .string ""
.LC2:
        .string "%c %x\n"
        .text

.stringディレクティブが使われていますが、「.string "t"」は 「.ascii "t\0"」と等価らしい。つまり、.stringを使えば自動的に char型のヌル文字で終端されるという事らしい。てか、データ列的に同じだからと言って、 wstringをわざわざ妙な変換で表現するのは訳が分からなくなると思いました。 さておき、終端は「.string ""」なので「.ascii "\0"」 と同じという事で、wchar型のヌル文字終端にはやっぱりなっていないという 感じ。

2016/06/06

遅めに帰着。

Web巡回して終了。

2016/06/05

AM中に起床。

掃除したり洗濯したりぐうたら過ごしたり。

Wings3Dの開発版リリース2.0.4 ってのが先月出ていたのに気づいたり。64bit版で1500万ポリゴンの AsianDragon(WavefrontOBJファイル)をインポートしてみるのですが、 メモリを爆食いしているうちにWindows自体がハング状態に陥ったり。 やっぱダメか。それにしても、メモリが足りないと言われないもの なのだろうか?と疑問には思ったりも。

コンビニのレジのそばに、こち亀の199巻が置いてあったり。 連載40年になるのか。 日本の長期連載漫画ランキングという ページ を知ったのですが、2014年5月時点で こち亀より連載期間の長いマンガが 結構あるのだなぁと思ったりも。

アンチャ3。トラウマチャプターの一つ12。どうにかクリアした後に宝物を取り損ねて いる事に気づき、もう一回やり直すハメにトホホ。

2016/06/04

AM中に起床。

そういや、gdbではブレークポイントやステップ実行で止まった時に 値を自動表示するdisplayコマンドというのがあります。ただ、このコマンド ではある値の表示に限定されていて、例えば$pcが指す命令の 逆アセンブル表示と、とあるメモリ領域のダンプの両方を表示する事ができません。
もう一つ、defineコマンドを使うと、いくつかの手続きを並べて一つのコマンド として定義できます。

$ cat -n gdb_cmd.txt
     1  define printregs
     2    x/i $pc
     3    printf "%08x %08x %08x\n", $eax, $ecx, $ebx
     4    where
     5    x/16x $pc
     6  end
     7
     8  b _Dmain
     9  run
    10  printregs
    11
    12  #quit

$ gdb ./a.exe -q -x gdb_cmd.txt
Reading symbols from ./a.exe...done.
Breakpoint 1 at 0x401352: file str_literal.d, line 7.
[New Thread 7920.0x2188]
[New Thread 7920.0x46ec]
[New Thread 7920.0x4274]

Breakpoint 1, D main () at str_literal.d:7
7         writef("%s %s %s.%03d (D%s)\n",name,vendor,version_major,version_minor,D_major) ;
=> 0x401352 <_Dmain+8>: movl   $0x14,-0x20(%ebp)
0040134a 00280000 00bafec8
#0  D main () at str_literal.d:7
0x401352 <_Dmain+8>:    0x14e045c7      0xc7000000      0x7024e445      0x44c7004f
0x401362 <_Dmain+24>:   0x00021c24      0x44c70000      0x00431824      0x44c70000
0x401372 <_Dmain+40>:   0x00021424      0x44c70000      0x00021024      0x54a10000
0x401382 <_Dmain+56>:   0x8b0049d0      0x49d05815      0x24448900      0x24548908
(gdb)

でも、displayコマンドにはユーザ定義コマンドを指定する事はできません (displayというコマンド名による所はあるのかも知れませんが)。

ブレークポイントを踏んだ時に、定義したコマンド列を実行する事は commands コマンドを使う事で実現可能です。でも、ステップ実行時に 毎回ユーザ定義コマンドを実行する方法は見当たりませんでした。 できそうでできない事の一つなのかしら?

もう少し調べてみたら、「ユーザ定義コマンド・フック」という方法 がある事が判りました。「 特別な種類のユーザ定義コマンドである、 フックを定義することができます。 `hook-foo'というユーザ定義コマンドが存在すると、 `foo'というコマンドを実行するときにはいつも、 `foo'コマンドが実行される前に (引数のない) `hook-foo'が実行されます。 」という事のよう。また、仮想コマンドにstopというのがあって、ブレーク ポイントやステップ実行で止まる度に実行されるコマンドで、これを 使えば、止まる度にユーザ定義コマンドを実行するという事が可能になる ようです。

$ cat -n gdb_cmd.txt
     1  define printregs
     2    x/i $pc
     3    printf "%08x %08x %08x\n", $eax, $ecx, $ebx
     4  #  where
     5    x/16x $pc
     6  end
     7
     8  define hook-stop
     9    printregs
    10  end
    11
    12  b _Dmain
    13
    14  run
    15
    16  #quit

$ gdb ./a.exe -q -x gdb_cmd.txt
Reading symbols from ./a.exe...done.
Breakpoint 1 at 0x401352: file str_literal.d, line 7.
[New Thread 5432.0x273c]
[New Thread 5432.0x3110]
[New Thread 5432.0x3f1c]
=> 0x401352 <_Dmain+8>: movl   $0x14,-0x20(%ebp)
0040134a 002d9000 00bafec8
0x401352 <_Dmain+8>:    0x14e045c7      0xc7000000      0x7024e445      0x44c7004f
0x401362 <_Dmain+24>:   0x00021c24      0x44c70000      0x00431824      0x44c70000
0x401372 <_Dmain+40>:   0x00021424      0x44c70000      0x00021024      0x54a10000
0x401382 <_Dmain+56>:   0x8b0049d0      0x49d05815      0x24448900      0x24548908

Breakpoint 1, D main () at str_literal.d:7
7         writef("%s %s %s.%03d (D%s)\n",name,vendor,version_major,version_minor,D_major) ;
(gdb) si
=> 0x401359 <_Dmain+15>:        movl   $0x4f7024,-0x1c(%ebp)
0040134a 002d9000 00bafec8
0x401359 <_Dmain+15>:   0x24e445c7      0xc7004f70      0x021c2444      0xc7000000
0x401369 <_Dmain+31>:   0x43182444      0xc7000000      0x02142444      0xc7000000
0x401379 <_Dmain+47>:   0x02102444      0xa1000000      0x0049d054      0xd058158b
0x401389 <_Dmain+63>:   0x44890049      0x54890824      0x458b0c24      0xe4558be0
0x00401359      7         writef("%s %s %s.%03d (D%s)\n",name,vendor,version_major,version_minor,D_major) ;
(gdb) si
=> 0x401360 <_Dmain+22>:        movl   $0x2,0x1c(%esp)
0040134a 002d9000 00bafec8
0x401360 <_Dmain+22>:   0x1c2444c7      0x00000002      0x182444c7      0x00000043
0x401370 <_Dmain+38>:   0x142444c7      0x00000002      0x102444c7      0x00000002
0x401380 <_Dmain+54>:   0x49d054a1      0x58158b00      0x890049d0      0x89082444
0x401390 <_Dmain+70>:   0x8b0c2454      0x558be045      0x240489e4      0x04245489
0x00401360      7         writef("%s %s %s.%03d (D%s)\n",name,vendor,version_major,version_minor,D_major) ;
(gdb)

やっぱできるよね。流石です。そんな感じでした。

セガのハードに込められた熱意が語られた GAME ONトークイベント“セガハードの歴史を語り尽くす”詳細リポート 」という記事。誤記が多くて脳内補正が必要な点をさておき、 一連のハード開発エピソードは非常に興味深いです。 90年代に入ってリアルタイム3Dに入った辺りでも、独自ハードで やってた訳ですから、かなりな とんでも技術力だと思います。 丁度、ナムコも同じ時期に同じようなハードスペックのアーケード ハードを出していたので、そちらの話も聞いてみたいと思いました。

ドラマの「お迎えデス。」。ん?なんか順序関係が矛盾してないか? この関係だと、兄の堤円よりも 異母兄妹になる 妹さやか の方が年上に なってしまう気がしたりも。あぁ、兄の円と父親に血縁関係が無いと いうこと....なのか?それよりも少女マンガ原作(原作タイトルは 「お迎えです。」)だというのを今日初めて知りました(^^;

2016/06/03

遅めに帰着。

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

2016/06/02

遅めに帰着。

gdcのwstring文字列リテラル終端問題。 GIMPLEを見てみたのですが、データ自体はGIMPLEには全て出てこなくて、 ポインタが文字列領域を指している事が判る最低限の表現に留まって いるみたい。この為、リテラル終端をどのように処理しているのか までは判りませんでした。
4/30〜5/17までの間に入った変更でエンバグしているのは確かなのですが、 3週間弱の間に結構な量の変更が入っている為、これって箇所の見当が イマイチ付きません。

2016/06/01

遅めに帰着。

gdcの文字列リテラル終端の件。-Sオプションを使ってアセンブラ コードがどうなっているか調べてみたところ、ちゃんとヌル文字終端 されているようだったり。でも、gdbでメモリをダンプしてみると やっぱりヌル文字終端になっていないようだったり。

よく見てみると違いがありました。

        OK-gdc                                                          NG-gdc
        .ascii "t\0e\0s\0t\0_\0s\0t\0r\0i\0n\0g\0\0\0"        |         .ascii "t\0e\0s\0t\0_\0s\0t\0r\0i\0n\0g\0\0"

wstring型なので文字の間に\0が入ってて判りにくいですが、 OKの方は「wchar型のヌル文字が終端」になってるのが、NGの方は 「char型のヌル文字が終端」になっています。この為、 NGの方では wcharのヌル文字終端に見えない(隣接するデータの値が0 だったらヌル文字に見えるかも知れませんが)という事のようです。 如何にもという感じのバグっぽいですが、どう直せば良いかは良く判らず。


TOP PREV