main() blog

プログラムやゲーム、旅、愛する家族について綴っていきます。

【GW】39.5℃の涙

5/3(水)

幕張メッセのフリマに行った。

ブログ書こうかなぁ、あまりネタないし、疲れたから明日にするか…

 

その日の夜中…

2時過ぎにもの凄い寒気で目が醒める。

マズイ…

確実に熱が出てる…

とりあえずママを起こす。

「ママ…ママ…熱出てる…」

途端に吐き気が。

そのままトイレに駆け込み嘔吐。

熱を測ると39℃。

身体が痛い…

先週まで上のお姉ちゃんがインフルエンザだったから移ったか?

それとも今日行ったイベントで風邪でももらったか、変なものでも食べたか?

 

とにかく隣で寝てる下の子に移さないようにママの布団に移動して布団も離して横になる。

ママが水まくらを持って来てくれて、一応バケツも枕元に用意。

胃がムカムカするし、頭がグワングワンするがとりあえず寝るしかない。

 

5/4(木)

7時に起きて熱を測っても39℃。

休日当番医を調べても車で20分のところしかない。

小さい子もいるので自分で行くしかない。

9時くらいに病院に着いたけどすでに沢山の人。

手続きを済ませて、なんとか座れたけどずっと朦朧としたままでどれだけ待ったことか…

呼ばれたのは2時間後…

「とりあえずウィルス性の胃腸炎かな」

「インフルエンザは明日にならないとわからないから、熱が続いたらまた診てもらって」

整腸剤と解熱剤だけ処方。

 

帰ってすぐにくすりを飲んで横に。

とにかく身体が痛い。

寝てるのか起きてるのか分からないまま夜に。

熱を測ると38.5℃。

少しだけおかゆを口にして薬を飲んで横に。

下の子が寂しそうに部屋を覗き込んでいた顔がなんとも言えない。

f:id:takezoh_1127:20170506232512j:image 

 

夜中の2時に目が醒める。

身体が痛い。

熱を測ると39.5℃。

ヤバイ…

とにかく解熱剤飲んで横に。

寝てるのか起きてるのか分からない…

 

5/5(金)

7時に目が覚めて熱を測ると38℃。

もう一度病院に行かねば。

 

 近所だと耳鼻科メインの担当医しかないようだ。

行ってみるとやはり激混み。

1時間半くらいでようやく呼ばれて中に入ると診察台?

「これ反応出てないよねぇ?」

大丈夫か?と思いつつもインフルエンザでは無かったようです。

 

結局また胃腸炎だろうという事で、整腸剤と抗生物質、解熱剤が処方。

 

 帰って一眠りしたところで汗がドバッと。

体温も37℃まで下がりました。

 

5/6(土)

朝、体温を測ると36.7℃。

子供の顔を見に行ったら下の子が起きていて顔見たら「パパ!」と笑顔で言ったけどすぐに布団で顔を隠してた。

 

 

せっかくのゴールデンウィークなのに遊んでやれなくてゴメンね。

それからママもありがとう…

 

 

【Git】Gitのインストール手順(TortoiseGit)

インストー

下記のページを参考にインストールしてみます。
こちらもとても参考になりますので是非読んでください。

TortoiseGitのインストールの前にGit for Windowsをインストールしておく必要があります。
下記のページを参考にインストールしてください。

1.ダウンロードしてくる

TortoiseGit

現状の最新版は2.4.0.2です。(2017/4/7)

TortoiseGit-2.4.0.2-64bit.msiをダウンロードします。
日本語化パック(TortoiseGit-LanguagePack-2.4.0.0-64bit-ja.msi)もあわせてダウンロードします。

Git for Windowsはインストール済なのでTortoiseGitのインストールを開始します。

2.TortoiseGitのインストー

インストーラを実行します。
基本的には[Next>]で進めていけば問題ありません。

tortoisegit_000.png

tortoisegit_001.png

SSHクライアントの選択は一番上を選択しておきます。

tortoisegit_002.png

カスタムセットアップも変更がなければそのまま進めます。

tortoisegit_003.png

tortoisegit_004.png

tortoisegit_005.png

インストールが完了しました。

tortoisegit_006.png

起動してみます。
日本語化パックをインストールしていないのでここはEnglishのまま進めます。

tortoisegit_007.png

