Forum > Debugger

Display of bitpacked arrays in the debugger

(1/2) > >>

440bx:
Hello,

What the debugger shows for a bitpacked array of boolean isn't what I'm expecting and, I'm wondering if I am missing/misinterpreting something.

The debugger's DRIVEMAP shows true(205), false, false, true(2), true(2), etc.

I cannot figure out what the "205" and the "2"s mean.

Also, I expected the DRIVEMAP to show: true, false, true, true... etc (see the black screenshot output)
but the debugger shows an extra "false" between the first two instances of true. 

Am I missing something or is there something wrong in what is displayed by the debugger ?

The program that produces those results is : (hover over the "ProcessDeviceMapData" parameter after the call to the Nt... function - parameter line is highlighted.)
--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{$APPTYPE      CONSOLE} {$TYPEDADDRESS ON} program _QueryInformationProcess;  uses  Windows,  sysutils  ; {$ifdef VER90}type  DWORD = longint;  PDWORD = ^DWORD;{$endif} type  NTSTATUS = DWORD;  const   { 17   23 } ProcessDeviceMap = 23;  { PROCESS_DEVICEMAP_INFORMATION        }                                       { PROCESS_DEVICEMAP_INFORMATION_EX     }   ntdll = 'ntdll';   PROCESS_ALL_ACCESS        = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $FFFF;   STATUS_SUCCESS            = 0;  function NtQueryInformationProcess(ProcessHandle            : THANDLE;                                   ProcessInformationClass  : DWORD;                                   ProcessInformation       : pointer;                                   ProcessInformationLength : DWORD;                                   ReturnLength             : PDWORD)         : NTSTATUS; stdcall; external ntdll;  function IsDebuggerPresent {$ifdef FPC} () {$endif}       : BOOL; stdcall external kernel32;  function _itoa             (              { _in_  } In32bitInteger  : integer;              { _out_ } OutAsciizString : pchar;              { _in_  } InRadix         : DWORD             )         : pchar; cdecl external ntdll;                            { !! CDECL }  type  { _PROCESS_DEVICEMAP_INFORMATION                                            }   PPROCESS_DEVICEMAP_INFORMATION = ^TPROCESS_DEVICEMAP_INFORMATION;  TPROCESS_DEVICEMAP_INFORMATION = record    case integer of      {$ifdef WIN64}      0 : (           { record size must be a multiple of 16 in 64bit                    }            ForceSize                 : packed array[0..5] of pointer;          );      {$endif}       1 : (           SetMap                    : record             DirectoryHandle             : THANDLE;           end;          );       2 : (           QueryMap                  : record             DriveMap                    : DWORD;             DriveType                   : packed array[0..31] of byte;           end;          );      {$ifdef FPC}      3 : (           BitMap                    : record             DriveMap                    : bitpacked array[0..31] of boolean;             DriveType                   : packed array[0..31]    of byte;           end;          );      {$endif}  end; var  ProcessHandle                   : THANDLE;   ProcessDeviceMapData            : TPROCESS_DEVICEMAP_INFORMATION;    BufferSize    : DWORD;   ReturnLength  : DWORD;   Status        : NTSTATUS;    itoa_buf      : packed array[0..127] of char;  begin  writeln;   // since we are dealing with our own process we can specify PROCESS_ALL_ACCESS   ProcessHandle := OpenProcess(PROCESS_ALL_ACCESS,                               FALSE,                               GetCurrentProcessId());   if ProcessHandle = 0 then Halt(1);     writeln;    writeln;    writeln('  ProcessDeviceMap : ', ord(ProcessDeviceMap), ' (d) ',               IntToHex(ord(ProcessDeviceMap), 0), ' (h)');     BufferSize   := sizeof(ProcessDeviceMapData);    ReturnLength := 0;     writeln;    writeln;    writeln('  Buffer size : ', BufferSize);     ZeroMemory(@ProcessDeviceMapData, sizeof(ProcessDeviceMapData));     if IsDebuggerPresent then DebugBreak();    Status := NtQueryInformationProcess(ProcessHandle,                                        ProcessDeviceMap,                                       @ProcessDeviceMapData,                                        BufferSize,                                       @ReturnLength);     if IsDebuggerPresent then DebugBreak();    if Status <> STATUS_SUCCESS then    begin      writeln;      writeln;      writeln('  NtQueryInformationProcess failed.  NTSTATUS : ',                 IntToHex(Status, 0));    end;      writeln;    writeln;     writeln('  ', _itoa(ProcessDeviceMapData.QueryMap.DriveMap, itoa_buf, 2));    writeln;    writeln('  returned length : ', ReturnLength);   writeln;  writeln('Press <enter>/<result> to end this program.');  readln;end. 
Thank you for your help.

