見出し画像

SGDK学習メモ:No.5、kprintf()について、Visual Studio Code+GNUデバッガ(GDB)環境構築手順覚え書き

*以下SGDKは記述時点で最新版のSGDK 2.00 (january 2024)、エミュレータはGens KMod V0.7.3(Gens)使用しています

SGDK学習の際のメモです。

今回は主にGDBを使用したデバッグ環境構築手順についてです。


kprintf()について

SGDKにおいてGensのDebug Messageでログ表示に使用する
KLog()はDeprecated、代わりにkprintf()を使用すること
となっていました。
kprintf()はSGDK 1.70 (february 2022)から導入された関数です。

doc/html/index.html

KLog()は引数がcharのみでしたが、kprintf()はprintf()の様に「フォーマット指定子」(format specifiers)が使用可能です。

以下kprintf()のサンプルです。

char str1[] = "abc";
int num = 123;

KLog(str1);
kprintf(str1);
kprintf("char -> %s , int -> %i",str1,num);
ソースを追ってわかったのですが、
kprintf()は最終的にKLog()を使用していました

ドキュメントには「kprintf()は最大255文字なので注意すること」(意訳)とあります。

u16 kprintf ( const char * fmt,
...
)
(中略)
On success, the total number of characters written (limited to 255 max)
Copy the string pointed by 'fmt' param to KMod console.
(中略)
Note that internally a buffer of 255 characters is allocated so consider this limitation !

doc/html/index.html
一部bold装飾追加

KLog系のメソッド(KDebug log helper methods)は複数存在するのですが(例:KLog_U1())、それらに対してもヘッダーファイル(tools.h)で"deprecated Use kprintf(..) instead"となっています。

GensのDebug Messageは
Tuto Introduction · Stephane-D/SGDK Wiki · GitHub
に記載があるように、”Active Development Features”にチェックが入っていないと表示されません。

GensのメニューのOption → Debug

Visual Studio Code+GNUデバッガ(GDB)環境構築手順覚え書き

*初めてGDBを使用しました、間違い等ありましたらコメントいただけると嬉しいです

SGDKでのデバッグについて調べていたところ

Debug - Genesis Code Documentation

Genesis code, can help you to create a configuration for remote debugging with GDB. With this configuration you can use an emulator like GensKMod or Blastem for open a remote debug session using GDB.

https://zerasul.github.io/genesis-code-docs/debug/

がヒットしました。
「Genesis CodeはGNUデバッガ(GDB)のリモートデバッグ用設定ファイル生成を手助けします。設定ファイルとGDBを使用してGens KModやBlastEm等でデバッグできます」(意訳)
とあります。

以下は
「GDBによってVisual Studio Code(VS Code)上のソースコードに設定したbreakpointでコードが停止できるようになるまで」
の手順の覚書です。
VS Codeのインストール及びVS CodeへのGenesis Codeの導入は終わっていることを前提とします。

事前準備1)
Gensを起動、Option→Debug選択→Debug configuration画面表示、”Active Development Features”(上記kprintf()参照)と”use GDB”にチェックを入れOK押下、一旦Gensを終了させる

*下図では"Single Instance"にチェックが入っていませんが、デバッグ時はチェックを入れたほうが効率が良いです。これにより”Genesis Code: Compile & Run Project”などを実行時、複数のGensが起動しません。

GDB用のポート番号は変更可能ですが上図はデフォルト値、
use GDB有効化によってGens起動時ファイヤーウォールの警告が出る場合があります

事前準備2)
VS Codeの設定画面(Ctrl + ,)でGenesis Code選択、"Gens: Path"にGensを指定

ソースコード等を設置するフォルダを作成、今回は C:\games\dev\gdb_test とする

*以下VS Code操作中に”Do you trust the authors of the files in this folder?”とメッセージが表示されたら”Trust the authors of all files in the parent folder (フォルダー名)”にチェックし”Yes, I trust the authors”押下

VS Codeの言語設定によって英語以外(日本語)でメッセージが表示されると思います(未確認)

VS Codeを起動、起動時に(前回の)既存のフォルダーが開いたらFile → Close Folderでそのフォルダーを閉じる

コマンドパレット(Ctrl + Shift + P)で”Genesis Code: Create Project”を実行、以降の"Genesis Code: XXX"はコマンドパレット実行を意味する

"フォルダーの選択"が表示されるので、先に作成したgdb_testを選択後”フォルダーの選択”ボタン押下


gdb_testフォルダー内にmain.c等のファイルが生成される(後述するlaunch.jsonも生成される)、main.cの"inclue <genesis.h>"で警告が出る場合は環境変数GDKが未設定または指定しているパスが間違っている可能性がある

GDK未設定のために警告の赤い破線が表示されている状態

一度コンパイルして動作確認する、”Genesis Code: Compile & Run Project”実行、動作確認後Gensを終了する

動作確認Gensを終了

デバッグ確認用にmain.c書き換え、Aボタン/Bボタン/Cボタンのいずれかを押下でグローバル変数 int gInt をインクリメントしkprintf()でDebug Messageにメッセージを表示する

#include <genesis.h>

int gInt=0;