tortoisegit_008.png

tortoisegit_009.png

ユーザー情報もGit Bashで設定した情報が表示されているのでこのまま進めます。

tortoisegit_010.png

tortoisegit_011.png

これで初期スタートの設定も完了です。

3.日本語化パックのインストー

langpack_000.png

langpack_001.png

langpack_002.png

インストールが完了しました。

日本語に切り替えます。
右クリックのTortoiseGitのsettingを選択してください。

langpack_003.png

GeneralのLanguageを日本語に切り替えてください。

langpack_004.png

これで日本語への切り替えが完了しました。

【Git】Gitのインストール手順(Git for Windows)

インストー

下記のリンクを参考にインストールしてみます。
ページによって若干違いがありますがとても参考になりますので読んでください。

1.ダウンロードしてくる

Git for windows

現状の最新版は2.12.0。(2017/3/17)
Git-2.12.0-64-bit.exeをダウンロード。

2.インストーラを起動する

git_000.png

3.インストール先のフォルダを選択する

特に変更がなければそのまま進みます。

git_001.png

4.インストールするコンポーネントを選択する

ここもとりあえず変更なしで進めます。

git_002.png

5.スタートメニューへ追加するかどうか選択する

スタートメニューに追加したくない場合は下の Don’t create a Start Menu folder にチェックを入れます。

git_003.png

6.Gitをコマンドプロンプトから使うかどうか選択する

今回は一番上の Git Bash only を選択しました。
TortoiseGitを使用する場合も考慮する必要があればその時に再度見直します。

git_004.png

7.改行の扱いをどうするか選択する

参考ページでも意見が分かれているところです。
今回は一番下の Checkout as-is,commin as-is で進めます。

git_005.png

これは開発環境やプロジェクトによって都度検討してくことになると思われます。
インストール後に変更できるのか?
プロジェクトによってポリシーが異なった場合はどうやって運用していくのか?

8.ターミナルに何を使うか選択する

そのまま進めます。

git_006.png

9.キャッシュと2段階認証の設定有効/無効を選択する

そのまま進めます。

git_007.png

10.インストール中…

git_008.png

11.インストール完了

git_009.png

12.Git Bash起動

スタートメニューからGitBashを実行して起動を確認します。

【UE4】UnrealEngine4をソースからビルドする

UnrealEngine4のソースを取得してビルドする方法についてまとめました。

以下の項目については事前に準備しておく必要があります。

ビルド手順

UnrealEngineのアカウントとGitHubのアカウントを関連付ける

UnrealEngineのアカウント管理画面でGitHubのアカウントを入力します。 これでUEのアカウントとGitHubのアカウントが関連付けられました。

ue4_000.png

GitHubからソースを取得する

GitHub内のEpicのページにアクセスしてUnrealEngieのページが開くことができれば関連付けが正しく行われたことになります。

ue4_001.png

zipファイルでダウンロードすることもできますが、今回はTortoiseGtiで取得してみます。 右上の緑のボタンのChose or downloadを選択してください。 そこに表示されているURLをコピーしておきます。

ue4_002.png

TortoiseGitでリポジトリをクローンします。 URLに先ほどのURLを入力して、ディレクトリは任意のディレクトリを指定しておきます。

ue4_003.png

ue4_004.png

これでGitHubからソースを取得することができました。

追加の依存ファイルをダウンロード

取得したフォルダのルートにSetup.batというバッチファイルがあるので実行します。 これで必要な追加ファイルがダウンロードされます。

ue4_005.png

ソリューションファイルの生成

GenerateProjectFiles.batを実行します。 UE4.slnというVisualStudioのソリューションファイルが生成されます。

詳しくはオフィシャルのドキュメントも参考にしてください。

ビルド

UE4.slnをクリックしてVisualStudioを起動してビルドしてください。

これでUnrealEngineをソースからビルドすることができました。

参考



【おでかけ】カフェノタビ

f:id:takezoh_1127:20170501092228j:image

カフェノタビに行って来ました!

 

カフェや古本、手作り雑貨などが集まるイベントです。

 

かずさアカデミアパークの近くの公園が会場です。

ここでの開催は2回目とのことです。

 

妻が好きな花屋さんも出店しています。

イベントを知ったのも花屋さんから教えてもらいました。

 

会場に入るとまずは古本のコーナー。

