Title and Contents

Appendixes

Appendix 1—Debugger Variables

The debugger has the following predefined variables. Conventionally, a Ladebug debugger variable name is an identifier with a leading dollar sign ($).

Variable
Default Setting
Description
$aggregatedmsghistory
0
Controls the length of the aggregated message list. If set to the default (0), the debugger records as many messages as the system will allow.
$ascii
1
Prints ASCII or all ISO Latin-1.
$beep
1
Beeps on illegal command line editing.
$catchexecs
0
Stops execution on program exec.
$catchforkinfork
0
Notifies you as soon as the forked process is created (otherwise you are notified when the call finishes).
$catchforks
0
Notifies you on program fork and stops child.
$childprocess
0
When the debugger detects a fork, it assigns the child process ID to $childprocess.
$curevent
0
Displays the current breakpoint number.
$curfile
(null)
Displays the current source file.
$curfilepath
(null)
Displays the current source file access path.
$curline
0
Displays the current source line.
$curpc
0
Displays the current point of program execution.
$curprocess
0
Displays the current process ID.
$cursrcline
0
Displays the last source line at end of the most recent source listing.
$cursrcpc
0
Displays the PC address at end of the most recent machine code listing.
$curthread
0
Displays the current thread ID.
$dbxoutputformat
0
Displays various data structures in dbx format.
$dbxuse
0
Replaces current use paths.
$decints
0
Displays integers in decimal radix.
$doverbosehelp
1
Displays the help menu front page.
$editline
1
Enables command line editing.
$eventecho
1
Echoes events with event numbers.
$exitonterminationofprocesswithpid
None
If set to process ID (pid), when that process terminates, the debugger exits.
$floatshrinking
1
If set to the default (1), the debugger prints binary floating point numbers using the shortest possible decimal number. If set to 0, the debugger prints the decimal number that is the closest representation in the number of decimal digits available of the internal binary number.
$funcsig
1
Displays function signature at breakpoint.
$giveladebughints
1
Displays hints on Ladebug features.
$hasmeta
0
Interprets multibyte characters.
$hexints
0
Displays integers in hex radix.
$historylines
20
Defines the number of commands to show for history.
$indent
1
Prints structures with indentation.
$kdebug_host
localhost
Specifies the node name of the gateway system. The default "localhost" indicates no gateway system.
$kdebug_line
kdebug
Specifies the label of the /etc/remote entry on the gateway system for the kdebug communication port.
$kdebug_dbgtty
(null)
Specifies the pathname of the terminal window (output from tty (1)) on the gateway system used to display kdebug communication traffic. The default (null) indicates no gateway system.
$ladebugpid
None
Value of the pid for Ladebug itself.
$lang
None
Defines the programming language of current routine.
$lasteventmade
0
Displays the number of last (successful) breakpoint definition.
$lc_ctype
"C"
Displays the current locale information.
$listwindow
20
Displays the number of lines to show for list.
$main
"main"
Displays the name of the first routine in the program.
$maxstrlen
128
Defines the largest string to print fully.
$memorymatchall
0
When set to non-zero, displays all memory matches in the specified range. Otherwise, displays only the first memory match.
$octints
0
Displays integers in octal radix.
$overloadmenu
1
Prompts for choice of overloaded C++ name.
$page
1
Paginates debugger terminal output.
$pagewindow
0
Defines the number of lines per output page. The default of 0 causes the debugger to query the terminal for the page size.
$parallel_aggregatordelay
3000 milliseconds
Set in the .ladebugrc file or or in the file used with the debugger invocation option -i, specifies the length of time that aggregators wait before they aggregate and send messages down to the next level when not all the expected messages have been received.
$parallel_branchingfactor
8
Set in the .ladebugrc file or in the file used with the debugger invocation option -i, specifies the factor used to build the n-nary tree and determine the number of aggregators in the tree.
$parentprocess
0
When the debugger detects a fork, it assigns the parent process ID to $parentprocess.
$pimode
0
Echoes input to log file on playback input.
$prompt
"(ladebug) "
Specifies debugger prompt.
$readtextfile
0
If set to non-zero, reads instructions from the text area of the binary file rather than from the memory image.
$regstyle
1
Controls the format of register names during disassembly. Valid settings are:
  • 0 = compiler names, for example, t0, ra, or zero.
  • 1 = hardware names, for example, r1, r26, or r31.
  • 2 = assembly names, for example, $1, $26, or $31.
$repeatmode
1
Repeats previous command when you press the Return key.
$showlineonstartup
0
Displays the first executable line in main.
$showwelcomemsg
1
Displays welcome message at startup time.
$stackargs
1
Shows arguments in the call stack if 1.
$statusargs
1
Prints breakpoints with parameters if 1.
$stepg0
0
Steps over routines with minimal symbols.
$stoponattach
0
Stops the running process on attach.
$stopparentonfork
0
Stops parent process execution on fork. When set to a nonzero value, this variable instructs the debugger to stop the parent process after it forks a child process. The child process continues to run if $catchforks is not set, otherwise stops. The default is 0.
$symbolsearchlimit
100
Specifies the maximum number of symbols that are returned by the whereis command for a regular expression search. The default value is 100; a value of 0 indicates no limit.
$threadlevel
decthreads
Specifies POSIX threads (DECthreads) or native threads.
$usedynamictypes
1
Evaluates using C++ static or dynamic type.
$verbose
0
Produces even more output.



Appendix 2—Debugger Aliases

