User Tools

Site Tools


blog:pushbx:2023:0205_ldebug_ms_debug_s_command_ldebug_manual_quick_start_tips

lDebug/MS Debug S command, lDebug manual quick start, tips

2023-02-02

Yesterday rr asked about the syntax for the Debug command S (search memory).

I replied that lDebug can search an entire segment using eg s E000:0 l 10000 "DIP" or s E000:0 FFFF "DIP". I also stated that the latter should work in Microsoft's Debug too.

However, he replied that a range from an offset 0 to offset FFFF doesn't work in Microsoft's Debug. Other end values such as 7FFF, FFF0, and even FFFE do work however.

I first suspected that the search mask length may be involved. This is not correct however.

Upon learning that start offset 0 and end offset FFFE worked with a 3-byte search mask, I quickly deduced that Debug doesn't contain special support for range lengths of a full 64 KiB. Because some of the debugger's internal handling uses a 16-bit value as the length, and does not encode it as in "this is the length minus 1" or "a value of zero means 64 KiB", the lengths it can theoretically handle are all unsigned 16-bit numbers, up to FFFFh, including a zero length.

I tested my suspicion by issuing a range of 1 FFFF and… it worked! Looking at the sources of my msdebug recreation (based on the free software MS-DOS v2 release), it became apparent that it specifically detects incrementing a length to 0 and errors out, avoiding needing to special case a 64 KiB length elsewhere.

During the review I also noticed that there is no check for the search range length being at least as large as the search mask length. This makes it not work correctly nor error out on a command like s 0 1 "123". Instead of erroring or returning no result, it acts as if a large length was given.

I found that lDebug does error out for this case, but it will cause an error in the sequence of hack calls (in the next hack-using command like S or D) because the search error is handled after prephack and dohack have already been called. Further, si does not point into the debugger's input line at that point anymore so the error carat display will generally be wrong.

lDebug manual quick start

2023-02-03

This draft is meant to address rr's haste in reading the manual's section on the S command, which did not explain the parameter types referred to as range and list.

Quick start for reading this manual

The interface reference explains the basics of the debugger's interface and lists some common commands.

The parameter reference lists the types of parameters used by the available commands.

The command reference describes most commands in detail.

The expression reference details how numeric parameters are parsed by the expression evaluator.

The variable reference lists a subset of the debugger's variables and what they can be used for.

The interrupt reference lists what interrupt hooks the debugger sets up.

The service reference lists what services are called by the debugger, which may be useful for developers of the debugger, or of kernels, ROM-BIOSes, or DPMI hosts.

The online help pages provide some additional descriptions not found elsewhere in the manual, as well as overviews of many different topics.

The command help lists most of the switches and parameters accepted by the debugger and the instsect program.

The news lists an overview of changes since prior releases of lDebug.

Invoking the debugger states how to start the debugger, either bootloaded, as a device driver, as an application, or through the test suite.

Building the debugger lists components, build options, and instructions on how to build.

Debugging the debugger itself lists some considerations for working with CDebug or DDebug as a debuggee.

The additional usage conditions section lists attribution and licenses for the various depackers that can be used for the compressed debugger executable.

Source Control Revision ID gives the Mercurial hash of the manual's source revision, and links to that revision in ecm's repository.

For a tour, definitely start with the interface reference. To help invoke the debugger read the section on Invoking the debugger as an application. It may help to read the manual while testing the debugger on another terminal. Use the main page of the online help as a reference to what is possible, then check the command reference for details. To explain what parameter types are used refer to the parameter reference. For how to calculate refer to the expression reference.

Reconfiguring the debugger can be done using variables, including the Debugger Assembler Options (DAO) and the Debugger Common Options (DCO) 1 to 6. Use the variable reference and the online help pages on the options for those. Change variables using the R commands, such as r dco or= 800 or r ior := #50.