本だけを扱うお店や雑貨も一緒に置いてあるお店など10店ほど出ていました。

 

f:id:takezoh_1127:20170501092304j:image

f:id:takezoh_1127:20170501092429j:image 

下の子はフェーブ(フランスでお菓子に入れる陶器の小さな人形)に夢中に。

ずーっと選んでいましが、最終的に選んだのがタマゴ。

ネコとか女の子とか勧めたけど「マゴ!マゴ!」と言ってタマゴを嬉しそうに選んでいました。

 

昼ごはんはSmallAxeというお店のハンバーガー。

ボリュームもあってジューシーでメチャクチャ美味しいです。

こういうイベントには良く出店されているので他も食べたいけどやっぱり選んでしまいます。

 

それからPIZZA FORNOのピザ。

石窯焼きのピザでとても美味しいです。

このお店も別のイベントで食べたことがあります。

 

f:id:takezoh_1127:20170501092328j:image

 

f:id:takezoh_1127:20170501092345j:image

 

他にも手作り雑貨やカフェや食べるお店など沢山あって、ステージで音楽のイベントがあったりしてましたが下の子が楽しそうに走り回っていたのでゆっくりと見れません出した。

 

f:id:takezoh_1127:20170501092503j:image

 

f:id:takezoh_1127:20170501092531j:image

 

f:id:takezoh_1127:20170501092551j:image

 

 

帰りにhanahacoというカフェにも寄りました。

料理が美味しくてサラダバーも美味しいお店です。

会場からすぐ近くなのでこちらもオススメです。

f:id:takezoh_1127:20170501093326j:image

f:id:takezoh_1127:20170501093339j:image 

 

 

家からも近いし、来年も開催してくれると嬉しいです。

天気も良くて楽しい一日でした。

 

※下の子の「マゴ」

f:id:takezoh_1127:20170501093507j:image

 

※購入した古本

f:id:takezoh_1127:20170502085329j:image

 

※花屋さんで購入

f:id:takezoh_1127:20170502151146j:image

 

※イベントのチラシ

f:id:takezoh_1127:20170501093537j:image

f:id:takezoh_1127:20170501093550j:image 

【バグ】マスターまで残り4日!1バイトのメモリ破壊を追え!

はじめに

過去のプロジェクトでマスター直前に出たメモリ破壊のバグを調査した時の方法を公開します。

報告内容

プラットフォーム:コンシューマ
言語:C++

症状:
メモリアロケート時に門番の情報が破壊されているらしく、不正チェックに引っかかり、ASSERTで停止。
タイミングは不定、アドレスも不定な為ハードウェアブレイクでも追うのが困難な状況。
再現頻度はかなり低い。

今ところはデバッグ版のみで発生。
リリース版はエラーチェックに引っかからないので発覚していないだけで、メモリは破壊されている可能性はある。

調査開始

かなりやっかいなメモリ破壊系の不具合報告が来ました。

破壊している箇所がたまたま門番の場所だったのでその領域を解放した時のチェックで発覚しました。
メモリアロケート時に不正チェックに引っかかっているということは、それ以前のどこかのタイミングで破壊されていると思われます。
もしかしたら他のデータ領域を壊している可能性もありますし、その場合壊されたことに気が付かず動作し続けている可能性もあります。

色々と追っているがとっかかりがない状況です。

他のメンバーはマスター直前で他のチケットにかかりきりで誰も調べられていません。

可能性を考えてみます。

頻度は高くないが壊されたメモリを確認してみると、必ず1バイトが書き換わっている様で前後の門番のフィルの状態は壊されていませんでした。

バッファオーバーランの可能性もありますが、仮にそのオブジェクトのインスタンスでメモリを破壊してそのタイミングで門番を破壊しているようであれば
そのインスタンスが破棄されたタイミングなどでもエラーが出てもよさそうなものです。

まずは変数の書き込みを疑ってみることにします。

ということで以下の様なことをやって書き込みのタイミングで拾うようにしてみました。

調査方法

プロジェクトでは固有の型が定義されています。
簡潔に書くために便宜上以下の様にしています。

typedef char s8;
typedef unsigned char u8;
typedef short s16;
typedef unsigned short s16;
  :
  :