void joyHandlerMenu(u16 joy, u16 changed, u16 state)
{
    if (joy == JOY_1)
    {
        if (state & BUTTON_A)
        {
            gInt++;
            kprintf("A Pressed,int value is [%i]",gInt);
        }
        if (state & BUTTON_B)
        {
            gInt++;
            kprintf("B Pressed,int value is [%i]",gInt);
        }
        if (state & BUTTON_C)
        {
            gInt++;
            kprintf("C Pressed,int value is [%i]",gInt);
        }
    }
}

int main()
{

    JOY_setEventHandler(&joyHandlerMenu);

    VDP_drawText("Hello Sega!!", 10,13);
    while(1)
    {
        SYS_doVBlankProcess();
    }
    return (0);
}

デバッグ開始時にbreakpoint以外で停止するのを防ぐため .vscode/launch.jsonの"stopAtEntry"をfalseに書き換える

launch.json修正(*stopAtEntryのみ)

            "stopAtEntry": true,

launch.json修正(*stopAtEntryのみ)

            "stopAtEntry": false,

debug用build前に一度 "Genesis Code: clean" を実行、これによりoutフォルダ以下のファイルが削除される
*cleanは毎回実行する必要はないようです、今回は使用していませんがリソースファイル関連の修正時は必須?

Genesis Code: clean 実行
Genesis Code: clean 実行
outフォルダ以下のファイルが削除された

"Genesis Code: Compile For Debugging”実行、debug用コンパイルが実行される

debugオプション付きでコンパイルが実行される(TERMINALで確認可能)、
具体的には以下のコマンドが実行される
%GDK%\bin\make -f %GDK%\makefile.gen debug

main.cの3つのkprintf()にbreakpointを設定

Aボタン、Bボタン、Cボタン押下時に
実行されるkprintf()にbreakpoint設定

アクティビティーバーの"Run and Debug"またはCtrl+Shift+D押下でサイドバー切り替え、WATCHに"gInt"追加

グローバル変数はVARIABLESに表示されない、
WATCHに手動で追加しておく(もっといいやり方がある?)

debug用コンパイルした out/rom.bin をGensで実行("Genesis Code: Run Project")、Gensが起動したらDebug Messageを表示しておく

先に行った”use DBG”の有効化により待機状態になっているが
この2画面からは待受状態か否かは判別できない(多分)

Start DebbugingボタンまたはF5キー押下でデバッグ開始、デバッグが開始されるとDEBUG CONSOLEにメッセージが表示される
*環境変数GDK未設定だとlaunch.json内の"${env:GDK}"が展開できない=gdb.exeが見つからずにエラーとなります("${env:GDK}"を手動で書き換える対処方法もあります)

Warningが出ていますが動作に問題ないようなので一旦放置、
Gens未起動だとエラーになります(デバッグ用に指定したポートが存在しないため)

GensでA~Cボタンのいずれかを押下、下図はAボタン押下によってbreakpointで処理が止まった状態

breakpointで処理が止まっている状態、
WATCHに追加したgIntも初回インクリメント後で0→1になっていることが確認できる

ContinueボタンまたはF5キー押下で処理続行、kprintf()が実行されDebug Messageにメッセージが表示される

continue押下後、kprintf()が実行されメッセージが表示された

あとは
Step Over : F10キー押下
Step Into : F11キー押下
Step Out : Shift + F11キー押下
となります。


今回VS Codeに慣れていない人向けにスクリーンショット多めにしてみました。

GDB + BlastEmのRemote DebuggingはNightly BuildsBlastEm Windows 64-bitでテストしてみましたがうまく動きませんでした。私のGDBの理解不足から設定等が足りていないのだと思います(と思ったら違っていました、下記追記参照)。
BlastEmのRemoteではないDebugging(-dmオプション)では、コマンドvrでVDPの情報が表示されることは確認できました。


*2024/04/25及び2024/04/26追記
BlastEmのRemote Debuggingも成功しました。
手順は基本的に上記Gens使用時と同じなのですが、異なる点は

1)
launch.jsonの
"miDebuggerServerAddress": "localhost:6868",

"miDebuggerServerAddress": "localhost:1234",
に書き換える(BlastEmはGensの様にポート番号変更できない?)
2)
コマンドプロンプト起動、BlastEmでdebug用コンパイルしたrom.binを-Dオプション付きで実行(例 : 絶対パス\blastem.exe 絶対パス\out\rom.bin -D)
*この時点でBlastEmはタスクバーに表示されない
3)
VS CodeのStart Debugging(F5)実行でBlastEmが起動、Gens同様にbreakpoint、ステップデバッグも可能、kprintf()やKDebug log helper methodsの実行でメッセージ表示用ウインドが自動的に起動する

となります。

BlastEmではメッセージ表示用ウインドが自動的に開くので、
頻繁にメッセージを確認する場合はGensより便利かもしれません
Revision bfd09d3367ba(2024-Apr-16)で
デバッガへのOpenGL対応が入ったのですが、これによって
私の一部マシンでデバッガ起動時にabortするようになりました、
Revision 48ab1e3e5df5(2024-Apr-01)は問題ありません

グラフィックボードのドライバ不具合によりBlastEmの挙動も不安定になり、それに伴ってRemote Debuggingできなくなっていたようです。ドライバを入れ直したところ改善しました。

【了】

この記事が気に入ったらサポートをしてみませんか?