User Tools

Site Tools


blog:pushbx:2026:0825_extensions_for_ldebug_comparison_eldcomp_debugging

Extensions for lDebug comparison (eldcomp) debugging

I tried out the eldcomp Extension for lDebug recently to verify that the updated alias Extension for lDebug doesn't contain any observable bugs.

Bugs found in and with eldcomp

I found six discrepancies around the use of eldcomp this week:

  • eldcomp didn't hash the entirety of the ELD data block, due to a bug in the date time stamp handling introduced on 2024-05-22, so it was useless for detecting relocation errors in the data block. I noticed because the checksum didn't change between a test that installed alias.eld without defining any aliases and one that included an ALIAS RUN rvm command. Fixed now in the experimental repo.
  • The date time stamps recorded the build date time down to seconds granularity, so if the XLD and ELD build happened to run at times differing by one second then a false positive of a data block difference would occur. Fixed by patching eldcomp to zero out the seconds of the detected stamp (overwriting them with the text "00") before hashing the data block.
  • The library ELDs (extlib.eld, extpak.eld, and mcplib.eld) show up with differences in the data block that are likely the offsets in their library tables.
  • rcexec.eld doesn't work as expected under eldcomp, probably because the injected commands take precedence over running the RC buffer commands. However, eldcomp doesn't find any differences between the XLD and ELD.
  • tsc.eld stores the current Time Stamp Counter, which naturally differs between the XLD and ELD run.
  • reserve.eld preserves 256 bytes read from part of line_in (overflowing at the end) to allow it to operate on its commands during injecting various commands of its own. eldcomp didn't initialise the tail of line_in, leading to bogus data block differences. Fixed by having eldcomp clear the entirety of line_in + 1 (256 bytes) with all-zeroes first, then copy over only the defined command contents rather than an entire 256 bytes.

The eldcomp setup

Create a serial port that is attached to a socat instance whose Linux end is named /tmp/vptty-linux: (The trace.log file is used by tractest for TracList.)

socat -r /tmp/trace.log pty,link=/tmp/vptty-dos,rawer pty,link=/tmp/vptty-linux,rawer & disown
picocom /tmp/vptty-linux

Connect the DOS end to dosemu2 like so: (We're using COM2 because that is the default for lDebug's serial I/O feature, which goes back to Public Domain ZModem using COM2 by default.)

~/local.new/bin/dosemu -I "serial { com 2 device /tmp/vptty-dos }"

With the debugger running, connect to the dosemu2 serial port:

install serial

Prepare the debugger with two more commands as suggested in the manual:

install nofreeoneshot
uninstall paging

To store the test results to a file written to the Linux file system using dosemu2's mfs redirector, use the Copy Output Extension for lDebug, like so:

ext co.eld install
co name 20260825.1

Use a perl scriptlet to extract the commands and the sendser.pl script to send the commands to the debugger:

ldebug/source$ perl -ne '
  if (/test (?:install|run) command:\s*(.*)$/) {
    my $command = $1;
    $ARGV =~ /eld\/(.*)\.asm/;
    my $base = $1;
    print "ext eldcomp.eld ext $base.xld $command; ext reclaim.eld; ext $base.eld $command; ext reclaim.eld\n";
  }' eld/*.asm |
  ~/proj/symscr/sendser.pl --bytesleep=0.01 --sleepduration=4 > /tmp/vptty-linux

The sendser.pl script:

#! /usr/bin/perl

# lDebug commands to serial send program
#  by C. Masloch, 2019
#
# Usage of the works is permitted provided that this
# instrument is retained with the works, so that any entity
# that uses the works is notified of this instrument.
#
# DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.

use warnings;
use strict;

use Time::HiRes;
use Getopt::Long;

our $sleepduration = 0.008;
our $bytesleep = 0.0;
my $byte;

GetOptions(
	'sleepduration=f' => \$sleepduration,
	'bytesleep=f' => \$bytesleep,
) or die;

$| = 1;
LINE:
  while (<>) {
    Time::HiRes::sleep($sleepduration);
    s/[\n\r]+/\r/;
    if ($bytesleep != 0.0) {
      foreach $byte (split //, $_) {
        Time::HiRes::sleep($bytesleep);
        print($byte);
      }
    }
  } continue {
    if ($bytesleep == 0.0) {
      print or die "-p destination: $!\n";
    }
  }

It uses the perl $| variable, also called $OUTPUT_AUTOFLUSH, to flush the perl output after every byte written. As stated on the perldoc page, "Mnemonic: when you want your pipes to be piping hot."

Finally, close the file using a Copy Output ELD command to the debugger, so that further testing results aren't appended to the log file:

co close
You could leave a comment if you were logged in.
blog/pushbx/2026/0825_extensions_for_ldebug_comparison_eldcomp_debugging.txt · Last modified: 2026-08-25 16:51:53 +0200 Aug Tue by ecm