Forum > Debugger
Display of bitpacked arrays in the debugger
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