変数の書き込みのタイミングでチェックを行うために以下の様なclassを定義します。
力技ですがboolやs8,u8という型をGrepでBool,S8,U8に置換します。
これで今までと同じ挙動で変数の型を置き換えることができました。

class check_bool
{
public:
    check_bool() : val( false ){}
    check_bool( bool b ) : val( b ){}
    
    operator bool() const { return val; }
    operator int() const { return val; }
    
    check_bool& operator=( const bool &src )
    {
        // 書き込みに行く前にヒープ領域のチェック.
        if( Allocator::CheckAddressIsFreeBlock( &val ) )
        {
            ASSERT( " ### Error : free memory access.\n" );
        }
        
        val = src;
        return *this;
    }
    
    check_bool& operator=( const check_bool &src )
    {
        // 書き込みに行く前にヒープ領域のチェック.
        if( Allocator::CheckAddressIsFreeBlock( &val ) )
        {
            ASSERT( " ### Error : free memory access.\n" );
        }
        
        val = src.val;
        return *this;
    }
    
    bool operator==( const bool &src ) const
    {
        return val == src;
    }
    
    bool operator==( const check_bool &src ) const
    {
        return val == src.val;
    }
    
    bool operator!=( const bool &src ) const
    {
        return val != src;
    }
    
    bool operator!=( const check_bool &src ) const
    {
        return val != src.val;
    }
    
    bool operator!( void ) const
    {
        return !val;
    }
    
    bool operator<( const bool &src ) const
    {
        return val < src;
    }
    
    bool operator<( const check_bool &src ) const
    {
        return val < src.val;
    }
    
    bool operator>( const bool &src ) const
    {
        return val > src;
    }
    
    bool operator>( const check_bool &src ) const
    {
        return val > src.val;
    }

private:
    bool   val;

private:
    bool operator<( const bool &src );
    bool operator<( const check_bool &src );
    bool operator<=( const bool &src );
    bool operator<=( const check_bool &src );
    bool operator>( const bool &src );
    bool operator>( const check_bool &src );
    bool operator>=( const bool &src );
    bool operator>=( const check_bool &src );
};

