FreePascalのコンソールアプリで、デバッグするときにメモリダンプするユーティリティがほしかったので、ChatGPTにざっくり書いてもらって少し手直しして使っている。
コード
memory_dump.pp:
program memory_dump; uses SysUtils; procedure DumpMemory(addr: Pointer; size: Integer); var i, j: Integer; p: PByte; asciiLine: string; begin p := PByte(addr); for i := 0 to (size div 16) - 1 do begin // 16バイトずつ表示 Write(Format('%p ', [Pointer(p)])); // メモリアドレスを表示 asciiLine := ''; // ASCII表現の行 // 16バイト分のデータを表示 for j := 0 to 15 do begin Write(Format('%02x ', [p^])); // 16進数で表示 if (p^ >= 32) and (p^ <= 126) then asciiLine := asciiLine + Chr(p^) // 表示可能なASCII文字を保存 else asciiLine := asciiLine + '.'; // 表示できない文字は '.' に置換 Inc(p); end; // ASCII表現を表示 WriteLn(' ', asciiLine); end; // 残りのバイトがある場合 if (size mod 16) <> 0 then begin Write(Format('%p ', [Pointer(p)])); // メモリアドレスを表示 asciiLine := ''; // ASCII表現の行 // 残りのバイトを表示 for j := 0 to (size mod 16) - 1 do begin Write(Format('%02x ', [p^])); if (p^ >= 32) and (p^ <= 126) then asciiLine := asciiLine + Chr(p^) else asciiLine := asciiLine + '.'; Inc(p); end; // 残り部分の整列 for j := (size mod 16) to 15 do Write(' '); // ASCII表現を表示 WriteLn(' ', asciiLine); end; end; var testData: array[0..31] of Byte; i: Integer; begin // ダミーデータの初期化 for i := 0 to High(testData) do testData[i] := i + 32; // メモリダンプの実行 DumpMemory(@testData, SizeOf(testData)); end.
コンパイル
$ fpc memory_dump.pp
実行結果
$ ./memory_dump 000000000047D530 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F !"#$%&'()*+,-./ 000000000047D540 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 0123456789:;<=>?
メモリアドレスの表示とascii出力があるので、ポインタのアドレス探しつつ... みたいなデバッグで役に立ちました。 このprocedure自体は、そのままDelphiでも使えそう。