pit-rayの備忘録

開発中に得た知識を記事にしていくブログ

<Qt>CDBをデバッガとして利用する方法

今回は、QtにCDBをデバッガとして設定する方法を解説します。

Qtでデバッグ開始時に以下のようなエラーを吐かれてデバッグができないケースがあります。
f:id:pit-ray:20180828212259j:plain

The selected debugger may be inappropriate for the inferior.
Examining symbols and setting breakpoints by file name and line number may fail.

The inferior is in the Portable Executable format.
Selecting CDB as debugger would improve the debugging experience for this binary format.

エラーの通り、CDBをデバッガにすると改善が見込めるとあります。
Qtの初期設定では、CDBが既にインストールされている場合には自動検出されるため、CDBがPC上にないことが考えられます。
よって、CDBをインストールすればOKです。

まず、CDBのインストーラーを入手する必要があります。

以下のWebサイトから得られるインストーラーは、Windows Driver Kitといい、様々なツールが含まれています。
このWDKの中にCDBがあります。
f:id:pit-ray:20180828220226j:plain
Download the Windows Driver Kit (WDK) | Microsoft Docs





次に、WDKインストーラーを入手したら、この中にあるCDBインストーラーのみを実行します。
CDBインストーラーのみ実行するには以下の手順を踏みます。

①WDKインストーラーを実行し、
Download the Windows Driver Kit - Windows 10.0.17134.1 for installation on a separate computer
からインストール。
f:id:pit-ray:20180828221043j:plain

②次にダウンロード先のディレクトリWindows Kits/10/WDK/Installersから
X64 Debuggers And Tools-x64_en-us.msiまたは
X86 Debuggers And Tools-x86_en-us.msiを実行します。
f:id:pit-ray:20180828222044j:plain
Windows 64bit:x64
Windows 32bit:x86


このインストーラーがCDBインストーラーになります。


CDBインストーラーは流れにそってそのまま進めるとインストールが完了し、自動でQtに適用されます。
f:id:pit-ray:20180828223005j:plain
自動で適用されない場合、手動でcdb.exeのパスを入れます。

以上です。
なにかありましたらコメントください。

<C言語>構造体のアドレスは何を指すのか

本日はまたC言語についてのちょっとしたトピックを取り上げます。

構造体のアドレスは何を指しているのか?です。

まず、以下のプログラムを見ていきましょう。

#include <Windows.h>
#include <stdio.h>

typedef struct STRUCT_P_TEST {
    int a ;
    int b ;
} st_test ;

int main() {
    st_test st = { 5, 6 } ;

    //構造体、メンバのアドレスをポインタとしてコピー
    int* p_st   = ( int* )&st ;
    int* p_st_a = ( int* )&st.a ;
    int* p_st_b = ( int* )&st.b ;

    printf( "struct adress   = %p\n", p_st ) ;
    printf( "member a adress = %p\n", p_st_a ) ;
    printf( "member b adress = %p\n", p_st_b ) ;

    printf( "_ _ _ _ _ _ _ _ _ _ _ _ _\n" ) ;
    printf( "struct value    = %d\n", *p_st ) ;
    printf( "member a value  = %d\n", *p_st_a ) ;
    printf( "member b value  = %d\n", *p_st_b ) ;
    
    Sleep( 5000 ) ;

    return 0 ;
}

実行結果

struct adress   = 00AFFE74
member a adress = 00AFFE74
member b adress = 00AFFE78
_ _ _ _ _ _ _ _ _ _ _ _ _
struct value    = 5
member a value  = 5
member b value  = 6

動作環境
OS:Windows10
CPU:Core i5-4590

Windows.hはSleep関数を用いるためにインクルードしています。
このように構造体自体のアドレスというのは最初のメンバのアドレスと一致します
そのため、構造体のint型の値を取り出すと、当然最初のメンバの値が出てきます。

しかし、ここで注意したいのはint型(4バイト)で取り出しているこそ同じ値になっているだけで、取り出すサイズが違えば値も異なります
一致しているのはアドレスということに注目してください。

イメージとしてはこのような形です。

f:id:pit-ray:20180712230704j:plain
構造体のメモリ構造イメージ

では今日のまとめです。

構造体のアドレス=最初のメンバのアドレス


・参考文献
c - 構造体のアドレスと構造体の最初のメンバーのアドレスは同一であるとして良いか? - スタック・オーバーフロー