win32とCRTで簡単なメモリリーク診断とリーク位置の発見

VC6の素のwin32プロジェクトが前提。

プログラムの最初のほうで以下を書く

ここではStdAfx.cppに書いた。_CrtSetDbgFlagを呼ぶことでプログラム終了時にリークがあると以下のように出力される。

ここにファイル名を表示させたりもできるが今回はスルー。上記の{47}に注目してコードの先頭で以下のように書く。

こうするとリークするアロックのときブレークするのでコールスタックからリーク位置が分かる。

これで判明するのはmalloc, calloc, realloc, newなどのCRT関連で、HeapAllocやSysAllocStringなどは対象外。

右クリックの「送る」メニューにドライブを表示させない

上のテキストを拡張子.regで保存して実行する。Explorer.exeを再起動するか、いったんサインアウトする。

string size length 違い

違いはない。ただしstrlenとは違う。

stringは自分でサイズを持っているのでNUL文字を含むことができる。strlenなどの関数はNULまでを数えて返すが、size()やlength()は自分で管理しているサイズを返す。

ランタイムライブラリ /MD /MT

メモ
VC2010

コピペ https://msdn.microsoft.com/ja-jp/library/vstudio/abx4dbyh%28v=vs.100%29.aspx

C run-time library (without iostream or standard C++ library) Associated DLL Characteristics Option Preprocessor directives
libcmt.lib None, static link. Multithreaded, static link /MT _MT
msvcrt.lib msvcr100.dll Multithreaded, dynamic link (import library for MSVCR100.DLL). Be aware that if you use the Standard C++ Library, your program will need MSVCP100.DLL to run. /MD _MT, _DLL
libcmtd.lib None, static link Multithreaded, static link (debug) /MTd _DEBUG, _MT
msvcrtd.lib msvcr100d.dll Multithreaded, dynamic link (import library for MSVCR100D.DLL) (debug). /MDd _DEBUG, _MT, _DLL
msvcmrt.lib None, static link C Runtime static library. Used for mixed managed/native code. /clr

/clr:oldSyntax

msvcurt.lib None, static link C Runtime static library compiled as 100% pure MSIL code. All code complies with the ECMA URT spec for MSIL. /clr:pure  

 

コピペ https://msdn.microsoft.com/en-us/library/abx4dbyh%28v=vs.100%29.aspx

Characteristics Option Preprocessor directives
LIBCPMT.LIB Multithreaded, static link /MT _MT
MSVCPRT.LIB Multithreaded, dynamic link (import library for MSVCP100.dll) /MD _MT, _DLL
LIBCPMTD.LIB Multithreaded, static link /MTd _DEBUG, _MT
MSVCPRTD.LIB Multithreaded, dynamic link (import library for MSVCP100D.DLL) /MDd _DEBUG, _MT, _DLL

コピペ https://msdn.microsoft.com/en-us/library/b0084kay.aspx

_M_CEE Defined for a compilation that uses any form of /clr (/clr:oldSyntax, /clr:safe, for example).
_M_CEE_PURE Defined for a compilation that uses /clr:pure.
_M_CEE_SAFE Defined for a compilation that uses /clr:safe.

コピペ C:\Program Files\Microsoft Visual Studio 9.0\VC\include\use_ansi.h

/MT

libcmt.libにスタティックにリンクする。Cランタイムコードは自分のEXEやDLLに埋め込まれる。DLLでは普通はこれを使わない。このオプションを指定するとコンパイラは_MTをdefineする。C++ソースコードはこのフラグによってC++ランタイムをpragma comment(lib…)でリンクする。/MTの場合はlibcpmt.libがリンクされる。これはスタティックライブラリで自分のEXEにCPPコードが埋め込まれる。

/MD

イ ンポートライブラリmsvcrt.libにリンクする。実行時にmsvcr100.dllにリンクされる。Cランタイムコードはmsvcr100.dll にある。DLLを作るときは通常これを使い、そうして作られたDLLを使うEXEをリンクするときも/MDを使う。そうすればランタイムが共有される。コンパイラは_MTと_DLLをdefineしその結果msvcprt.libがリンクされる、これはインポートライブラリで意実行時にmsvcp100.dllにリンクされる。/MDを使いCPPのリンクはスタティックで行いたいときは_STATIC_CPPLIBを定義する。

/clr:pure /clr

‘/clr’ と ‘/MT’ は同時に指定できないので、/MDになる。
pureをつけるとCランタイムがリンクされない。あとは不明

Win32で全角半角変換、カタカナひらがな変換

詳しくは調べていない。W系の関数ならLCIDは無視すると思いたいが、マニュアルにはそう書いてないように見える。CStringはstd::wstringでも動くはず。

mainの前に関数を呼び出す方法 VCの場合

Cでmainの前に関数を呼び出す

セクション.CRT$XIUに関数ポインタを置く。これは自分で書く。

CRTはCRT$XIAとCRT$XZに__xi_a,__xi_zを置く。
セクションはリンク時にまとめてアルファベット順に並べられるので、__xi_aと__xi_zに挟まれた領域にある関数ポインタを全部呼び出すことでコンストラクタを呼び出す。

C++でグローバルなインスタンスのコンストラクタコール

グローバルインスタンスのコンストラクタを誰が呼ぶか?
Visual C++コンパイラはコンストラクタのポインタをセクションのCRT$XCUに置く。

CRTはCRT$XCAとCRT$XCZに__xc_a,__cx_zを置く。

mainの後に実行するもの

C++のグローバルインスタンスのデストラクタはおそらくatexitの機能と同様に呼ばれる。グローバルな場合はインスタンスが置かれてる順番で登録されるが複数ファイルにまたがるときの順番は不明。staticの場合はコンストラクタが実行された後のタイミングで登録される。

上で示したセグメントでやる呼ぶ方法もあるが同じなのでスルー

https://msdn.microsoft.com/ja-jp/library/bb918180.aspx
http://www.codeguru.com/cpp/misc/misc/applicationcontrol/article.php/c6945/Running-Code-Before-and-After-Main.htm#page-1

Windows8のメンテナンス機能

Windows8のメンテナンス機能

従来のタスクスケジューラの拡張で、アイドル時に行われ、時刻指定のないタスク群のこと
タスクの設定で MaintenanceSettings が指定されているのもと思われる。
こういったタスクは普通のタスクとして登録するよりもメンテナンスとして登録しておけばタスクの衝突が起こらずコンピュータリソースがビジーになったりしないようにできる。

設定例:

PeriodやDeadlineの書式は不明だがここでは2日に一回、14日に一回と読んでおこう。基本的に2日に一回実行し、最低でも14日に一回は実行されないとならないと読める。
14日を超えたら何らかの通知がなされるものと思われる。

起動は普通のタスクとして登録されている”Idle Mantenace”や”Regular Maintenace”から行われると思われる。
この2つのタスクのアクションはカスタムハンドラー{57BFCFDD-EEE4-4DBB-A751-3CDEB169FF44}で定義されているのでここから起動された%systemroot%\system32\msched.dllがタスクを開始すると思われる。(インターフェースは不明)

https://msdn.microsoft.com/en-us/library/windows/desktop/hh848037(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/jj835985(v=vs.85).aspx

cygwinにapt-cygをインストール

1、wgetを普通にインストール
wgetはデフォルトでインストールされないのでインストールしておく、これがなくてもlynxで動くらしいがうまく動かなかったので事前にインストールしておく。

clipshot 2015-10-02 12-18-34

2、apt-cygをインストール

apt-cygはスクリプトなので32ビットでも64ビットでも大丈夫

3、検索してインストール
ここではlibislを探してインストール