template< typename Tp_ > class check_integer
{
public:
    check_integer(){}
    check_integer( Tp_ i ) : val( i ){}
    
    operator Tp_() const { return val; }
    
    check_integer& operator=( const Tp_ &src )
    {
        // 書き込みに行く前にヒープ領域のチェック.
        if( Allocator::CheckAddressIsFreeBlock( &val ) )
        {
            ASSERT( " ### Error : free memory access.\n" );
        }
        
        val = src;
        return *this;
    }
    
    check_integer& operator=( const check_integer &src )
    {
        // 書き込みに行く前にヒープ領域のチェック.
        if( Allocator::CheckAddressIsFreeBlock( &val ) )
        {
            ASSERT( " ### Error : free memory access.\n" );
        }
        
        val = src.val;
        return *this;
    }
    
    /** 前置インクリメント.
       
       r = ++i;
       
       int は前置と後置の判別のためのダミー
   */
    check_integer& operator ++ (int)
    {
        // 書き込みに行く前にヒープ領域のチェック.
        if( Allocator::CheckAddressIsFreeBlock( &val ) )
        {
            ASSERT( " ### Error : free memory access.\n" );
        }
        
        ++val;
        return *this;
    }
    
    /** 前置デクリメント
       r = --i;
   */
    check_integer& operator -- (int)
    {
        // 書き込みに行く前にヒープ領域のチェック.
        if( Allocator::CheckAddressIsFreeBlock( &val ) )
        {
            ASSERT( " ### Error : free memory access.\n" );
        }
        
        --val;
        return *this;
    }
    
    /** 後置インクリメント
       r = i++;
   */
    check_integer operator ++ ()
    {
        // 書き込みに行く前にヒープ領域のチェック.
        if( Allocator::CheckAddressIsFreeBlock( &val ) )
        {
            ASSERT( " ### Error : free memory access.\n" );
        }
        
        check_integer   r( val );   // 壊す前の値を返さなければならない.
        
        ++val;
        return r;
    }
    
    /** 後置デクリメント
       r = i--;
   */
    check_integer operator -- ()
    {
        // 書き込みに行く前にヒープ領域のチェック.
        if( Allocator::CheckAddressIsFreeBlock( &val ) )
        {
            ASSERT( " ### Error : free memory access.\n" );
        }
        
        check_integer   r( val );   // 壊す前の値を返さなければならない.
        
        --val;
        return r;
    }
    
    /** 単項マイナス
       r = -i;
   */
    check_integer operator - () const
    {
        return check_integer( -val );
    }
    
    /** 加算
       r = i0 + i1;
   */
    check_integer operator + ( const check_integer &src ) const
    {
        return check_integer( val + src.val );
    }
    
    check_integer operator + ( const int &src ) const
    {
        return check_integer( val + src );
    }
    
    /** 減算
       r = i0 - i1;
   */
    check_integer operator - ( const check_integer &src ) const
    {
        return check_integer( val - src.val );
    }
    
    check_integer operator - ( const int &src ) const
    {
        return check_integer( val - src );
    }
    
    /** 乗算
       r = i0 * i1;
   */
    check_integer operator * ( const check_integer &src ) const
    {
        return check_integer( val * src.val );
    }
    
    check_integer operator * ( const int &src ) const
    {
        return check_integer( val * src );
    }
    
    /** 除算
       r = i0 / i1;
   */
    check_integer operator / ( const check_integer &src ) const
    {
        return check_integer( val / src.val );
    }
    
    check_integer operator / ( const int &src ) const
    {
        return check_integer( val / src );
    }
    
    /** 剰余
       r = obj % o;
   */
    check_integer operator % ( const check_integer &src ) const
    {
        return check_integer( val % src.val );
    }
    
    check_integer operator % ( const int &src ) const
    {
        return check_integer( val % src );
    }
    
    /** 加算代入
       i0 += i1;
   */
    check_integer& operator += ( const check_integer &src )
    {
        val += src.val;
        return *this;
    }
    
    /** 減算代入
       i0 -= i1;
   */
    check_integer& operator -= ( const check_integer &src )
    {
        val -= src.val;
        return *this;
    }
    
    /** 乗算代入
       i0 *= i1;
   */
    check_integer& operator *= ( const check_integer &src )
    {
        val *= src.val;
        return *this;
    }
    
    /** 除算代入
       i0 /= i1;
   */
    check_integer& operator /= ( const check_integer &src )
    {
        val /= src.val;
        return *this;
    }
    
    /** 剰余代入
       obj %= o;
   */
    check_integer& operator %= ( const check_integer &src )
    {
        val %= src.val;
        return *this;
    }
    
    bool operator==( const s8 &src ) const
    {
        return val == src;
    }
    
    bool operator==( const u8 &src ) const
    {
        return val == src;
    }
    
    bool operator==( const s16 &src ) const
    {
        return val == src;
    }
    
    bool operator==( const u16 &src ) const
    {
        return val == src;
    }
    
    bool operator==( const s32 &src ) const
    {
        return val == src;
    }
    
    bool operator==( const u32 &src ) const
    {
        return val == src;
    }
    
    bool operator==( const int &src ) const
    {
        return val == src;
    }
    
    bool operator==( const check_integer &src ) const
    {
        return val == src.val;
    }
    
    bool operator!=( const s8 &src ) const
    {
        return val != src;
    }
    
    bool operator!=( const u8 &src ) const
    {
        return val != src;
    }
    
    bool operator!=( const s16 &src ) const
    {
        return val != src;
    }
    
    bool operator!=( const u16 &src ) const
    {
        return val != src;
    }
    
    bool operator!=( const s32 &src ) const
    {
        return val != src;
    }
    
    bool operator!=( const u32 &src ) const
    {
        return val != src;
    }
    
    bool operator!=( const int &src ) const
    {
        return val != src;
    }
    
    bool operator!=( const check_integer &src ) const
    {
        return val != src.val;
    }
    
    bool operator<( const s8 &src ) const
    {
        return val < src;
    }
    
    bool operator<( const u8 &src ) const
    {
        return val < src;
    }
    
    bool operator<( const s16 &src ) const
    {
        return val < src;
    }
    
    bool operator<( const u16 &src ) const
    {
        return val < src;
    }
    
    bool operator<( const s32 &src ) const
    {
        return val < src;
    }
    
    bool operator<( const u32 &src ) const
    {
        return val < src;
    }
    
    bool operator<( const int &src ) const
    {
        return val < src;
    }
    
    bool operator<( const check_integer &src ) const
    {
        return val < src.val;
    }
    
    bool operator<=( const s8 &src ) const
    {
        return val <= src;
    }
    
    bool operator<=( const u8 &src ) const
    {
        return val <= src;
    }
    
    bool operator<=( const s16 &src ) const
    {
        return val <= src;
    }
    
    bool operator<=( const u16 &src ) const
    {
        return val <= src;
    }
    
    bool operator<=( const s32 &src ) const
    {
        return val <= src;
    }
    
    bool operator<=( const u32 &src ) const
    {
        return val <= src;
    }
    
    bool operator<=( const int &src ) const
    {
        return val <= src;
    }
    
    bool operator<=( const check_integer &src ) const
    {
        return val <= src.val;
    }
    
    bool operator>( const s8 &src ) const
    {
        return val > src;
    }
    
    bool operator>( const u8 &src ) const
    {
        return val > src;
    }
    
    bool operator>( const s16 &src ) const
    {
        return val > src;
    }
    
    bool operator>( const u16 &src ) const
    {
        return val > src;
    }
    
    bool operator>( const s32 &src ) const
    {
        return val > src;
    }
    
    bool operator>( const u32 &src ) const
    {
        return val > src;
    }
    
    bool operator>( const int &src ) const
    {
        return val > src;
    }
    
    bool operator>( const check_integer &src ) const
    {
        return val > src.val;
    }
    
    bool operator>=( const s8 &src ) const
    {
        return val >= src;
    }
    
    bool operator>=( const u8 &src ) const
    {
        return val >= src;
    }
    
    bool operator>=( const s16 &src ) const
    {
        return val >= src;
    }
    
    bool operator>=( const u16 &src ) const
    {
        return val >= src;
    }
    
    bool operator>=( const s32 &src ) const
    {
        return val >= src;
    }
    
    bool operator>=( const u32 &src ) const
    {
        return val >= src;
    }
    
    bool operator>=( const int &src ) const
    {
        return val >= src;
    }
    
    bool operator>=( const check_integer &src )
    {
        return val >= src.val;
    }

private:
    Tp_     val;

private:
    bool operator!( void ) const;
};

