2017-09-20 12 views
1

私はGDIリークを追跡し、WINAPIをより良く理解するためのコードを書いています。私はGDI functionsのすべてを迂回し、リストされたすべてのハンドルの作成と破棄を記録することでこれをやっています。DeleteObject()を使用する以外の方法でHBITMAPを削除する方法はありますか?

HBITMAPCreateDIBitmap()を使用して作成されており、DeleteObject()を使用して破壊されないことが分かる(又は記載されている他の破壊関数呼び出しのいずれか)、その後しばらく後で前述の関数として同じハンドルにCreateBitmap()コール結果。その間にたくさんのHBITMAP(および他のハンドル)が作成されています。

ドキュメントに記載されていないHBITMAPを破棄する他の方法があるかどうかは疑問です。または同じものを生成する方法がありますHBITMAP? 誰か知っていますか?

私はGDIの破損を発見したことをちょっと心配しています。

編集

ただ、更新のため、ここでは(これが唯一のインスタンスである、他のすべてのインスタンスが同じ場合はチェックしていない)私は私のログに見ていますものです:

 
    21133  107110: |>Creating HBITMAP # 707/782 with function CreateDIBSection 
    21134  107110: |<Created HBITMAP # 707/782 0xAC057A00 with function CreateDIBSection 
    21135  107125: |>Creating HBITMAP # 708/783 with function CreateBitmap 
    21136  107125: |<Created HBITMAP # 708/783 0xA9057B85 with function CreateBitmap 
    21137  107125: |>Creating HDC# 16/16 with function CreateCompatibleDC 
    21138  107125: |<Created HDC# 16/16 0x5F01466B with function CreateCompatibleDC 
    21139  107125: |>Creating HICON # 35/35 with function CreateIconIndirect 
    21140  107125: |>Creating HBITMAP # 709/784 with function CreateDIBitmap 
    21141  107125: |<Created HBITMAP # 709/784 0x67055812 with function CreateDIBitmap 
    21142  107141: |>Creating HBITMAP # 710/785 with function CreateBitmap 
    21143  107141: |<Created HBITMAP # 710/785 0x9605596F with function CreateBitmap 
    21144  107141: |>Creating HDC# 17/17 with function CreateCompatibleDC 
    21145  107141: |<Created HDC# 17/17 0xD7011ACD with function CreateCompatibleDC 
    21146  107141: |>Destroying HDC# 17/17 0xD7011ACD with function DeleteDC 
    21147  107156: |<Destroyed handle 0xD7011ACD with function DeleteDC 
    21148  107156: |<Created HICON # 35/35 0x653526D3 with function CreateIconIndirect 
    21149  107156: |>Destroying HBITMAP # 710/785 0xA9057B85 with function DeleteObject 
    21150  107156: |<Destroyed handle 0xA9057B85 with function DeleteObject 
    21151  107156: |>Destroying HDC# 16/16 0x5F01466B with function DeleteDC 
    21152  107156: |<Destroyed handle 0x5F01466B with function DeleteDC 

...といくつかの時間後に(約9秒)...

 
    25319  118172: |>Creating HBITMAP # 862/937 with function CreateBitmap 
    25320  118172: |<Created HBITMAP # 862/937 0x9605596F with function CreateBitmap * 
    25321  118172: |>Creating HDC# 16/16 with function CreateCompatibleDC 
    25322  118172: |<Created HDC# 16/16 0x39013C5B with function CreateCompatibleDC 
    25323  118172: |>Creating HICON # 36/36 with function CreateIconIndirect 
    25324  118172: |>Creating HBITMAP # 862/937 with function CreateDIBitmap 
    25325  118188: |<Created HBITMAP # 862/937 0x27056374 with function CreateDIBitmap 
    25326  118188: |>Creating HBITMAP # 863/938 with function CreateBitmap 
    25327  118188: |<Created HBITMAP # 863/938 0xD20538B5 with function CreateBitmap 
    25328  118188: |>Creating HDC# 17/17 with function CreateCompatibleDC 
    25329  118188: |<Created HDC# 17/17 0xD9015812 with function CreateCompatibleDC 
    25330  118188: |>Destroying HDC# 17/17 0xD9015812 with function DeleteDC 
    25331  118188: |<Destroyed handle 0xD9015812 with function DeleteDC 
    25332  118203: |<Created HICON # 36/36 0x087718AD with function CreateIconIndirect 
    25333  118203: |>Destroying HBITMAP # 863/938 0x9605596F with function DeleteObject 
    25334  118219: |<Destroyed handle 0x9605596F with function DeleteObject 
  • sequeを注文しようとすると、1列目には、シーケンスカウント(便利です複数のスレッドのイベントのnce)。
  • 2番目は、最初のログ項目からの時間(ミリ秒)です。
  • :spaces|は、私が見ているすべてのものに対して、呼び出しがネストされている距離を見るための視覚的なグラフです。
  • >は、関数に入る直前を表し、<は、関数を終了した直後を表します。
  • 作成または破棄、および作成または破棄されているオブジェクトを示します。
  • x/yここで、xは、作成しようとしているオブジェクトの数または破棄された残りの数です。yは、基本タイプ(削除されるタイプ)を表します。
  • 進数は関数が破壊/オブジェクト
  • を作成するために使用されるラインは*で終わる場合、それは、このハンドルは前に説明したが、破壊されていないことを意味するハンドル値
  • あります。

どのくらいの情報があり、どのようにネスティングが機能するかは興味深いです(ウィンドウメッセージをトラッキングするのには本当に便利です)。

 
    25349  118250: |>Destroying HICON # 36/36 0x087718AD with function DestroyIcon 
    25350  118250: |<Destroyed handle 0x087718AD with function DestroyIcon 

HICONが破壊されますが、含まれているHBITMAP sがない、と彼らは、彼らが予想外にいるとき以外は(どこかのログで再び参照されていない:私は気づい

もうひとつは、このでしたリサイクル)。したがって、これがHICONの場合にのみ発生すると、DestroyIcon()がうまく再生されず、文書化されていない関数が使用されている可能性があります。残りのログを調査する必要があります。

+0

私はWindows OSのキャッシュ機能をいくつか見ていると思います。 – VuVirt

+0

@VuVirt、そしてそれはどうやって動作しますか?これらは名前のついたオブジェクトではありません。 *同じ*ハンドルを使用すべきと判断する方法は? – Adrian

+0

HGDIOBJはアドレス(一意ではない)ではなく、有限のサイズのテーブルのスロットのインデックスです。技術的には、テーブルがオーバーフローしたときに同じHGDIOBJ値を得ることができます。 –

答えて

1

徹底的にログを調べ、GetGuiResources()でGDIオブジェクトの数を記録すると、HICONを作成するときにHBITMAPが作成されたように見えます。ただし、DestroyIcon()ファンクションは、ファンクションコールを破棄するときにDestoryObject()ファンクションコールをバイパスします。

私はMSの誰かがこれを行うことで数サイクルを節約したかったと思いますか?なんでも。

これは興味深い練習であり、ログはうまく機能しているようです。

関連する問題