Commit graph

62 commits

Author SHA1 Message Date
Hermès Bélusca-Maïto
b15dcb5cf6
[NTOS:KD64] The DbgKdPageInApi, introduced in NT4, has been obsoleted in NT5.
It has been replaced by ExpDebuggerPageIn support in ExpDebuggerWorker().
2024-12-14 23:33:53 +01:00
Hermès Bélusca-Maïto
c53eb190c7
[NTOS:KD64] Revamp the debugger banner helpers a little.
- Directly call KdpGetMemorySizeInMBs() within KdpPrintBanner(),
  instead of having the caller doing it.
- Use the miarm.h MiIsMemoryTypeInvisible() helper.
- Add Doxygen comments.
2024-12-14 23:31:47 +01:00
Hermès Bélusca-Maïto
cb0c9a4570
[NTOS:KD64] KdInitSystem(): Minor code enhancements.
- Move local variables to the code blocks where they are used.
- if-s one-line bodies on their own lines.
- Massage the boot-images symbols loading, using a for-loop.
2024-12-14 23:31:46 +01:00
Hermès Bélusca-Maïto
6cf426345b
[NTOS:KD64] Use KdpDprintf() instead of DbgPrint() for the debugger banner DPRINTs (#7540)
Override DbgPrint(), used by the debugger banner DPRINTs,
because KdInitSystem() can be called under the debugger lock
by KdEnableDebugger(WithLock)().

In this case, when DbgPrint() (re-)enters the debugger via an
interrupt and acquires the debugger lock, a deadlock occurs.
2024-12-03 22:14:02 +01:00
Hermès Bélusca-Maïto
1a02d3306b
[NTOS:KD64] Fix usage of the debugging banner code, based on when KdInitSystem() is called (#7540)
- The debugging banner helpers *CANNOT* be in the INIT section, because
  it is possible for KdInitSystem() to enable the debugger **MUCH LATER**
  after boot time. (Reverts part of commit f239ca0f0 (r72922).)

  This can happen in two situations:

  * When the debugger is in CRASHDEBUG mode, i.e. initialized at boot
    time but not immediately enabled, and a BSOD happens later that
    enables the debugger with a `KdInitSystem(0, NULL)` call.

  * When the debugger was possibly manually disabled with a
    KdDisableDebugger() call, then later re-enabled with a
    KdEnableDebugger() call.

- In the same cases as described above, the KeLoaderBlock is freed after
  boot time. Thus, KdpGetMemorySizeInMBs() cannot use it and enumerate
  the MemoryDescriptors to evaluate the number of physical memory pages
  available on the system. Instead, we can use what the memory manager
  has already computed, since the latter is already initialized by now.

These two fixes avoid (invisible) crashes when (re-)enabling
the debugger at non-boot run time.
2024-12-03 22:13:57 +01:00
Hermès Bélusca-Maïto
76d35dde1d
[NTOS:KD64] KdInitSystem(): Poll for break-in on symbol load *ONLY* at boot-time (#7539)
I.e. when LoaderBlock != NULL and we have loaded the initial hal and
ntoskrnl symbols. KdBreakAfterSymbolLoad is then checked for when the
other boot symbols have been loaded by ex/init.c!ExpLoadBootSymbols(),
invoked by ExpInitializeExecutive().
2024-12-03 19:29:12 +01:00
Hermès Bélusca-Maïto
2995806a44
[NTOS:KD64] kdx64.c: Implement KdpAllowDisable() the same as in x86 (#7538)
AMD64 has the same DR7 register as x86 with the same bits meanings,
thus the same implementation can be used.

References:

- https://en.wikipedia.org/wiki/X86_debug_register#DR7_-_Debug_control

- AMD64 Architecture Programmer’s Manual, Volume 2: System Programming
  https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf
  Section "13.1.1.4 Debug-Control Register (DR7)"
  pgs. 393-396 (pgs. 455-458 of the PDF)

- Intel® 64 and IA-32 Architectures Software Developer’s Manual,
  Volume 3 (3A, 3B, 3C, & 3D): System Programming Guide
  https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
  Section "19.2.4 Debug Control Register (DR7)" (pgs. 644-646)
  Section "19.2.6 Debug Registers and Intel® 64 Processors" (pg. 647)
2024-12-03 19:02:28 +01:00
Hermès Bélusca-Maïto
61feb649d1
[NTOS:KD64] kdx86.c: Fix Dr7 check to verify whether debugger disabling is allowed (#7538)
Don't check the whole Dr7 value, but only the first 8 bits that
correspond to the local/global enable breakpoints.

We cannot check the whole value because some of the Dr7 bits are
reserved always set to 1 (bit 10), or describe other debug state.

References:

- https://en.wikipedia.org/wiki/X86_debug_register#DR7_-_Debug_control

- Intel® 64 and IA-32 Architectures Software Developer’s Manual,
  Volume 3 (3A, 3B, 3C, & 3D): System Programming Guide
  https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
  Section "19.2.4 Debug Control Register (DR7)" (pgs. 644-646)
2024-12-03 19:02:21 +01:00
Hermès Bélusca-Maïto
edb6d19aa8
[NTOS:KD64] Only use the UNIMPLEMENTED macro in the debugger's KdpSys* helpers.
This basically avoids re-entering the debugger (via the embedded breakpoint)
while we are already running within its context.

In addition, this allows the tests for Kd/NtSystemDebugControl
(see PRs #7424 and #7426) to run without having ReactOS to crash.
2024-11-21 22:34:37 +01:00
Hermès Bélusca-Maïto
842e40d7cd
[NTOS:KDBG] Minor code style for the following commits 2024-10-14 22:51:51 +02:00
Timo Kreuzer
72fd54a7f4 [NTOS:KE/x64] Implement Kd processor switching 2024-04-23 15:50:06 +02:00
Hermès Bélusca-Maïto
579eab8a31
[NTOS] Include kdbg/kdb.h only in the files that really need it. 2023-04-11 00:44:10 +02:00
Hermès Bélusca-Maïto
9d9536d431
[NTOS:KD64] Format string of KdpDprintf can be const. 2023-03-22 19:57:59 +01:00
Hermès Bélusca-Maïto
f7024d6c72
[PSDK][NTOS:KD64] Turns out, that even Clang in MSVC mode needs the 64-bits pointer extension hack!
Addendum to commit de81021ba.
Otherwise, we get the following build error:

 \ntoskrnl\kd64\kddata.c(532,5): error: initializer element is not a compile-time constant
      PtrToUL64(RtlpBreakWithStatusInstruction),
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 \ntoskrnl\kd64\kddata.c(526,26): note: expanded from macro 'PtrToUL64'
 #define PtrToUL64(x)    ((ULPTR64)(x))
                          ^~~~~~~~~~~~
2022-11-24 13:30:43 +01:00
Hermès Bélusca-Maïto
ffb05406e6
[NTOS:KD64] Implement KdLogDbgPrint() for the WinDbg !dbgprint command.
See this command's documentation:
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-dbgprint
and the section "DbgPrint buffer and the debugger"
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/reading-and-filtering-debugging-messages#dbgprint-buffer-and-the-debugger
for more details.

- Loosely implement the function, based on our existing circular printout
  buffers in kdio.c.
- Enable its usage in the KdpPrint() and KdpPrompt() functions.

Notice that this function will *only* capture the strings being sent **to**
the debugger, and not the strings the debugger itself produce. (This means
that we cannot use the KdPrintCircularBuffer as a replacement for our
KDBG dmesg one, for example...)

How to test:
Run ReactOS under WinDbg, and use the !dbgprint command to view the
buffer. You can also use the Memory Window, place yourself at the
address pointed by KdPrintCircularBuffer and KdPrintWritePointer, and
read its contents.

What you should observe:
Prior notice: The circular buffer in debug builds of ReactOS and Windows
is 0x8000 bytes large. In release builds, its size is down to 0x1000.
1- When you start e.g. the 2nd-stage GUI installation of ReactOS, going
   past the initial "devices installation" and letting it stabilize on
   the Welcome page, break into WinDbg and run the !dbgprint command. You
   should notice that the end of its output is weirdly truncated, compared
   to what has been actually emitted to the debug output. Comparing this
   with the actual contents of the circular buffer (via Memory Window),
   shows that the buffer contents is actually correct.
2- Copy all the text that has been output by the !dbgprint command and
   paste it in an editor; count the number of all characters appearing +
   newlines (only CR or LF), and observe that this number is "mysteriously"
   equal to 16384 == 0x4000.
3- Continue running ReactOS installation for a little while, breaking back
   back into WinDbg and looking at !dbgprint again. Its output seems to be
   still stopping at the same place as before (but the actual buffer memory
   contents shows otherwise). Continue running ROS installation, and break
   into the debugger when ROS is about to restart. You should now observe
   that the dbgprint buffer rolled over:
     dd nt!KdPrintRolloverCount shows 1.
   Carefully analysing the output of !dbgprint, however, you will notice
   that it looks a bit garbage-y: the first part of the output is actually
   truncated after 16384 characters, then you get a second part of the
   buffer showing what ReactOS was printing while shutting down. Then
   you get again what was shown at the top of the !dbgprint output.
   (Of course, comparing with the actual contents of the circular buffer
   in memory shows that its contents are fine...)

The reason of these strange observations, is because there is an intrinsic
bug in the !dbgprint command implementation (in kdexts.dll). Essentially,
it displays the contents of the circular buffer in two single dprintf()
calls: one for the "older" (bottom) part of the buffer:
  [WritePointer, EndOfBuffer]
and one for the "newer" (upper) part of the buffer:
  [CircularBuffer, WritePointer[ .
The first aspect of the bug (causing observation 3), is that those two
parts are not necessarily NULL-terminated strings (especially after
rollover), so for example, displaying the upper part of the buffer, will
potentially also display part of the buffer's bottom part.
The second aspect of the bug (explaining observations 1 and 2), is due
to the implementation of the dprintf() function (callback in dbgenv.dll).
There, it uses a fixed-sized buffer of size 0x4000 == 16384 characters.
Since the output of the circular buffer is not done by little chunks,
but by the two large parts, if any of those are larger than 0x4000 they
get truncated on display.
(This last observation is confirmed in a completely different context by
https://community.osr.com/discussion/112439/dprintf-s-max-string-length .)
2022-11-24 01:18:18 +01:00
Hermès Bélusca-Maïto
36335d9cee
[NTOS:KD64] Correctly initialize the KdPrint buffer data in KdDebuggerDataBlock so as to fix the WinDbg !dbgprint command.
Now, !dbgprint just shows an empty log (since we don't fill it), instead
of showing the following error:

  kd> !dbgprint
  Can't find DbgPrint buffer
2022-11-24 01:18:17 +01:00
Hermès Bélusca-Maïto
de81021bab
[PSDK][NTOS:KD64] Rename GCC_ULONG64 to ULPTR64 to self-document the fact it stores a pointer as a 64-bit quantity.
But the underlying GCC stupidity is still there (15 years later).

However, enable it only in 32-bit GCC builds, not in 64-bits nor with MSVC.
See commit b9cd3f2d9 (r25845) for some details.

GCC is indeed still incapable of casting 32-bit pointers up to 64-bits,
when static-initializing arrays (**outside** a function) without emitting
the error:

  "error: initializer element is not constant"

(which might somehow indicate it actually tries to generate executable
code for casting the pointers, instead of doing it at compile-time).

Going down the rabbit hole, other stupidities show up:

Our PVOID64 type and the related POINTER_64 (in 32-bit archs), or the
PVOID32 and POINTER_32 (in 64-bit archs), are all silently broken in
GCC builds, because the pointer size attributes __ptr64 and __ptr32,
which are originally MSVC-specific, are defined to nothing in _mingw.h.
(And similarly for the __uptr and __sptr sign-extension attributes.)

Clang and other sane ompilers has since then implemented those (enabled
with -fms-extensions), but not GCC. The closest thing that could exist
for GCC is to do:

  #define __ptr64 __attribute__((mode(DI)))

in order to get a 64-bit-sized pointer type with

  typedef void* __ptr64 PVOID64;

but even this does not work, with the error:

  "error: invalid pointer mode 'DI'"
2022-11-24 01:18:16 +01:00
Hermès Bélusca-Maïto
1c0950b557
[PSDK][NTOS:KD64] Update the KDDEBUGGER_DATA64 structure with new fields.
Information from the Windows 10 SDK and from
https://github.com/DarthTon/Blackbone/blob/master/src/BlackBoneDrv/NativeStructs.h
2022-11-24 01:18:15 +01:00
Hermès Bélusca-Maïto
98e585364b
[NTOS:KD] Annotate KdInitSystem and remove redundant declaration in kd.h 2022-11-18 18:11:29 +01:00
Hermès Bélusca-Maïto
6e9ff14e26
[NTOS:KD64,KE] IRQL is automatically adjusted during calls to KdEnterDebugger() and KdExitDebugger(). (#3942)
Addendum to 608032bd and 835c3023.

The IRQL is actually raised by KeFreezeExecution() and lowered by
KeThawExecution(), always to HIGH_IRQL on MP systems, or if necessary
on UP. These functions are called respectively by KdEnterDebugger()
and KdExitDebugger().
2021-09-12 18:20:32 +02:00
Hermès Bélusca-Maïto
05590079cc
[NTOS:KD64] First unlock the KD port then lower the IRQL, instead of doing the reverse. (#3942)
This properly reverses the operation of first raising the IRQL before
locking the KD port.
2021-09-12 18:19:59 +02:00
Hermès Bélusca-Maïto
c9f335e996
[NTOS:KD64] KdPollBreakIn(): Use the KeRestoreInterrupts() inline. 2021-09-12 18:16:13 +02:00
Jérôme Gardou
835c30232e [NTOS:KD][NTOS:KD64][NTOS:KDBG] Fix IRQL & spinlock use
KD64: Raise to HIGH_LEVEL when entering trap
KDBG: lower to DISPATCH_LEVEL when applying IRQL hack & use a worker thread to load symbols
KD&KDBG: Actually unload symbols when required
2021-06-29 11:49:20 +02:00
Jérôme Gardou
608032bd08 [NTOS:KD64][NTOS:KDBG] Fix spinlocks use
Raise IRQL before entering debugger, so that KeAcquireSpinLockAtDpcLevel works as expected.
 - HIGH_LEVEL since we don't know where we are coming from.

Do not try to read debug symbol from files in KDBG.
 - There is no reason that this works if Mm didn't map it in the first place.
2021-06-29 11:49:20 +02:00
Thomas Faber
2858ff53ce
[NTOS:KD] Avoid large stack buffer in KdpPrint. CORE-17215 2020-11-27 10:31:45 +01:00
Hervé Poussineau
d6d5caec7c [NTOS:KD] Move some KDBG-specific variables to KDBG-specific file 2020-11-16 08:55:04 +01:00
Hervé Poussineau
0c76bbfe98 [NTOS:KD] Merge KdpReportExceptionStateChange() with kd64 version 2020-11-16 08:55:04 +01:00
Hervé Poussineau
95faf65ebf [NTOS:KD] Remove useless variables/members
Those where only set and never read.
2020-11-16 08:55:03 +01:00
Hervé Poussineau
8d3a395101 [NTOS:KD] Remove Bochs port debugging
You can use serial port debugging instead.
2020-11-16 08:55:03 +01:00
Hervé Poussineau
8a62f277d8 [NTOS:KD] Remove useless implementation of BREAKPOINT_PRINT in KdSystemDebugControl
This is (as expected) handled in KdpTrap(), which also calls KdpPrint().
2020-11-16 08:55:03 +01:00
Hervé Poussineau
1eda7d7e99 [NTOS:KD] Merge KdpReportCommandStringStateChange() with kd64 version 2020-11-16 08:55:03 +01:00
Hervé Poussineau
6f7835d30c [NTOS:KD] Merge KdpReportLoadSymbolsStateChange() with kd64 version 2020-11-16 08:55:03 +01:00
Hervé Poussineau
e31be4ec25 [NTOS:KD] Merge KdEnableDebuggerWithLock()/KdDisableDebuggerWithLock() with kd64 version 2020-11-16 08:55:03 +01:00
Hervé Poussineau
ebb6f29e69 [NTOS:KD] Merge KdEnterDebugger()/KdExitDebugger() with kd64 version 2020-11-16 08:55:03 +01:00
Hervé Poussineau
81b184741d [NTOS:KD] Remove useless uses of _WINKD_ 2020-11-16 08:55:03 +01:00
Hervé Poussineau
329b9fa2fb [NTOS:KD] Merge KdpReport() with kd64 version 2020-11-16 08:55:03 +01:00
Hervé Poussineau
a8662c73a5 [NTOS:KD] Merge KdpTrap() with kd64 version 2020-11-16 08:55:03 +01:00
Hervé Poussineau
5730394bd0 [NTOS:KD] Merge KdpPrintString()/KdpPromptString() with kd64 version 2020-11-16 08:55:03 +01:00
Hervé Poussineau
d5fe15e5e6 [NTOS:KD] Merge KdpStub with kd64 version 2020-11-16 08:55:03 +01:00
Hervé Poussineau
660948ce6f [NTOS:KD] Merge some more functions with kd64
Functions are KdIsThisAKdTrap, KdUpdateDataBlock, KdEnterDebugger,
KdExitDebugger, KdRefreshDebuggerNotPresent, KdDisableDebugger,
KdEnableDebuggerWithLock, KdEnableDebugger, KdSystemDebugControl
2020-11-16 08:55:03 +01:00
Hervé Poussineau
d0e2fada23 [NTOS:KD] Rename KdpEnterDebuggerException to KdpTrap + add KdpStub forwarder
This removes somes uses of _WINKD_ macro.
2020-11-16 08:55:02 +01:00
Hervé Poussineau
4d84c856ad [NTOS:KD] Merge KdInitDebugger with kd64 version + move variable declarations to kd64/kddata.c
Remove now unused file kd/kdinit.c
2020-11-16 08:55:02 +01:00
Hervé Poussineau
6025df33a5 [NTOS:KD] Make implementation of KdInitSystem more similar with the kd64 one
Move some kd initializations into KdDebuggerInitialize0() function.
2020-11-16 08:55:02 +01:00
Hervé Poussineau
f417a53743 [NTOS:KD] Compile all kd64 files in kdbg mode 2020-11-16 08:55:02 +01:00
Hervé Poussineau
e09554a06c [NTOS:KD] Merge KdPowerTransition/KdChangeOption with kd64 version 2020-11-16 08:55:02 +01:00
Hervé Poussineau
b18529de28 [NTOS:KD] Merge KdPollBreakIn() with kd64 version 2020-11-16 08:55:02 +01:00
Victor Perevertkin
5c7ce4475e
[REACTOS] Cleanup INIT and some PAGE section allocations
- Change INIT_FUNCTION and INIT_SECTION to CODE_SEG("INIT") and DATA_SEG("INIT") respectively
- Remove INIT_FUNCTION from function prototypes
- Remove alloc_text pragma calls as they are not needed anymore
2020-11-02 21:45:31 +03:00
Hermès Bélusca-Maïto
ceb58c821a [NTOS][SDK] Add new kernel debug filters that have been added in Win8 and Win10; they can be useful for us. 2020-07-18 17:45:40 +02:00
Jérôme Gardou
0b5033e2ff [NTOSKRNL] Fix build 2020-03-30 07:36:30 +00:00
Victor Perevertkin
b6e33426bf [NTOS:KD] Fix wrong debug level checking logic in KdpPrint.
Use NtQueryDebugFilterState in that function for consistency.
Thanks Hermès Bélusca-Maïto for help
2019-12-30 05:57:49 +02:00