typedef    check_bool          Bool;
typedef    check_integer< s8 >   S8;
typedef    check_integer< u8 >   U8;
bool Allocator::CheckAddressIsFreeBlock( const void* p )
{
    // 独自アロケータで実装されているので書き込みを行ったアドレスが
    // ヒープのフリー領域や門番等のアドレスかどうかをチェックします
}

この仕組みを施してテストに回したところ、テストプレイで見事にチェックに引っかかりました。

担当者に報告してデバッガ上で再現してもらい確認してもらったところ、デバッグ機能側で解放されたオブジェクトに対して操作を行っていたらしいです。

デバッグ機能というところまで絞り込めたので、そこまで分かれば再現手順も絞り込めます。
担当者に修正してもらい、テストプレイでも再現しないことが確認できました。

最後に

今回は本当に1バイトの変数の書き込みのタイミングだったのでバグが特定できましが、違う不具合だったらどう対処してたんでしょうか…

他にももっとスマートな解決方法があったもしれません。

そもそも論で言えばスマートポインタのような仕組みで設計、実装されていればというのもありますが、起きてしまったバグはなんとか潰さなければなりません。

手法はどうあれ問題を解決することが重要です。

同じやり方でというケースはないかもしれませんが何かの参考にでもなればと思います。

みなさんもやっかい系のバグに出くわして、こういう風に解決しましたという事例があったら教えてください。


そもそもバグに悩まされるのがいやなので、こちらの関連記事も読んでみてください。

www.main-function.com

【Unity】C#のタブがスペースに置き換えらてしまう

UnityでC#を触っていますが、VisualStudioで編集しているとタブが勝手にスペースに置き換えられてしまいます。

デフォルトの設定でそうなっているので何か理由があるのかもしれませんが、 自分はどうもそれに馴染めないので設定を変更してみます。

[ツール]→[オプション]でオプション設定ウィンドウを開いて、 [テキストエディター]→[C#]→[タブ]の設定でタブの保持にチェックを入れます。

f:id:takezoh_1127:20170424104133p:plain

みなさんはどうしているのでしょうか? それからチームで開発するときはどう統一しているのでしょうか?