The debugger has the following predefined aliases:

Appendix 3—corefile_listobj.c Example

You can use the following example as an alternative to the listobj command for cases in which the debugger cannot be run on the original system. See the Transporting Core Files section for more information.
/*
  cc corefile_listobj.c -lxproc -o corefile_listobj
 */


#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

#include <errno.h>

typedef unsigned long vma_t;

/* core file format */

#include <sys/user.h>
#include <sys/core.h>

/* dynamic loader hookup */

#include <loader.h>
typedef int (*ldr_reader_func)(vma_t from,
                               void * to,
                               long nbytes,
                               int is_string);
extern pid_t ldr_core_process();
extern int ldr_set_core_reader(ldr_reader_func reader);

/********************************************************************/

static FILE *                   corefile;
static struct core_filehdr      corehdr;
static int                      nsections;
static struct core_scnhdr *     section_headers;

int
open_corefile(const char * corename)
{
  size_t nread;

  corefile = fopen(corename, "rb");
  if (!corefile) {
    perror("Opening corefile");
    return -1;
  }
  nread = fread(&corehdr, sizeof(corehdr), 1, corefile);
  if (nread != 1) {
    perror("fread() of corefile header");
    return -1;
  }
  if (strncmp(corehdr.magic, "Core", 4) != 0) {
    fprintf(stderr, "Corefile header magic is not \"Core\"\n");
    return -1;
  }
  nsections = corehdr.nscns;
  section_headers = calloc(nsections, sizeof(section_headers[0]));
  if (!section_headers) {
    perror("Allocating corefile section headers");
    return -1;
  }
  nread = fread(section_headers, sizeof(section_headers[0]),
                nsections, corefile);
  if (nread != nsections) {
    perror("fread() of corefile section headers");
    return -1;
  }

  return 0;
}

static int
section_type_has_memory(int type)
{
  switch (type) {
  case SCNTEXT: case SCNDATA: case SCNRGN: case SCNSTACK:
    return 1;
  case SCNREGS: case SCNOVFL:
  default:
    return 0;
  }
}

static int
read_from_corefile(vma_t from,
                   void * to,
                   long nbytes,
                   int is_string)
{
  vma_t getter = from;
  char * putter = (char *) to;
  long to_go = nbytes;
  int secnum;
  size_t nxfer;

try_for_more:
  while (to_go > 0) {
    for (secnum = 0; secnum < nsections; secnum += 1) {
      if (section_type_has_memory(section_headers[secnum].scntype)) {
        vma_t vaddr = (vma_t) section_headers[secnum].vaddr;
        vma_t size  = (vma_t) section_headers[secnum].size;
        if (vaddr <= getter && getter < vaddr+size) {
          vma_t this_time = (size < to_go ? size : to_go);
          long file_offset = section_headers[secnum].scnptr+(getter-vaddr);
          if (fseek(corefile, file_offset, SEEK_SET) != 0) {
            perror("fseek() for corefile read");
            return -1;
          }
          nxfer = fread(putter, 1, this_time, corefile);
          if (nxfer != this_time) {
            perror("fread() of corefile data ");
            return -1;
          }
          to_go -= this_time;
          getter += this_time;
          putter += this_time;
          goto try_for_more;
        }
      }
    }
    fprintf("Couldn't find core address for %#lx\n", getter);
    return -1;
  }
  return 0;
}

int
main(int argc, char* argv[])
{
  pid_t process;

  if (argc != 2) {
    fprintf(stderr, "Usage is %s \n", argv[0]);
    return 1;
  }
  if (open_corefile(argv[1]) < 0)
    return -1;

  process = ldr_core_process();
  ldr_set_core_reader(read_from_corefile);

  if (ldr_xattach(process) < 0) {
    perror("Attaching to corefile");
    return 1;
  } else {
    ldr_module_t mod_id = LDR_NULL_MODULE;
    ldr_module_info_t info;
    size_t ret_size;
    while (1) {
      if (ldr_next_module(process, &mod_id) < 0) {
        perror("ldr_next_module");
        return 1;
      }
      if (mod_id == LDR_NULL_MODULE)
        break;
      if (ldr_inq_module(process, mod_id, &info,
                         sizeof(info), &ret_size) < 0) {
        perror("ldr_inq_module");
        return 1;
      }
      printf("%s\n", info.lmi_name);
    }
    ldr_xdetach(process);
    return 0;
  }
}

Appendix 4—Array Navigation Example

The debugger provides parameterized aliases and debugger variables of arbitrary types. Clever use of these can do almost any list traversal.

For example, here is how to navigate an array:

alias elt(e_) "{ p e_ }"
alias pa0(a)  "{ set $a = &a[0]; set $i = 0; elt($a[$i]); set $i = $i+1 }"
alias pan     "{ elt($a[$i]); set $i = $i+1 }"
pa0
pan
pan
pan

%ladebug a.out
...
(ladebug) alias elt(e_) "{ p e_ }"
(ladebug) alias a0(a)   "{ set $a = &a[0]; set $i = 0; elt($a[$i]); set $i = $i+1 }"
(ladebug) alias pan     "{ elt($a[$i]); set $i = $i+1 }"
...
(ladebug) pa0(a)
struct S {
  next = 0x140000178;
}
(ladebug) pan
struct S {
  next = 0x140000180;
}
(ladebug)
struct S {
  next = 0x140000188;
}
(ladebug)
struct S {
  next = 0x140000190;
}