Martin_fr:
Which Debugger?

Last time I tested, GDB had issues with packed data. That needs to be fixed in gdb (not yet tested gdb 10, but that has other issues)

FpDebug: not sure about 2.0.x
But in trunk it works.  Though for the hint, it shortens the embedded arrays.

--- Code: ---ForceSize: ($03030300020227DE, $0005020202020003, $0000030000000300, $0000030000000000, nil, nil)
SetMap: {record} (217020505612494814)
QueryMap: {record} (33695710;
 (0, 3, 3, {29 more elements}))
BitMap: {record} ((False, True, True, {29 more elements});
 (0, 3, 3, {29 more elements}))

--- End code ---

A watch on ProcessDeviceMapData.BitMap

--- Code: ---DriveMap: (False, True, True, True, True, False, True, True, True, True, {22 more elements})
DriveType: (0, 3, 3, 3, 3, 0, 2, 2, 2, 2, {22 more elements})

--- End code ---

And if you enter ProcessDeviceMapData.BitMap.DriveMap you see the data.

You can open ProcessDeviceMapData in "inspect dialog" (afaik Alt F5), then click through the path, and (in latest trunk) hit the "add watch" button.


---
I did recently notice that packed sets do not yet work in FpDebug.

Martin_fr:
Note that it may not be entirely gdb's fault (though I think it happens with fpc trunk and gdb too)

https://bugs.freepascal.org/view.php?id=36144 (and maybe others)
Not sure in which version that was fixed.

However, IIRC FpDebug works around that. So FpDebug should work with older fpc too.

MarkMLl:
What's generating the Boolean? If it's C then it might be assuming that non-zero is universally recognised as true, and the debugger's alerting you to the fact.

Some of my own code has arrays or bytebools (?), and yesterday I noticed that the numeric value was either 0 or 255.

MarkMLl

440bx:

--- Quote from: Martin_fr on June 04, 2021, 12:26:30 pm ---Which Debugger?

--- End quote ---

sorry, I forgot to mention the debugger version, it is v7.2 (old version but, it usually works well for what I do)


--- Quote from: Martin_fr on June 04, 2021, 12:26:30 pm ---Last time I tested, GDB had issues with packed data. That needs to be fixed in gdb (not yet tested gdb 10, but that has other issues)
--- End quote ---
I've experienced a few issues with GDB and bitpacked data but, this one was different than the ones I've seen in the past.  Thought I'd ask just in case.

I really have to check out FpDebug sometime and, a newer version of Lazarus than the one I'm using.  The output you showed looked enticing :)



--- Quote from: MarkMLl on June 04, 2021, 12:33:11 pm ---What's generating the Boolean? If it's C then it might be assuming that non-zero is universally recognised as true, and the debugger's alerting you to the fact.
--- End quote ---
It's C but, it is a bitmap returned in a DWORD.  It's the same DWORD returned by GetLogicalDrives (GetLogicalDrives calls that NT function get the DWORD it returns.)  It's not an array of bytebool it's definitely a bit array (as _itoa showed.)


Navigation

[0] Message Index

[#] Next page

Go to full version