Some tips:

  • Use the GT or GNT commands to skip past conditionals
  • Use G ABO to skip past calls or loops if P would not work
  • T, P, G, U, and D commands have autorepeat to repeat the same command if an empty line (only blanks) is entered after they return control to the debugger prompt
  • The POINTER type expression allows using a 32-bit number as a 16:16 segmented address whereever an address parameter is parsed
  • The assembler can access the expression evaluator by surrounding an expression with parentheses (…)
  • The A, E, D, and U commands write to the AAO, AEO, ADO, and AUO variables to point past the end of their last read or write
  • The ABO variable points past the last instruction disassembled by an R command
  • Permanent breakpoints can be set up using the B commands, including as pass points or conditionally
  • The G command can repeat the prior list by specifying the AGAIN keyword as the first breakpoint, and can save to the list without actually executing the debuggee by ending the breakpoint list with a REMEMBER keyword
  • T, P, and G commands can change either the instruction pointer only or also the code segment using an equals-sign-prefixed address as the first prameter. The TTEST command will change the CS:IP without actually executing anything.
  • The machine type can be viewed or changed with an M command. Assembly and disassembly will note if a required machine level is absent according to the machine type.
  • DCO option 800 enables the line editor and input history even when using DOS for input
  • DCO6 option 200 will use the ROM-BIOS for output instead of DOS, including for register change highlighting
  • DCO option 8 will act as if the debugger is always running with the InDOS flag set, avoiding DOS calls from the debugger itself
  • The INSTALL AMIS and INSTALL TIMER commands can be used to provide the debugger's AMIS interface and hook the timer interrupt
  • The DW ss:sp command is useful to view the current stack formatted as words
  • The debugger is largely capitalisation-insensitive
  • The LFSR variable allows to generate a stream of pseudo-random numbers
  • The DIM command shows MCB names of blocks pointed to by interrupt vectors, while DIL (or DIML) will query AMIS multiplexers for their interrupt entrypoints to find hidden chains
  • Long output of many commands is paged by default, displaying a [more] prompt that pauses the output until a keypress is received
  • The VALUE IN construct allows to match one numeric value or range against many match values or match ranges
  • A breakpoint can be set up on an interrupt handler by issuing for example BP NEW ptr ri2Dp, if the interrupt handler is writeable
  • If given a single expression the H command displays the result as hexadecimal and as decimal
  • Decimal numbers can be entered with a # prefix, and binary with 2#. Character codes can be used as numbers with #"…"
  • Script files can be run with the Y command
  • A program can be traced until it tries to modify interrupts 1 or 3 using tp FFFFF while ! value from linear 0:1*4 length 3*4 in writing silent. Add a conditional breakpoint like bp new ptr ri21p when value ax in 2501, 2503 beforehand to intercept DOS calls to change these interrupts
  • If at its entrypoint and you want to return from a near function, use g word [ss:sp]. For a 16-bit far or interrupt function use g ptr [ss:sp]
  • In a loop with several exit conditons, trace with T or P and accumulate exits with G AGAIN address REMEMBER (insert an offset or (NOT)TAKEN keywords for the address), then finally run G AGAIN
  • The L and W commands for reading and writing sectors accept drive letters for their second parameter, specified with a trailing colon
  • The RV, RVM, RVP, and RVD commands will show some information on modes, memory segment locations, processes, and device headers
  • RX toggles the 32-bit register view for the R command
  • The RE buffer can contain many different commands, which are run on RE commands or when T, P, or G initiate a register dump
  • The DCO options are described in the full ?O help page as well as individual pages like ?O6 for DCO6
  • Not sure what version of lDebug is running? The command ?BUILD displays the description and source control revision IDs. The description includes a build date or release number.
  • Setting a breakpoint at the current instruction pointer with the G command will trace past this instruction once then write the breakpoint and run at full speed
  • There's a TSR mode converting the application-mode debugger into a resident program, allowing to debug the debugger's parent process
  • The symbolic F register for the R command allows dumping and modifying the flags using the abbreviated flag states
  • The R command can modify variables using binary operators suffixed by an equal sign, both on the command line of the R command as well as after the R variable prompt
  • By adding a trailing dot after a variable name for the R command, a variable's value can be inspected without bringing up a variable prompt that requires submitting a second input line
You could leave a comment if you were logged in.
blog/pushbx/2023/0205_ldebug_ms_debug_s_command_ldebug_manual_quick_start_tips.txt · Last modified: 2023-02-05 17:12:17 +0100 Feb Sun by ecm