Title and Contents |
It is intended to be used as a reference and therefore contains a wide variation in the level of information provided in each section.
void loopForDebugger()
{
if (!getenv("loopForDebugger")) return;
static volatile int debuggerPresent = 0;
while (!debuggerPresent);
}
attach
capability to get the process under control.
When you have the process under debugger control, you can assign
a non-zero value to debuggerPresent, and continue your program. For example:
% setenv loopForDebugger ""
% a.out arg1 arg2 &
% ladebug -pid 1709 a.out
^C
(ladebug) assign debuggerPresent = 1
...
(ladebug) cont
You can also call the
debugBreak
function to start the
debugger at some specified point after your program starts executing.
/*% cc -g traceback.c -lexc
**% a.out
*/
struct exception_info;
/* To suppress compilation warnings from sym.h */
#include <demangle.h>
#include <excpt.h>
#include <setjmp.h>
#include <signal.h>
#include <sym.h>
#include <unistd.h>
static void printHeader(void)
{
printf("Diagnostic stack trace ...\n");
}
static void printTrailer(void)
{
printf("end of diagnostic stack trace.\n");
}
#define RETURNADDRREG (26)
#define FAULTING_ADDRESS sc_traparg_a0
extern unsigned long _procedure_string_table;
extern unsigned long _procedure_table_size;
extern unsigned long _procedure_table;
extern unsigned long _ftext; /* Start address of the program text.*/
extern unsigned long _etext; /* First address above the program text.*/
/* Turn a PC into the name of the routine containing that PC.
*/
char* programCounterToName(
unsigned long programCounter);
/* Unwind the stack one level.
*/
void unwindOneLevel(
struct sigcontext* unwindSignalContext,
void * runtimeProcedurePtr);
void printFrame(
void * rpdp,
unsigned long programCounter)
{
char* procedureName;
/* Get the procedure name.
*/
procedureName = programCounterToName(programCounter);
printf("%p %s\n",
(void* ) programCounter, procedureName ? procedureName : "
stdin
or
from the file specified in the source
command
(as described in Part II), each line is
then converted into a sequence of lexical elements known as
lexemes. For example, print(a++);
is converted into the
following lexemes:
print ( a ++ ) ;
The sequence of lexemes is then recognized as Ladebug commands containing language-specific expressions by a process known as parsing. The recognition is based on a set of rules known as a grammar. The debugger uses a single grammar for commands regardless of the current program's language, but it has language-specific subgrammars for some of the pieces of commands, such as names, expressions, and so on.
The debugger moves between the following lexical states as it recognizes the lexemes:
Lexical State | Description |
LBPT | Breakpoint commands have lexemes that change the lexical state to LBPT. |
LEXPORT | The command export changes the lexical state to
LEXPORT. This state recognizes an evironment variable identifier. |
LFILE | Commands that require file names have lexemes that change the
lexical state to LFILE so that things like mysrc/foo.txt are
recognized as
a file name, and not as a variable mysrc being divided by a
structure data member foo.txt . |
LFINT | Commands that require either a file name or a process ID have lexemes to change the lexical state to LFINT. |
LKEYWORD | All but one of the Ladebug commands begin with one or more
keywords. The exception is the examine command.
The debugger recognizes the '{' and ';' lexemes that must precede a
command, and uses those to reset to the LKEYWORD state for the beginning of
the next command. |
LLINE | Commands that require arbitrary character input have lexemes that change the lexical state to LLINE. |
LNORM | Language expressions involve language-specific lexemes. The lexemes that precede an expression change the lexical state to LNORM, and then LNORM recognizes the language-specific lexemes. |
LSETENV | The command setenv changes the lexical state to
LSETENV. This state recognizes an evironment variable identifier.
|
LSIGNAL | Commands that require signal names have lexemes that change the lexical state to LSIGNAL. |
LWORD | Commands that require shell words have lexemes that change the lexical state to LWORD. |
The rules that each lexical state uses are described in the following sections, in a format known as a lex regular expression. Rather than repeating some of descriptions, a set of common subrules is described first. After the common subrules, we describe the initial state, the rules, and for each recognized token, the next lexical state.
All Ladebug commands, except
examine
, begin with
leading keywords. Because the
examine
command
begins with an expression, all identifiers must be recognized as such
from both the LKEYWORD state
that starts commands and the LNORM state
that the debugger uses for processing expressions.
Some Ladebug commands have keywords embedded in them
following expressions, and the ends of expressions are hard to recognize.
You can use identifiers that have the same spelling as an embedded keyword
simply by enclosing the whole expression in parentheses (()
).
For more information on using keywords within commands, see
Section 4.4.4.
Furthermore, the C and C++ grammars need to know whether an identifier is a
typedef
or struct/class
identifier. The debugger currently
makes the determination at the time the
whole command is parsed, rather than deferring the determination to when the
expression itself is being evaluated. This can result in a misidentification of the
identifier.
When in the following four lexical states, the debugger can recognize identifiers:
Language | Regular Expression |
C, C++, Fortran, Ada | {LT}({LT}|{DG})* |
COBOL | CobolWord |
Language | Regular Expression |
All | {LT}({LT}|{DG})* |
{LT}
equates to {LTI18N}
.
The complete set of embedded keywords follows:
Lexeme | Representation | Initial Lexical State | Changed Lexical State | Language Specific? |
ANY |
any |
LNORM | LNORM |
Shared by all |
AT |
at |
LBPT , LNORM
| LNORM |
Shared by all |
CHANGED |
changed |
LNORM | LNORM |
Shared by all |
IF |
if |
LBPT | LNORM |
Shared by all |
IN |
in |
LBPT , LNORM
| LNORM |
Shared by all |
IN_ALL |
in{Whitespace}all
{Whitespace} |
LBPT , LNORM
| LNORM |
Shared by all |
POLICY |
policy |
LNORM | LNORM |
Shared by all |
PRIORITY |
priority |
LNORM | LNORM |
Shared by all |
READ |
read |
LNORM | LNORM |
Shared by all |
THREAD |
thread |
LNORM | LNORM |
Shared by all |
THREAD_ALL |
thread{Whitespace}all
|
LNORM | LNORM |
Shared by all |
TO |
to |
LNORM | LNORM |
Shared by all |
WITH_STATE |
with{Whitespace}state |
LNORM | LNORM |
Shared by all |
WITHIN |
within |
LNORM | LNORM |
Shared by all |
WRITE |
write |
LNORM | LNORM |
Shared by all |
NOTE: THREAD
is both a leading and an embedded keyword.
()
) to use them as a normal identifier,
unless they occur at the start of an examine
command.
Leading keywords may differ between languages. The complete set follows:
Lexeme | Representation (Some May Be Language Specific) |
Initial Lexical State | Changed Lexical State | Language Specific? |
ALIAS |
alias |
LKEYWORD | LNORM |
Shared by all |
ASSIGN |
assign |
LKEYWORD | LNORM |
Shared by all |
ATTACH |
attach |
LKEYWORD | LNORM |
Shared by all |
CALL |
call |
LKEYWORD | LNORM |
Shared by all |
CATCH |
catch |
LKEYWORD | LSIGNAL |
Shared by all |
CATCH_UNALIGN |
catch{Whitespace}unaligned |
LKEYWORD | LNORM |
Shared by all |
CLASS |
class |
LKEYWORD | LNORM |
C++ Special Case |
CLONE_SNAPSHOT |
clone{Whitespace}snapshot |
LKEYWORD | LNORM |
Shared by all |
CONDITION |
condition |
LKEYWORD | LNORM |
Shared by all |
CONT |
cont |
LKEYWORD | LNORM |
Shared by all |
CONTI |
conti |
LKEYWORD | LNORM |
Shared by all |
CONT_THREAD |
cont{Whitespace}thread |
LKEYWORD | LNORM |
Shared by all |
DELETE |
delete |
LKEYWORD | LNORM |
Shared by all, also used for C++ special case |
DELETE_ALL |
delete{Whitespace}*
|
LKEYWORD | LNORM |
Shared by all |
DELSHAREDOBJ |
delsharedobj |
LKEYWORD | LFILE |
Shared by all |
DETACH |
detach |
LKEYWORD | LNORM |
Shared by all |
DISABLE |
disable |
LKEYWORD | LNORM |
Shared by all |
DISABLE_ALL |
disable{Whitespace}*
|
LKEYWORD | LNORM |
Shared by all |
DOWN |
down |
LKEYWORD | LNORM |
Shared by all |
DUMP |
dump |
LKEYWORD | LNORM |
Shared by all |
EDIT |
edit |
LKEYWORD | LFILE |
Shared by all |
ELSE |
else |
LKEYWORD | LKEYWORD |
Shared by all |
ENABLE |
enable |
LKEYWORD | LNORM |
Shared by all |
ENABLE_ALL |
enable{Whitespace}*
|
LKEYWORD | LNORM |
Shared by all |
EXPORT |
export |
LKEYWORD | LNORM |
Shared by all |
FILECMD |
file |
LKEYWORD | LFILE |
Shared by all |
FILEEXPR |
fileexpr |
LKEYWORD | LFILE |
Shared by all |
FUNC |
func |
LKEYWORD | LNORM |
Shared by all |
GOTO |
goto |
LKEYWORD | LNORM |
Shared by all |
GUI |
gui |
LKEYWORD | LNORM |
Shared by all |
HELP |
help |
LKEYWORD | LLINE |
Shared by all |
HISTORY |
history |
LKEYWORD | LNORM |
Shared by all |
HPFGET |
hpfget |
LKEYWORD | LNORM |
Fortran |
IF |
if |
LKEYWORD | LNORM |
Shared by all |
IGNORE |
ignore |
LKEYWORD | LSIGNAL |
Shared by all |
IGNORE_UNALIGN |
ignore{Whitespace}unaligned |
LKEYWORD | LNORM |
Shared by all |
INPUT |
input |
LKEYWORD | LFILE |
Shared by all |
IO |
io |
LKEYWORD | LFILE |
Shared by all |
KILL |
kill |
LKEYWORD | LNORM |
Shared by all |
KPS |
kps |
LKEYWORD | LNORM |
Shared by all |
LIST |
list |
LKEYWORD | LNORM |
Shared by all |
LISTOBJ |
listobj |
LKEYWORD | LNORM |
Shared by all |
LOAD |
load |
LKEYWORD | LFILE |
Shared by all |
MAP_SOURCE_DIRECTORY |
map{Whitespace}source{Whitespace}directory |
LKEYWORD | LNORM |
Shared by all |
MUTEX |
mutex |
LKEYWORD | LNORM |
Shared by all |
NEXT |
next |
LKEYWORD | LNORM |
Shared by all |
NEXTI |
nexti |
LKEYWORD | LNORM |
Shared by all |
OUTPUT |
output |
LKEYWORD | LFILE |
Shared by all |
PATCH |
patch |
LKEYWORD | LNORM |
Shared by all |
PLAYBACK |
playback |
LKEYWORD | LKEYWORD |
Shared by all |
POP |
pop |
LKEYWORD | LNORM |
Shared by all |
PRINT |
print |
LKEYWORD | LNORM |
Shared by all |
PRINTB |
printb |
LKEYWORD | LNORM |
Shared by all |
PRINTD |
printd |
LKEYWORD | LNORM |
Shared by all |
PRINTENV |
printenv |
LKEYWORD | LNORM |
Shared by all |
PRINTF |
printf |
LKEYWORD | LNORM |
Shared by all |
PRINTI |
printi |
LKEYWORD | LNORM |
Shared by all |
PRINTO |
printo |
LKEYWORD | LNORM |
Shared by all |
PRINTT |
printt |
LKEYWORD | LNORM |
Shared by all |
PRINTX |
printx |
LKEYWORD | LNORM |
Shared by all |
PRINTREGS |
printregs |
LKEYWORD | LNORM |
Shared by all |
PROCESS |
process |
LKEYWORD | LNORM |
Shared by all |
PROCESS_ALL |
process{Whitespace}*
|
LKEYWORD | LNORM |
Shared by all |
PTHREAD |
pthread |
LKEYWORD | LNORM |
Shared by all |
QUESTION |
? |
LKEYWORD | LNORM |
Shared by all |
QUIT |
quit |
LKEYWORD | LNORM |
Shared by all |
READSHAREDOBJ |
readsharedobj |
LKEYWORD | LFILE |
Shared by all |
RECORD |
record |
LKEYWORD | LKEYWORD |
Shared by all |
RERUN |
rerun |
LKEYWORD | LWORD |
Shared by all |
RETURN |
return |
LKEYWORD | LNORM |
Shared by all |
RUN |
run |
LKEYWORD | LWORD |
Shared by all |
SAVE_SNAPSHOT |
save{Whitespace}snapshot |
LKEYWORD | LNORM |
Shared by all |
SET |
set |
LKEYWORD | LNORM |
Shared by all |
SETENV |
setenv |
LKEYWORD | LNORM |
Shared by all |
SH |
sh |
LKEYWORD | LNORM |
Shared by all |
SHOW |
show |
LKEYWORD | LKEYWORD |
Shared by all |
SHOW_SOURCE_DIRECTORY |
show{Whitespace}source{Whitespace}
directory |
LKEYWORD | LNORM |
Shared by all |
SHOW_ALL_SOURCE_DIRECTORY |
show{Whitespace}all{Whitespace}
source{Whitespace}directory |
LKEYWORD | LNORM |
Shared by all |
SLASH |
/ |
LKEYWORD | LNORM |
Shared by all |
SNAPSHOT |
snapshot |
LKEYWORD | LNORM |
Shared by all |
SNAPSHOT_ALL |
snapshot all |
LKEYWORD | LNORM |
Shared by all |
SNAPSHOT_* |
snapshot * |
LKEYWORD | LNORM |
Shared by all |
SOURCE |
source |
LKEYWORD | LFILE |
Shared by all |
STATUS |
status |
LKEYWORD | LNORM |
Shared by all |
STEP |
step |
LKEYWORD | LNORM |
Shared by all |
STEPI |
stepi |
LKEYWORD | LNORM |
Shared by all |
STOP |
stop |
LKEYWORD | LBPT |
Shared by all |
STOPI |
stopi |
LKEYWORD | LNORM |
Shared by all |
THREAD |
thread |
LKEYWORD | LNORM |
Shared by all |
TRACE |
trace |
LKEYWORD | LNORM |
Shared by all |
TRACEI |
tracei |
LKEYWORD | LNORM |
Shared by all |
UNALIAS |
unalias |
LKEYWORD | LNORM |
Shared by all |
UNLOAD |
unload |
LKEYWORD | LNORM |
Shared by all |
UNMAP_SOURCE_DIRECTORY |
unmap{Whitespace}source
{Whitespace}directory |
LKEYWORD | LNORM |
Shared by all |
UNRECORD |
unrecord |
LKEYWORD | LNORM |
Shared by all |
UNSET |
unset |
LKEYWORD | LNORM |
Shared by all |
UNSETENV |
unsetenv |
LKEYWORD | LNORM |
Shared by all |
UNSETENV_ALL |
unsetenv{Whitespace}* |
LKEYWORD | LNORM |
Shared by all |
UNUSE |
unuse |
LKEYWORD | LFILE |
Shared by all |
UP |
up |
LKEYWORD | LNORM |
Shared by all |
USE |
use |
LKEYWORD | LFILE |
Shared by all |
VERSION |
version |
LKEYWORD | LNORM |
Shared by all |
WATCH |
watch |
LKEYWORD | LNORM |
Shared by all |
WATCH_MEMORY |
watch{Whitespace}memory |
LKEYWORD | LNORM |
Shared by all |
WATCH_VARIABLE |
watch{Whitespace}variable |
LKEYWORD | LNORM |
Shared by all |
WHATIS |
whatis |
LKEYWORD | LNORM |
Shared by all |
WHEN |
when |
LKEYWORD | LBPTChapter |
Shared by all |
WHENI |
wheni |
LKEYWORD | LNORM |
Shared by all |
WHERE |
where |
LKEYWORD | LNORM |
Shared by all |
WHEREIS |
whereis |
LKEYWORD | LNORM |
Shared by all |
WHERE_THREAD |
where{Whitespace}thread |
LKEYWORD | LNORM |
Shared by all |
WHERE_THREAD_ALL |
where{Whitespace}thread
{Whitespace}*
|
LKEYWORD | LNORM |
Shared by all |
WHICH |
which |
LKEYWORD | LNORM |
Shared by all |
Some identifiers are recognized as reserved words, regardless of whether they
are inside parentheses (()
).
The reserved words may differ between languages. The complete set follows:
Lexeme | Representation (Some May Be Language Specific) |
Initial Lexical State | Changed Lexical | Language Specific? |
AND |
AND |
LNORM | LNORM |
COBOL |
MOD |
MOD |
LNORM | LNORM |
COBOL |
NOT |
NOT |
LNORM | LNORM |
COBOL |
OR |
OR |
LNORM | LNORM |
COBOL |
BYCONTENT |
(BY[ \t]+)?CONTENT |
LNORM | LNORM |
COBOL |
BYDESCRIPTOR |
(BY[ \t]+)?DESCRIPTOR |
LNORM | LNORM |
COBOL |
BYREFERENCE |
(BY[ \t]+)?REFERENCE |
LNORM | LNORM |
COBOL |
BYVALUE |
(BY[ \t]+)?VALUE |
LNORM | LNORM |
COBOL |
CHAR |
char |
LNORM | LNORM |
C, C++ |
CLASS |
class |
LNORM | LNORM |
C++ |
CONST |
const |
LNORM | LNORM |
C, C++ |
DELETE |
delete |
LNORM | LNORM |
C++ |
DOUBLE |
double |
LNORM | LNORM |
C, C++ |
ENUM |
enum |
LNORM | LNORM |
C, C++ |
FLOAT |
float |
LNORM | LNORM |
C, C++ |
GIVING |
GIVING |
LNORM | LNORM |
COBOL |
INT |
int |
LNORM | LNORM |
C, C++ |
LONG |
long |
LNORM | LNORM |
C, C++ |
NEW |
new |
LNORM | LNORM |
C++ |
OF |
OF |
LNORM | LNORM |
COBOL |
OPERATOR |
operator |
LNORM | LNORM |
C++ |
REFERENCEOF |
REFERENCE([ \t]+"OF")? |
LNORM | LNORM |
COBOL |
SHORT |
short |
LNORM | LNORM |
C, C++ |
SIGNED |
signed |
LNORM | LNORM |
C, C++ |
SIGNNEG |
(IS[ \t]+)?"NEGATIVE" |
LNORM | LNORM |
COBOL |
SIGNNOTZERO |
(IS[ \t]+)?"NOT"[ \t]+"ZERO" |
LNORM | LNORM |
COBOL |
SIGNPOS |
(IS[ \t]+)?"POSITIVE" |
LNORM | LNORM |
COBOL |
SIGNZERO |
(IS[ \t]+)?"ZERO" |
LNORM | LNORM |
COBOL |
SIZEOF |
sizeof |
LNORM | LNORM |
C, C++, Fortran |
STRUCT |
struct |
LNORM | LNORM |
C, C++ |
UNION |
union |
LNORM | LNORM |
C, C++ |
UNSIGNED |
unsigned |
LNORM | LNORM |
C, C++ |
USING |
USING |
LNORM | LNORM |
COBOL |
VOID |
void |
LNORM | LNORM |
C, C++ |
VOLATILE |
volatile |
LNORM | LNORM |
C, C++ |
Some lexemes have the same representation in all languages, especially those that form part of the Ladebug commands apart from the language-specific expressions.
Concept | Rule | Representation | Description |
Decimal digit | DG | [0-9] |
One character from '0'..'9'. |
Octal digit | OC | [0-7] |
One character from '0'..'7'. |
Hexadecimal digit | HX | [0-9a-fA-F] |
Any of the characters '0'..'9' and any of the letters 'A'..'F' and 'a'..'f'. |
Single letter | LT | [A-Za-z_$] |
Any of the characters 'A'..'Z', 'a'..'z', and the underscore (_) and dollar sign ($) characters. |
Single letter
from the International Character Set |
LT18N | [A-Za-z_$\200-\377] |
Any of the characters 'A'..'Z', 'a'..'z', the underscore (_) and dollar sign ($) characters, and any character in the top half of the 8-bit character set. |
Shell 'word' | WD | [^ \t;\n<>'"] |
Any character except space, tab, semicolon (;), linefeed, less than (<), greater than (>), and quotes (' or "). |
File name | FL | [^ \t\n\}\;\>\<] |
Any character except space, tab, semicolon (;), linefeed, right brace (}), less than (<), greater than (>), and tick (`). |
Optional exponent | Exponent | [eE][+-]?{DG}+ |
Numbers often allow an optional exponent. It is represented as an 'e' or 'E' followed by an optional plus (+) or minus (-), and then one or more decimal digits. |
Whitespace | Whitespace | [ \t]+ |
Whitespace is often used to separate two lexemes that would
otherwise be misconstrued as a single lexeme. For example, stop in is two
keywords, but stopin is an identifier. Apart from this separating property,
Whitespace is usually ignored. Whitespace is a sequence of one or more tabs or
spaces.
|
String literal | stringChar | ([^"\\\n]|([\\]({simpleEscape}|
|
Any character except the terminating quote character ("), or a newline (\n). If the character is a backslash (\), it is followed by an escaped sequence of characters. |
Character literal | charChar | ([^'\\\n]|([\\]({simpleEscape}|
|
Any character except the terminating quote (') character, or a newline (\n). If the character is a backslash (\), it is followed by an escaped sequence of characters. |
Environment variable identifier | EID | [^ \t\n<>;='"&\|] |
Any character except space, tab, linefeed, less-than (<), greater-than (>), semicolon (;), equal sign (=), quotes (' or "), ampersand (&), backslash (\), and bar (|). |
The escaped sequence of characters can be one of following three forms:
Concept | Rule | Representation | Description |
Simple escape | simpleEscape | ([A-Za-z'"?#*\\])
|
One of 'A'-'Z' or 'a'-'z'. Some of these have special meanings, the most common being 'n' for newline and 't' for tab. Can be a quote (' or ") character that does not finish the literal, a question mark (?), a pound sign (#), an asterisk (*), or a backslash (\), which then becomes part of the string literal rather than causing a further escape sequence. |
Octal escape | octalEscape | (OC{1,3})
|
1 to 3 octal digits, the combined numeric value of which is the character that becomes part of the string literal. |
Hexadecimal escape | hexEscape | ([xX]HX{1,8})
|
An 'x' or an 'X' followed by 1 to 8 hexadecimal digits, the combined numeric value of which is the character that becomes part of the string literal. |
In all lexical states except LLINE, a semicolon also changes the lexical state to be LKEYWORD.
Initial State: | LKEYWORD, LNORM, LFILE, LLINE, LWORD, LSIGNAL, LBPT |
Regular Expression: | [\n] |
Lexeme: | NEWLINE |
Change to State: | LKEYWORD |
This is because SEMICOLON is the command separator.
Initial State: | LKEYWORD, LNORM, LFILE, LSIGNAL, LBPT, LWORD | Regular Expression: | ";" |
Lexeme: | SEMICOLON |
Change to State: | LKEYWORD |
Commands can be nested, and the following transitions support this:
Initial State: | LNORM | Regular Expression: | "{" |
Lexeme: | LBRACE |
Change to State: | LKEYWORD |
Initial State: | LKEYWORD, LNORM, LFILE, LSIGNAL, LBPT | Regular Expression: | "}" |
Lexeme: | RBRACE |
Change to State: | LKEYWORD |
In most lexical states, the spaces, tabs, and escaped newlines are ignored. In the LLINE state, the spaces and tabs are part of the line, but escaped newlines are still ignored. In the LWORD state, the spaces and tabs are ignored, but escaped newlines are not.
Initial State: | LKEYWORD, LNORM, LFILE, LSIGNAL, LBPT |
Regular Expression: | [ \t] |
Lexeme: | Ignored |
Change to State: | Unchanged |
Initial State: | LLINE |
Regular Expression: | \\\n |
Lexeme: | Ignored |
Change to State: | Unchanged |
Initial State: | LWORD |
Regular Expression: | [ \t] |
Lexeme: | Ignored |
Change to State: | Unchanged |
Lexeme | Regular Expression |
ANY |
any |
AT |
at |
ATSIGN |
"@" |
CHANGED |
changed |
CHARACTERconstant |
[lL][']{charChar}+['] |
COLON |
":" |
COMMA |
"," |
DOLLAR |
"$" |
DOT |
"." |
GREATER |
">" |
HASH |
unknown |
IF |
if |
IN |
in |
IN_ALL |
in{Whitespace}all{Whitespace} |
INTEGERconstant |
"0"[kK]{HX}+ |
LESS |
"<" |
LPAREN |
"(" |
POLICY |
policy |
PRIORITY |
priority |
RPAREN |
")" |
READ |
read |
SLASH |
"/" |
STAR |
"*" |
STATE |
state |
STRINGliteral |
["]{stringChar}*["] |
THREAD |
thread |
THREAD_ALL |
thread{Whitespace}all
thread{Whitespace}"*" |
TICK |
"`" |
TO |
to |
WIDECHARACTERconstant |
[lL][']{charChar}+['] |
WIDESTRINGliteral |
[lL]["]{stringChar}*["] |
WITH |
with |
WITHIN |
within |
WRITE |
write |
Lexeme | Regular Expression | Initial Lexical State | Changed Lexical State |
IN |
in |
LBPT | LNORM |
IN_ALL |
in{Whitespace}all |
LBPT | LNORM |
INTEGERconstant |
"0"[kK]{HX}+ |
LBPT | LBPT |
AT |
at |
LBPT | LNORM |
PC_IS |
pc |
LBPT | LNORM |
SIGNAL |
signal |
LBPT | LNORM |
UNALIGNED |
unaligned |
LBPT | LNORM |
VARIABLE |
variable |
LBPT | LNORM |
MEMORY |
memory |
LBPT | LNORM |
EVERY_INSTRUCTION |
every{Whitespace}instruction | LBPT | LNORM |
EVERY_PROC_ENTRY |
every{Whitespace}proc[edure]{Whitespace}entry |
LBPT | LNORM |
QUIET |
quiet |
LBPT | LBPT |
The state is left as LFILE, so that commands such as use
and
unuse
can have lists of files.
Lexeme | Regular Expression |
FILENAME |
{FL}+ |
Lexeme | Regular Expression |
INTEGERconstant |
"0"{OC}+ |
Lexeme | Regular Expression |
GREATER |
">" |
LESS |
"<" |
GREATERAMPERSAND |
">&" |
ONEGREATER |
"1>" |
TWOGREATER |
"2>" |
STRINGliteral |
[']{charChar}*['] |
STRINGliteral |
{WD}* that does not end in a backslash |
WIDECHARACTERconstant |
[lL][']{charChar}+['] |
WIDESTRINGliteral |
[lL]["]{stringChar}*["] |
Lexeme | Regular Expression |
INTEGERconstant |
{DG}+ |
IDENTIFIER |
{LT}({LT}|{DG})* |
Lexeme | Regular Expression |
ENVARID |
{EID} + |
Lexeme | Representation (Some May Be Language Specific) |
Initial Lexical State | Changed Lexical State | Language Specific? |
ALPHASDIGITSI18N |
[0-9A-Za-z_$\200-\377] |
LNORM, LBPT | LNORM |
COBOL |
ALPHASDIGITS
|
[0-9A-Za-z_$\200-\377\-] |
LNORM, LBPT | LNORM |
COBOL |
AMPERSAND |
"&" |
LNORM | Unchanged | C, C++, Fortran, Ada |
AND |
AND |
LNORM | Unchanged | COBOL |
ANDAND |
"&&" |
LNORM | Unchanged | C, C++, Ada |
ANDassign |
"&=" |
LNORM | Unchanged | C, C++ |
ARROW |
"->" |
LNORM | Unchanged | C, C++, Ada |
ARROWstar |
"->*" |
LNORM | Unchanged | C++ |
ASSIGNOP |
"=" |
LNORM | Unchanged | C, C++, Fortran, Ada, COBOL |
BRACKETS |
"[]" |
LNORM | Unchanged | C, C++, Ada |
CLCL |
"::" |
LNORM | Unchanged | C++ |
DECR |
"--" |
LNORM | Unchanged | C, C++, Ada |
DIVassign |
"/=" |
LNORM | Unchanged | C, C++, Ada |
DOTstar |
".*" |
LNORM | Unchanged | C++ |
ELLIPSIS |
"..." |
LNORM | Unchanged | C++ |
EQ |
"==" |
LNORM | Unchanged | C, C++, Fortran, Ada, COBOL |
ERassign |
"^=" |
LNORM | Unchanged | C, C++ |
EXPON |
"**" |
LNORM | Unchanged | COBOL |
GE |
">=" |
LNORM | Unchanged | C, C++, Fortran, Ada, COBOL |
GREATER |
">" |
LNORM | Unchanged | Shared by all, also used for Fortran and COBOL special cases |
HAT |
"^" |
LNORM | Unchanged | C, C++, Ada |
INCR |
"++" |
LNORM | Unchanged | C, C++, Ada |
LBRACKET |
"[" |
LNORM | Unchanged | C, C++, Fortran, Ada |
LE |
"<=" |
LNORM | Unchanged | C, C++, Fortran, Ada, COBOL |
LESS |
"<" |
LNORM | Unchanged | Shared by all, also used for Fortran and COBOL special cases |
LOGAND |
".AND." |
LNORM | Unchanged | Fortran |
LOGEQV |
".EQV." |
LNORM | Unchanged | Fortran |
LOGNEQV |
".NEQV." |
LNORM | Unchanged | Fortran |
LOGNOT |
".NOT." |
LNORM | Unchanged | Fortran |
LOGOR |
".OR." |
LNORM | Unchanged | Fortran |
LOGXOR |
".XOR." |
LNORM | Unchanged | Fortran |
LS |
"<<" |
LNORM | Unchanged | C, C++, Ada |
LSassign |
"<<=" |
LNORM | Unchanged | C, C++ |
MINUS |
"-" |
LNORM | Unchanged | C, C++, Fortran, Ada, COBOL |
MINUSassign |
"-=" |
LNORM | Unchanged | C, C++ |
MOD |
"%" |
LNORM | Unchanged | C, C++, Ada, COBOL |
MODassign |
"%=" |
LNORM | Unchanged | C, C++, Ada |
MULTassign |
"*=" |
LNORM | Unchanged | C, C++, Ada |
NE |
"!=" |
LNORM | Unchanged | C, C++, Fortran, Ada |
NOT |
"!" |
LNORM | Unchanged | C, C++, Ada, COBOL |
OPENSLASH |
"(/" |
LNORM | Unchanged | Fortran |
OR |
"|" |
LNORM | Unchanged | C, C++, Ada, COBOL |
OROR |
"||" |
LNORM | Unchanged | C, C++, Ada |
ORassign |
"|=" |
LNORM | Unchanged | C, C++ |
PARENS |
"()" |
LNORM | Unchanged | C++ |
PERCENT |
"%" |
LNORM | Unchanged | Fortran |
PLUS |
"+" |
LNORM | Unchanged | C, C++, Fortran, COBOL |
PLUSassign |
"+=" |
LNORM | Unchanged | C, C++, Ada |
QUESTION |
"?" |
LNORM | Unchanged | C, C++, Ada |
RBRACKET |
"]" |
LNORM | Unchanged | C, C++, Fortran, Ada |
RS |
">>" |
LNORM | Unchanged | C, C++, Ada |
RSassign |
">>=" |
LNORM | Unchanged | C, C++ |
SLASHCLOSE |
"/)" |
LNORM | Unchanged | Fortran |
SLASHSLASH |
"//" |
LNORM | Unchanged | Fortran |
STARSTAR |
"**" |
LNORM | Unchanged | Fortran |
TWIDDLE |
"~" |
LNORM | Unchanged | C, C++, Ada |
If a C++ identifier is followed by a "<", complex and dubious checks are made to try to match a complete template instance specifier.
Lexeme | Representation | Language |
ARROW |
"->" |
C, C++ |
INCR |
"++" |
C, C++ |
DECR |
"--" |
C, C++ |
LS |
"<<" |
C, C++ |
RS |
">>" |
C, C++ |
LE |
"<=" |
C, C++ |
GE |
">=" |
C, C++ |
EQ |
"==" |
C, C++ |
NE |
"!=" |
C, C++ |
ANDAND |
"&&" |
C, C++ |
OROR |
"||" |
C, C++ |
MULTassign |
"*=" |
C, C++ |
DIVassign |
"/=" |
C, C++ |
MODassign |
"%=" |
C, C++ |
PLUSassign |
"+=" |
C, C++ |
MINUSassign |
"-=" |
C, C++ |
LSassign |
"<<=" |
C, C++ |
RSassign |
">>=" |
C, C++ |
ANDassign |
"&=" |
C, C++ |
ERassign |
"^=" |
C, C++ |
ORassign |
"|=" |
C, C++ |
PLUS |
"+" |
C, C++ |
MINUS |
"-" |
C, C++ |
MOD |
"%" |
C, C++ |
HAT |
"^" |
C, C++ |
AMPERSAND |
"&" |
C, C++ |
OR |
"|" |
C, C++ |
TWIDDLE |
"~" |
C, C++ |
NOT |
"!" |
C, C++ |
BRACKETS |
"[]" |
C, C++ |
ASSIGNOP |
"=" |
C, C++ |
LBRACKET |
"[" |
C, C++ |
RBRACKET |
"]" |
C, C++ |
QUESTION |
"?" |
C, C++ |
CHAR |
char |
C, C++ |
DOUBLE |
double |
C, C++ |
FLOAT |
float |
C, C++ |
INT |
int |
C, C++ |
LONG |
long |
C, C++ |
SHORT |
short |
C, C++ |
SIGNED |
signed |
C, C++ |
UNSIGNED |
unsigned |
C, C++ |
VOID |
void |
C, C++ |
CONST |
const |
C, C++ |
VOLATILE |
volatile |
C, C++ |
SIZEOF |
sizeof |
C, C++ |
ENUM |
enum |
C, C++ |
STRUCT |
struct |
C, C++ |
UNION |
union |
C, C++ |
INTEGERconstant |
"0"{OC}+
|
C, C++ |
FLOATINGconstant |
{DG}*"."{DG}*
|
C, C++ |
IDENTIFIER, TYPEDEFname |
{LT}({LT}|{DG})* |
C, C++ |
The lexemes in the following table are specific to C++. The state stays in LNORM.
Lexeme | Representation | Language |
OPERATOR |
operator |
C++ |
NEW |
new |
C++ |
DELETE |
delete |
C++ |
CLASS |
class |
C++ |
ELLIPSIS |
"..." |
C++ |
CLCL |
"::" |
C++ |
THIS |
this |
C++ |
DOTstar |
".*" |
C++ |
ARROWstar |
"->*" |
C++ |
Lexeme | Representation |
PLUS |
"+" |
MINUS |
"-" |
STARSTAR |
"**" |
LESS |
".LT." |
LE |
".LE." |
EQ |
".EQ." |
NE |
".NE." |
GE |
".GE." |
GREATER |
".GT." |
LE |
"<=" |
EQ |
"==" |
NE |
"/=" |
GE |
">=" |
LOGNOT |
".NOT." |
LOGAND |
".AND." |
LOGOR |
".OR." |
LOGEQV |
".EQV." |
LOGNEQV |
".NEQV." |
LOGXOR |
".XOR." |
PERCENT |
"%" |
ASSIGNOP |
"=" |
SLASHSLASH |
"//" |
OPENSLASH |
"(/" |
SLASHCLOSE |
"/)" |
LBRACKET |
"[" |
RBRACKET |
"]" |
AMPERSAND |
"&" |
SIZEOF |
sizeof |
INTEGERconstant |
".TRUE."
|
IDENTIFIER, TYPEDEFname |
{LT}({LT}|{DG})* |
FortranName |
[A-Za-z$]({LT}|{DG})*
|
FortranNamedKind |
"_"{FortranName} |
FortranNumericKind |
"_"{DG}+
|
FortranKind |
{FortranNamedKind} |
FortranCharacterNamedKind |
{FortranName}"_" |
FortranCharacterNumericKind |
{DG}+"_" |
FortranCharacterKind |
{FortranCharacterNamedKind} |
RealWithDecimal |
({DG}+"."{DG}*) |
ExponentVal |
[+-]?{DG}+ |
RealEExponent |
[Ee]{ExponentVal}
|
RealDExponent |
[Dd]{ExponentVal} |
RealQExponent |
[Qq]{ExponentVal} |
RealSingleConstant |
(({DG}+{RealEExponent}) |
RealDoubleConstant |
({DG}+|{RealWithDecimal}){RealDExponent}
|
RealQuadConstant |
({DG}+|{RealWithDecimal}){RealQExponent}
|
RealConstant |
{RealSingleConstant} |
REALconstantWithKind |
RealConstant |
FortranBinaryValue |
[Bb]((['][01]+['])|(["][01]+["])) |
FortranOctalValue |
[Oo](([']{OC}+['])|(["]{OC}+["])) |
FortranHexValue |
[Zz](([']{HX}+['])|(["]{HX}+["])) |
FortranOctalValueAlternative |
(([']{OC}+['])|(["]{OC}+["]))[Oo] |
FortranHexValueAlternative |
(([']{HX}+['])|(["]{HX}+["]))[Xx] |
INTEGERconstantWithKind |
{DG}+{FortranKind} |
LOGICALconstantWithKind |
".TRUE."{FortranKind}? |
CharSingleDelim |
[^'\\\n]|('') |
CharDoubleDelim |
[^"\\\n]|("") |
FortranOctalEscape |
{OC}{1,3} |
FortranHexEscape |
[Xx]{HX}{1,2} |
FortranEscapeChar |
[\\]([AaBbFfNnRrTtVv]|{FortranOctalEscape} |
StringSingleDelim |
[']({CharSingleDelim}|[\\])*['] |
StringDoubleDelim |
["]({CharDoubleDelim}|[\\])*["] |
FortranString |
{StringSingleDelim} |
CStringSingleDelim |
[']({CharSingleDelim}|{FortranEscapeChar})*['] |
CStringDoubleDelim |
["]({CharDoubleDelim}|{FortranEscapeChar})*["] |
FortranCString |
({CStringSingleDelim}|{CStringDoubleDelim})[Cc] |
CHARACTERconstantWithKind |
{FortranString} |
Lexeme | Representation |
ARROW |
"->" |
INCR |
"++" |
DECR |
"--" |
LS |
"<<" |
RS |
">>" |
LE |
"<=" |
GE |
">=" |
EQ |
"==" |
NE |
"!=" |
ANDAND |
"&&" |
OROR |
"||" |
MULTassign |
"*=" |
DIVassign |
"/=" |
MODassign |
"%=" |
PLUSassign |
"+=" |
MINUSassign |
"-=" |
LSassign |
"<<=" |
RSassign |
">>=" |
ANDassign |
"&=" |
ERassign |
"^=" |
ORassign |
"|=" |
PLUS |
"+" |
MINUS |
"-" |
MOD |
"%" |
HAT |
"^" |
AMPERSAND |
"&" |
OR |
"|" |
TWIDDLE |
"~" |
NOT |
"!" |
BRACKETS |
"[]" |
ASSIGNOP |
"=" |
LBRACKET |
"[" |
RBRACKET |
"]" |
QUESTION |
"?" |
INTEGERconstant |
"0"{OC}+
|
FLOATINGconstant |
{DG}*"."{DG}+
|
IDENTIFIER, TYPEDEFname |
{LT}({LT}|{DG})* |
expression
: expression for C
| expression for C++
| expression for Fortran
| expression for Ada
| expression for COBOL
Often you can omit an expression from a command or use a convenient default
instead, to change the meaning of a command.
expression-opt
: [ expression ]
NOTE: The debugger does not know where in the scope a declaration occurred, so all lookups consider all identifiers in the scope, whether or not they occurred before the current line.
The lexical tokens for identifiers are specific to the current language, and also to the current lexical state.
IDENTIFIER
: identifier for LSIGNAL lexical state
| identifier for C
| identifier for C++
| identifier for Fortran
| identifier for Ada
| identifier for COBOL
TYPEDEFname
s are lexically just identifiers, but when looking them up in the
current scope, the debugger determines that they refer to types, such as
TYPEDEF
s, classes, or struct
s. This information is needed to
correctly parse C and C++ expressions.
TYPEDEFname
: IDENTIFIER
A few lexical tokens act as embedded keywords in some positions within expressions,
but the debugger generally tries to accept them as though they were normal identifiers.
identifier-or-key-word
: IDENTIFIER
| embedded-key-word
embedded-key-word
: ANY
| CHANGED
| READ
| WRITE
In other contexts, the debugger is also prepared to accept TYPEDEFname
s
(for example, int
or the name of a class
).
identifier-or-typedef-name
: identifier-or-typedef-name for C
| identifier-or-typedef-name for C++
| identifier-or-typedef-name for Fortran
| identifier-or-typedef-name for Ada
| identifier-or-typedef-name for COBOL
integer_constant
: INTEGERconstant for C and C++
| INTEGERconstant for Fortran
| INTEGERconstant for Ada
| INTEGERconstant for COBOL
#define
macros, and so on.
call-expression
: call-expression for C
| call-expression for C++
| call-expression for Fortran
| call-expression for Ada
| call-expression for COBOL
Any expression can be passed 'by value', but C++ constructors and destructors will not be invoked. Evaluating parameters can involve evaluating nested calls.
Anything whose address can be taken can be passed 'by reference'.
The debugger has very limited understanding of array descriptors.
Comma is both the argument separator and a valid operator in C and C++. Hence,
argument lists are comma-separated
assignment-expressions
rather than
full expressions.
argument-expression-list
: assignment-expression
| assignment-expression COMMA argument-expression-list
arg-expression-list-opt
: [ argument-expression-list ]
assignment-expression
: assignment-expression for C
| assignment-expression for C++
| assignment-expression for Fortran
| assignment-expression for Ada
| assignment-expression for COBOL
The C++ constructors and destructors are not invoked, which may cause problems.
Some variables may be in registers; you cannot take their addresses.
The optimizing compilers may move variables from one memory location to another, in which case you will obtain the address of the current memory location of the variable.
The optimizing compilers may eliminate unused functions, as well as functions that have had all calls inlined. Static functions in header files may result in multiple copies of the code, and the address will be of only one of those copies.
The optimizing compilers and linkers may skip some instructions on the way in during a call, so a breakpoint on the first few instructions may not be hit. When you set a breakpoint on a function, the debugger sets it deeper in the function, at the end of the entry sequence, to try to avoid this.
The address of a line of source code is the address of the first instruction in memory that came from this line, but this instruction may be branched around, so it might not be executed before any other instruction from the same line.
string
, then the current file is used. If you specify a
DOLLAR as
the line-number
, then the last line in
the file that generated any instructions is used.
line-address
: ATSIGN string COLON line-number
| ATSIGN line-number
line-number
: INTEGERconstant
| DOLLAR
whatis_command
supports supersets
of the normal expression
syntax of the
language.
whatis-expressions
: whatis-expressions for C
| whatis-expressions for C++
| whatis-expressions for Fortran
| whatis-expressions for Ada
| whatis-expressions for COBOL
Some commands (notably the
examine
command
and the
cont
command) have a syntax that inhibits the use of
a full expression. In this case, a more limited form of expression is still allowed.
address-exp
: address-exp for C
| address-exp for C++
| address-exp for Fortran
| address-exp for Ada
| address-exp for COBOL
The cont
command and
the change_stack_frame_commands
have a form that specifies where to continue to, or where to cut the stack back to.
loc
: loc for C
| loc for C++
| loc for Fortran
| loc for Ada
| loc for COBOL
The target
of a
modifying_command
can only be a subset of the possible expressions,
known as a unary-expression
.
unary-expression
: unary-expression for C
| unary-expression for C++
| unary-expression for Fortran
| unary-expression for Ada
| unary-expression for COBOL
string
: LNORM string
| LLINE string
| LWORD string
Most of the languages have places where they allow a series of string literals
to be equivalent to a single string formed of their concatenated characters.
string-literal-list
: string-literal-list for C
| string-literal-list for C++
| string-literal-list for Ada
Rescoped expressions cause the debugger to look up the
identifiers and so on in the qual-symbol-opt
,
as though it were in the source file specified by the preceding
filename-tick
or
qual-symbol-opt
.
rescoped-expression
: filename-tick qual-symbol-opt
| TICK qual-symbol-opt
rescoped-typedef
: filename-tick qual-typedef-opt
| TICK qual-typedef-opt
filename-tick
: string-tick
string-tick
: string TICK
qual-symbol-opt
: expression /* Base (global) name */
| qual-symbol-opt TICK expression /* Qualified name */
qual-typedef-opt
: qual-typedef-opt for C
| qual-typedef-opt for C++
| qual-typedef-opt for Fortran
| qual-typedef-opt for Ada
| qual-typedef-opt for COBOL
In the following example, rescoped expressions are used to distinguish which
x
the user is querying, because there are two variables named
x
(one local to main
and one global):
(ladebug) list $curline - 10: 20
1 long x = 5; // global x
2
3 int main()
4 {
5 int x = 7; // local x
6 int y = x - ::x;
> 7 return (y);
8 }
By default, a local variable is found before a global one,
so that the plain x
refers to the local variable.
(ladebug) whatis x
int x
(ladebug) which x
"x_rescoped.cxx"`main`x
(ladebug) whatis "x_rescoped.cxx"`main`x
int x
You may use the C++ ::
operator to specify the global
x
in C++ code or rescoped expressions in any language.
(ladebug) whatis ::x
long x
(ladebug) whatis "x_rescoped.cxx"`x
long x
(ladebug) print "x_rescoped.cxx"`x
5
In the following example,
the x
variable is used in the following places to
demonstrate how rescoping expressions can find the correct variable:
main
Foo
Foo
's member function SetandGet
CastAndAdd
function, but
visible as a parameter
(ladebug) list $curline - 10: 20
10 double x = 3.1415;
11
12 int CastAndAdd(char x) {
13 int result = ((int)::x) + x;
14 return result;
15 }
16
17 float Foo::SetandGet() { // multiple scopes!
18 long x = (long)::x; // local x = global x
19 Foo::x = (float)x; // member x = local x
> 20 return Foo::x; // return member x
21 }
22
23 int main () {
24 int x = 7;
25 x -= CastAndAdd((char)1);
26
27 Foo thefoo;
28 x -= (int)thefoo.SetandGet();
29 return x;
(ladebug) whatis x
long x
(ladebug) which x
"x_rescoped2.cxx"`Foo::SetandGet`x
(ladebug) whatis ::x
double x
(ladebug) whatis Foo::x
float Foo::x
(ladebug) whatis main`x
int x
(ladebug) whatis CastAndAdd`x
char x
printable-type
: printable-type for C
| printable-type for C++
| printable-type for Fortran
| printable-type for Ada
| printable-type for COBOL
expression
: assignment-expression
constant-expression
: conditional-expression
identifier-or-typedef-name
: identifier-or-key-word
| TYPEDEFname
primary-expression
: identifier-or-key-word
| constant
| string-literal-list
| LPAREN expression RPAREN
string-literal-list
: string
| string-literal-list string
constant
: FLOATINGconstant
| INTEGERconstant
| CHARACTERconstant
| WIDECHARACTERconstant
| WIDESTRINGliteral
qual-typedef-opt
: TYPEDEFname
| qual-typedef-opt TICK TYPEDEFname
whatis-expressions
: expression
| rescoped-expression
| printable-type
call-expression
: expression
function-call
: postfix-expression LPAREN [arg-expression-list] RPAREN
Restrictions and limits are documented here.
address
: AMPERSAND postfix-expression
| line-address
| postfix-expression
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
Restrictions and limits are documented here.
loc
is the following:
loc
: expression
| rescoped-expression
type-specifier
: basic-type-specifier
| struct-union-enum-type-specifier
| typedef-type-specifier
basic-type-specifier
: basic-type-name
| type-qualifier-list basic-type-name
| basic-type-specifier type-qualifier
| basic-type-specifier basic-type-name
type-qualifier-list
: type-qualifier
| type-qualifier-list type-qualifier
type-qualifier
: CONST
| VOLATILE
basic-type-name
: VOID
| CHAR
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| SIGNED
| UNSIGNED
printable-type
: rescoped_typedef
| type_name
struct-union-enum-type-specifier
: elaborated-type-name
| type-qualifier-list elaborated-type-name
| struct-union-enum-type-specifier type-qualifier
typedef-type-specifier
: TYPEDEFname
| type-qualifier-list TYPEDEFname
| typedef-type-specifier type-qualifier
elaborated-type-name
: struct-or-union-specifier
| enum-specifier
struct-or-union-specifier
: struct-or-union opt-parenthesized-identifier-or-typedef-name
opt-parenthesized-identifier-or-typedef-name
: identifier-or-typedef-name
| LPAREN opt-parenthesized-identifier-or-typedef-name RPAREN
struct-or-union
: STRUCT
| UNION
enum-specifier
: ENUM identifier-or-typedef-name
type-name
: type-specifier
| type-specifier abstract-declarator
| type-qualifier-list // Implicit "int"
| type-qualifier-list abstract-declarator // Implicit "int"
type-name-list
: type-name
| type-name COMMA type-name-list
abstract-declarator
: unary-abstract-declarator
| postfix-abstract-declarator
| postfixing-abstract-declarator
postfixing-abstract-declarator
: array-abstract-declarator
| LPAREN RPAREN
array-abstract-declarator
: BRACKETS
| LBRACKET constant-expression RBRACKET
| array-abstract-declarator LBRACKET constant-expression RBRACKET
unary-abstract-declarator
: STAR
| STAR type-qualifier-list
| STAR abstract-declarator
| STAR type-qualifier-list abstract-declarator
postfix-abstract-declarator
: LPAREN unary-abstract-declarator RPAREN
| LPAREN postfix-abstract-declarator RPAREN
| LPAREN postfixing-abstract-declarator RPAREN
| LPAREN unary-abstract-declarator RPAREN postfixing-abstract-declarator
assignment-expression
: conditional-expression
| unary-expression ASSIGNOP assignment-expression
| unary-expression MULTassign assignment-expression
| unary-expression DIVassign assignment-expression
| unary-expression MODassign assignment-expression
| unary-expression PLUSassign assignment-expression
| unary-expression MINUSassign assignment-expression
| unary-expression LSassign assignment-expression
| unary-expression RSassign assignment-expression
| unary-expression ANDassign assignment-expression
| unary-expression ERassign assignment-expression
| unary-expression ORassign assignment-expression
conditional-expression
: logical-OR-expression
| logical-OR-expression QUESTION expression COLON conditional-expression
logical-OR-expression
: logical-AND-expression
| logical-OR-expression OROR logical-AND-expression
logical-AND-expression
: inclusive-OR-expression
| logical-AND-expression ANDAND inclusive-OR-expression
inclusive-OR-expression
: exclusive-OR-expression
| inclusive-OR-expression OR exclusive-OR-expression
exclusive-OR-expression
: AND-expression
| exclusive-OR-expression HAT AND-expression
AND-expression
: equality-expression
| AND-expression AMPERSAND equality-expression
equality-expression
: relational-expression
| equality-expression EQ relational-expression
| equality-expression NE relational-expression
relational-expression
: shift-expression
| relational-expression LESS shift-expression
| relational-expression GREATER shift-expression
| relational-expression LE shift-expression
| relational-expression GE shift-expression
shift-expression
: additive-expression
| shift-expression LS additive-expression
| shift-expression RS additive-expression
additive-expression
: multiplicative-expression
| additive-expression PLUS multiplicative-expression
| additive-expression MINUS multiplicative-expression
multiplicative-expression
: cast-expression
| multiplicative-expression STAR cast-expression
| multiplicative-expression SLASH cast-expression
| multiplicative-expression MOD cast-expression
cast-expression
: unary-expression
| LPAREN type-name RPAREN cast-expression
unary-expression
: postfix-expression
| INCR unary-expression
| DECR unary-expression
| AMPERSAND cast-expression
| STAR cast-expression
| PLUS cast-expression
| MINUS cast-expression
| TWIDDLE cast-expression
| NOT cast-expression
| SIZEOF unary-expression
| SIZEOF LPAREN type-name RPAREN
| line-address
postfix-expression
: primary-expression
| postfix-expression LBRACKET expression RBRACKET
| function-call
| postfix-expression LPAREN type-name-list RPAREN
| postfix-expression DOT identifier-or-typedef-name
| postfix-expression ARROW identifier-or-typedef-name
| postfix-expression INCR
| postfix-expression DECR
The aspects of the expression system not processed properly during debugger expression evaluation include the following:
There are also some minor restrictions in the following grammar, compared with the full C++ expression grammar, to make it unambiguous:
expression
: assignment-expression
constant-expression
: conditional-expression
The debugger has only a limited understanding of namespaces. It correctly processes
names such as UserNameSpace::NestedNamespace::userIdentifier
, as
well as C++ use-declarations, which introduce a new
identifier into a scope.
The debugger does not currently understand C++ using-directives.
The debugger understands the relationship between struct
and class identifiers and
typedef
identifiers.
id-or-keyword-or-typedef-name
: identifier-or-key-word
| TYPEDEFname
constant
: FLOATINGconstant
| INTEGERconstant
| CHARACTERconstant
| WIDECHARACTERconstant
| WIDESTRINGliteral
call-expression
: expression
Restrictions and limits are documented here.
address
: AMPERSAND postfix-expression /* Address of */
| line-address
| postfix-expression
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
Restrictions and limits are documented here.
loc
:
loc
: expression
| rescoped-expression
whatis-expressions
: expression
| printable-type
qual-typedef-opt
: type-name
| qual-typedef-opt TICK type-name
string-literal-list
: string
| string-literal-list string
id-expression
: id-expression-internals
id-expression-internals
: qualified-id
| id-or-keyword-or-typedef-name
| operator-function-name
| TWIDDLE id-or-keyword-or-typedef-name
qualified-id
: nested-name-specifier qualified-id-follower
qualified-type
: nested-name-specifier TYPEDEFname
nested-name-specifier
: CLCL
| TYPEDEFname CLCL
| nested-name-specifier TYPEDEFname CLCL
qualified-id-follower
: identifier-or-key-word
| operator-function-name
| TWIDDLE id-or-keyword-or-typedef-name
type-specifier
: basic-type-specifier
| struct-union-enum-type-specifier
| typedef-type-specifier
type-qualifier-list
: type-qualifier
| type-qualifier-list type-qualifier
type-qualifier
: CONST
| VOLATILE
basic-type-specifier
: basic-type-name basic-type-name
| basic-type-name type-qualifier
| type-qualifier-list basic-type-name
| basic-type-specifier type-qualifier
| basic-type-specifier basic-type-name
struct-union-enum-type-specifier
: elaborated-type-name
| type-qualifier-list elaborated-type-name
| struct-union-enum-type-specifier type-qualifier
typedef-type-specifier
: TYPEDEFname type-qualifier
| type-qualifier-list TYPEDEFname
| typedef-type-specifier type-qualifier
basic-type-name
: VOID
| CHAR
| SHORT
| INT
| LONG
| FLOAT
| DOUBLE
| SIGNED
| UNSIGNED
elaborated-type-name
: aggregate-name
| enum-name
printable-type
: rescoped-typedef
| type-name
aggregate-name
: aggregate-key opt-parenthesized-identifier-or-typedef-name
| aggregate-key qualified-type
opt-parenthesized-identifier-or-typedef-name
: id-or-keyword-or-typedef-name
| LPAREN opt-parenthesized-identifier-or-typedef-name RPAREN
aggregate-key
: STRUCT
| UNION
| CLASS
enum-name
: ENUM id-or-keyword-or-typedef-name
parameter-type-list
: PARENS type-qualifier-list-opt
type-name
: type-specifier
| qualified-type
| basic-type-name
| TYPEDEFname
| type-qualifier-list
| type-specifier abstract-declarator
| basic-type-name abstract-declarator
| qualified-type abstract-declarator
| TYPEDEFname abstract-declarator
| type-qualifier-list abstract-declarator
abstract-declarator
: unary-abstract-declarator
| postfix-abstract-declarator
| postfixing-abstract-declarator
postfixing-abstract-declarator
: array-abstract-declarator
| parameter-type-list
array-abstract-declarator
: BRACKETS
| LBRACKET constant-expression RBRACKET
| array-abstract-declarator LBRACKET constant-expression RBRACKET
unary-abstract-declarator
: STAR
| AMPERSAND
| pointer-operator-type
| STAR abstract-declarator
| AMPERSAND abstract-declarator
| pointer-operator-type abstract-declarator
postfix-abstract-declarator
: LPAREN unary-abstract-declarator RPAREN
| LPAREN postfix-abstract-declarator RPAREN
| LPAREN postfixing-abstract-declarator RPAREN
| LPAREN unary-abstract-declarator RPAREN postfixing-abstract-declarator
pointer-operator-type
: TYPEDEFname CLCL STAR type-qualifier-list-opt
| STAR type-qualifier-list
| AMPERSAND type-qualifier-list
primary-expression
: constant
| string-literal-list
| THIS
| LPAREN expression RPAREN
| operator-function-name
| identifier-or-key-word
| qualified-id
operator-function-name
: OPERATOR operator-predefined
| OPERATOR basic-type-name
| OPERATOR TYPEDEFname
| OPERATOR LPAREN type-name RPAREN
| OPERATOR type-qualifier
| OPERATOR qualified-type
operator-predefined
: PLUS
| MINUS
| STAR
| ...
| DELETE
| COMMA
type-qualifier-list-opt
: [ type-qualifier-list ]
postfix-expression
: primary-expression
| postfix-expression LBRACKET expression RBRACKET
| postfix-expression PARENS
| postfix-expression LPAREN argument-expression-list RPAREN
| postfix-expression LPAREN type-name-list RPAREN
| postfix-expression DOT id-expression
| postfix-expression ARROW id-expression
| postfix-expression INCR
| postfix-expression DECR
| TYPEDEFname LPAREN argument-expression-list RPAREN
| TYPEDEFname LPAREN type-name-list RPAREN
| basic-type-name LPAREN assignment-expression RPAREN
type-name-list
: type-name
| type-name COMMA type-name-list
| type-name comma-opt-ellipsis
| ELLIPSIS
comma-opt-ellipsis
: ELLIPSIS
| COMMA ELLIPSIS
unary-expression
: postfix-expression
| INCR unary-expression
| DECR unary-expression
| line-address
| AMPERSAND cast-expression
| STAR cast-expression
| MINUS cast-expression
| PLUS cast-expression
| TWIDDLE LPAREN cast-expression RPAREN
| NOT cast-expression
| SIZEOF unary-expression
| SIZEOF LPAREN type-name RPAREN
| allocation-expression
allocation-expression
: operator-new LPAREN type-name RPAREN operator-new-initializer
| operator-new LPAREN argument-expression-list RPAREN LPAREN type-name RPAREN operator-new-initializer
operator-new
: NEW
| CLCL NEW
operator-new-initializer
: [ PARENS ]
| [ LPAREN argument-expression-list RPAREN ]
cast-expression
: unary-expression
| LPAREN type-name RPAREN cast-expression
deallocation-expression
: cast-expression
| DELETE deallocation-expression
| CLCL DELETE deallocation-expression
| DELETE BRACKETS deallocation-expression
| CLCL DELETE BRACKETS deallocation-expression
point-member-expression
: deallocation-expression
| point-member-expression DOTstar deallocation-expression
| point-member-expression ARROWstar deallocation-expression
multiplicative-expression
: point-member-expression
| multiplicative-expression STAR point-member-expression
| multiplicative-expression SLASH point-member-expression
| multiplicative-expression MOD point-member-expression
additive-expression
: multiplicative-expression
| additive-expression PLUS multiplicative-expression
| additive-expression MINUS multiplicative-expression
shift-expression
: additive-expression
| shift-expression LS additive-expression
| shift-expression RS additive-expression
relational-expression
: shift-expression
| relational-expression LESS shift-expression
| relational-expression GREATER shift-expression
| relational-expression LE shift-expression
| relational-expression GE shift-expression
equality-expression
: relational-expression
| equality-expression EQ relational-expression
| equality-expression NE relational-expression
AND-expression
: equality-expression
| AND-expression AMPERSAND equality-expression
exclusive-OR-expression
: AND-expression
| exclusive-OR-expression HAT AND-expression
inclusive-OR-expression
: exclusive-OR-expression
| inclusive-OR-expression OR exclusive-OR-expression
logical-AND-expression
: inclusive-OR-expression
| logical-AND-expression ANDAND inclusive-OR-expression
logical-OR-expression
: logical-AND-expression
| logical-OR-expression OROR logical-AND-expression
conditional-expression
: logical-OR-expression
| logical-OR-expression QUESTION expression COLON conditional-expression
assignment-expression
: conditional-expression
| unary-expression ASSIGNOP assignment-expression
| unary-expression MULTassign assignment-expression
| unary-expression DIVassign assignment-expression
| unary-expression MODassign assignment-expression
| unary-expression PLUSassign assignment-expression
| unary-expression MINUSassign assignment-expression
| unary-expression LSassign assignment-expression
| unary-expression RSassign assignment-expression
| unary-expression ANDassign assignment-expression
| unary-expression ERassign assignment-expression
| unary-expression ORassign assignment-expression
identifier-or-typedef-name
: identifier-or-key-word
| TYPEDEFname
| PROCEDUREname
real-or-imag-part
: real_constant
| PLUS real_constant
| MINUS real_constant
| integer_constant
| PLUS integer_constant
| MINUS integer_constant
constant
: real_constant
| integer_constant
| complex-constant
| character_constant
| LOGICALconstantWithKind
character_constant
: CHARACTERconstantWithKind
| string
complex-constant
: LPAREN real-or-imag-part COMMA real-or-imag-part RPAREN
qual-typedef-opt
: TYPEDEFname /* Base (global) name */
| qual-typedef-opt TICK TYPEDEFname /* Qualified name */
whatis-expressions
: expression
| rescoped-expression
| printable_type
call-expression
: call-stmt
call-stmt
: named-subroutine
| named-subroutine LPAREN RPAREN
| named-subroutine LPAREN actual-arg-spec-list RPAREN
address
: line-address
| primary
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
Restrictions and limits are documented here.
loc
: expression
| rescoped-expression
type-name
: TYPEDEFname
printable-type
: rescoped-typedef
| type-name
expression
: expr
| named-procedure
assignment-expression
: expr
constant-expression
: constant
unary-expression
: variable
expr
: level-5-expr
| expr defined-binary-op level-5-expr
level-5-expr
: equiv-operand
| level-5-expr LOGEQV equiv-operand
| level-5-expr LOGNEQV equiv-operand
| level-5-expr LOGXOR equiv-operand
equiv-operand
: or-operand
| equiv-operand LOGOR or-operand
or-operand
: and-operand
| or-operand LOGAND and-operand
and-operand
: level-4-expr
| LOGNOT and-operand
level-4-expr
: level-3-expr
| level-3-expr LESS level-3-expr
| level-3-expr GREATER level-3-expr
| level-3-expr LE level-3-expr
| level-3-expr GE level-3-expr
| level-3-expr EQ level-3-expr
| level-3-expr NE level-3-expr
level-3-expr
: level-2-expr
| level-3-expr SLASHSLASH level-2-expr
level-2-expr
: add-operand
| level-2-expr PLUS add-operand
| level-2-expr MINUS add-operand
add-operand
: add-operand-f90
| add-operand-dec
| unary-expr-dec
add-operand-f90
: mult-operand-f90
| add-operand-f90 STAR mult-operand-f90
| add-operand-f90 SLASH mult-operand-f90
mult-operand-f90
: level-1-expr
| level-1-expr STARSTAR mult-operand-f90
add-operand-dec
: mult-operand-dec
| add-operand-f90 STAR mult-operand-dec
| add-operand-f90 SLASH mult-operand-dec
| add-operand-f90 STAR unary-expr-dec
| add-operand-f90 SLASH unary-expr-dec
mult-operand-dec
: level-1-expr STARSTAR mult-operand-dec
| level-1-expr STARSTAR unary-expr-dec
unary-expr-dec
: PLUS add-operand
| MINUS add-operand
level-1-expr
: primary
| defined-unary-op primary
defined-unary-op
: DOT_LETTERS_DOT
primary
: constant
| variable
| function-reference
| LPAREN expr RPAREN
| AMPERSAND variable
defined-binary-op
: DOT_LETTERS_DOT
int-expr
: expr
scalar-int-expr
: int-expr
variable
: named-variable
| subobject
named-variable
: variable-name
subobject
: array-elt-or-sect
| structure-component
| known-substring
known-substring
: disabled-array-elt-or-sect LPAREN substring-range RPAREN
| hf-array-abomination
substring-range
: scalar-int-expr COLON scalar-int-expr
| scalar-int-expr COLON
| COLON scalar-int-expr
| COLON
hf-array-abomination
: named-variable
LPAREN section-subscript-list RPAREN
LPAREN section-subscript RPAREN
| structure PERCENT any-identifier
LPAREN section-subscript-list RPAREN
LPAREN section-subscript RPAREN
| structure DOT any-identifier
LPAREN section-subscript-list RPAREN
LPAREN section-subscript RPAREN
disabled-array-elt-or-sect
: DISABLER array-elt-or-sect
array-elt-or-sect
: named-variable LPAREN section-subscript-list RPAREN
| structure PERCENT any-identifier LPAREN section-subscript-list RPAREN
| structure DOT any-identifier LPAREN section-subscript-list RPAREN
section-subscript-list
: section-subscript
| section-subscript COMMA section-subscript-list
subscript
: scalar-int-expr
section-subscript
: subscript
| subscript-triplet
subscript-triplet
: subscript COLON subscript COLON stride
| subscript COLON COLON stride
| COLON subscript COLON stride
| COLON COLON stride
| subscript COLON subscript
| subscript COLON
| COLON subscript
| COLON
stride
: scalar-int-expr
structure-component
: structure PERCENT any-identifier
| structure DOT any-identifier
structure
: named-variable
| structure-component
| array-elt-or-sect
function-reference
: SIZEOF LPAREN expr RPAREN
| named-function LPAREN RPAREN
| named-function LPAREN actual-arg-spec-list RPAREN
named-procedure
: PROCEDUREname
named-function
: PROCEDUREname
named-subroutine
: PROCEDUREname
actual-arg-spec-list
: actual-arg-spec
| actual-arg-spec COMMA actual-arg-spec-list
actual-arg-spec
: actual-arg
actual-arg
: expr
any-identifier
: variable-name
| PROCEDUREname
variable-name
: identifier-or-key-word
PROCEDUREname
: IDENTIFIER
constant
: FLOATINGconstant
| INTEGERconstant
| CHARACTERconstant
Ada Rescoped Expressions
qual-typedef-opt
: TYPEDEFname
| qual-symbol-opt TICK TYPEDEFname
whatis-expressions
: expression
| rescoped-expression
| printable_type
Ada Calls
call-expression
: expression
Ada Addresses
address
: line-address
| AMPERSAND postfix_expression
| LPAREN postfix_expression RPAREN
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
Ada Loc Specification
loc
: expression
| rescoped-expression
Ada Types
type-specifier
: typedef-type-specifier
typedef-type-specifier
: TYPEDEFname
identifier-or-typedef-name
: identifier-or-key-word
| TYPEDEFname
type-name
: type-specifier
| type-specifier abstract-declarator
printable-type
: rescoped-typedef
| type-name
Other Forms of Ada Expressions
primary-expression
: identifier-or-key-word
| constant
| string-literal-list
| LPAREN expression RPAREN
postfix-expression
: primary-expression
| postfix-expression LBRACKET expression RBRACKET
| postfix-expression LPAREN arg-expression-list-opt RPAREN
| postfix-expression DOT identifier-or-typedef-name
| postfix-expression ARROW identifier-or-typedef-name
| postfix-expression INCR
| postfix-expression DECR
string-literal-list
: string
| string-literal-list string
unary-expression
: postfix-expression
| INCR unary-expression
| DECR unary-expression
| AMPERSAND cast-expression
| line-address
| STAR cast-expression
| PLUS cast-expression
| MINUS cast-expression
| TWIDDLE cast-expression
| NOT cast-expression
cast-expression
: unary-expression
| LPAREN type-name RPAREN cast-expression
multiplicative-expression
: cast-expression
| multiplicative-expression STAR cast-expression
| multiplicative-expression SLASH cast-expression
| multiplicative-expression MOD cast-expression
additive-expression
: multiplicative-expression
| additive-expression PLUS multiplicative-expression
| additive-expression MINUS multiplicative-expression
shift-expression
: additive-expression
| shift-expression LS additive-expression
| shift-expression RS additive-expression
relational-expression
: shift-expression
| relational-expression LESS shift-expression
| relational-expression GREATER shift-expression
| relational-expression LE shift-expression
| relational-expression GE shift-expression
equality-expression
: relational-expression
| equality-expression EQ relational-expression
| equality-expression NE relational-expression
AND-expression
: equality-expression
| AND-expression AMPERSAND equality-expression
exclusive-OR-expression
: AND-expression
| exclusive-OR-expression HAT AND-expression
inclusive-OR-expression
: exclusive-OR-expression
| inclusive-OR-expression OR exclusive-OR-expression
logical-AND-expression
: inclusive-OR-expression
| logical-AND-expression ANDAND inclusive-OR-expression
logical-OR-expression
: logical-AND-expression
| logical-OR-expression OROR logical-AND-expression
conditional-expression
: logical-OR-expression
| logical-OR-expression QUESTION expression COLON conditional-expression
assignment-expression
: conditional-expression
| unary-expression ASSIGNOP assignment-expression
| unary-expression MULTassign assignment-expression
| unary-expression DIVassign assignment-expression
| unary-expression MODassign assignment-expression
| unary-expression PLUSassign assignment-expression
| unary-expression MINUSassign assignment-expression
| unary-expression LSassign assignment-expression
| unary-expression RSassign assignment-expression
| unary-expression ANDassign assignment-expression
| unary-expression ERassign assignment-expression
| unary-expression ORassign assignment-expression
expression
: assignment-expression
constant-expression
: conditional-expression
abstract-declarator
: unary-abstract-declarator
| postfix-abstract-declarator
| postfixing-abstract-declarator
postfixing-abstract-declarator
: array-abstract-declarator
| LPAREN RPAREN
array-abstract-declarator
: BRACKETS
| LBRACKET constant-expression RBRACKET
| array-abstract-declarator LBRACKET constant-expression RBRACKET
unary-abstract-declarator
: STAR
| STAR abstract-declarator
postfix-abstract-declarator
: LPAREN unary-abstract-declarator RPAREN
| LPAREN postfix-abstract-declarator RPAREN
| LPAREN postfixing-abstract-declarator RPAREN
| LPAREN unary-abstract-declarator RPAREN postfixing-abstract-declarator
constant
: FLOATINGconstant
| INTEGERconstant
| DECIMALconstant
| CHARACTERconstant
constant-expression
: cobol-expression
COBOL Rescoped Expressions
qual-typedef-opt
: TYPEDEFname
| qual-typedef-opt TICK TYPEDEFname
COBOL Calls
call-expression
: identifier-or-key-word
| identifier-or-key-word USING cobol-expression-list
COBOL Addresses
address
: INTEGERconstant
| line-address
| address-language
| LPAREN cobol-expression RPAREN
address-exp
: address
| address-exp PLUS address
| address-exp MINUS address
| address-exp STAR address
address-language
: AMPERSAND cobol-identifier
| REFERENCEOF cobol-identifier
COBOL Loc
loc
: cobol-identifier
| rescoped-expression
COBOL Types
printable-type
: rescoped-typedef
Other Forms of COBOL Expressions
assignment-expression
: expression
cobol-expression
: cobol-identifier
| constant
| string
| cobol-expression PLUS cobol-expression
| cobol-expression MINUS cobol-expression
| cobol-expression STAR cobol-expression
| cobol-expression SLASH cobol-expression
| cobol-expression EXPON cobol-expression
| MINUS cobol-expression
| PLUS cobol-expression
| LPAREN cobol-expression RPAREN
cobol-expression-list
: cobol-expression
| cobol-expression COMMA cobol-expression-list
cobol-identifier
: qualification
| subscript
| refmod
condition-expression
: combined-condition
| negated-simple-condition
combined-condition
: negated-simple-condition AND negated-simple-condition
| negated-simple-condition OR negated-simple-condition
| LPAREN combined-condition RPAREN
negated-simple-condition
: simple-condition
| NOT simple-condition
| LPAREN NOT simple-condition RPAREN
simple-condition
: cobol-expression EQ cobol-expression
| cobol-expression ASSIGNOP cobol-expression
| cobol-expression NE cobol-expression
| cobol-expression LESS cobol-expression
| cobol-expression GREATER cobol-expression
| cobol-expression LE cobol-expression
| cobol-expression GE cobol-expression
| cobol-expression SIGNPOS
| cobol-expression SIGNNEG
| cobol-expression SIGNZERO
| cobol-expression SIGNNOTZERO
| LPAREN simple-condition RPAREN
expression
: constant-expression
| condition-expression
| address-language
identifier-or-typedef-name
: identifier-or-key-word
lvalue-expression
: cobol-identifier
qualification
: identifier-or-key-word OF qualification
| identifier-or-key-word
refmod
: qualification LPAREN cobol-expression COLON RPAREN
| qualification LPAREN cobol-expression COLON cobol-expression RPAREN
| subscript LPAREN cobol-expression COLON RPAREN
| subscript LPAREN cobol-expression COLON cobol-expression RPAREN
subscript
: qualification LPAREN cobol-expression-list RPAREN
unary-expression
: lvalue-expression
whatis-expressions
: expression
| rescoped-expression
| rescoped-typedef
core
and places it in the current directory.
The core file is not an executable file; it is a snaphot of the state of
your process at the time the error occurred. It allows you to analyze the
process at the point it crashed.
This chapter discusses the following topics:
It also contains a core file debugging example and a quick reference for transporting a core file % ladebug executable_file core_file
or
(ladebug) load executable_file core_file
The executable file is that which was being executed at the time the core file
was generated.
The stack trace lists the functions in your program that were active when the
dump occurred. By examining the values of a few variables along with
the stack trace, you may be able to pinpoint the process state and the cause
of the core dump. Core files cannot be executed; therefore the rerun
,
step
, cont
and so on commands will not work until you create
a process using the run
command.
In addition, if the program is multithreaded, you can examine the thread
information with the
show thread
and
thread
commands. You can
examine the stack trace for a particular thread or for all threads with the
where thread
command.
The following example uses a null pointer reference in the factorial
function.
This reference causes the process to abort and dump the core when it is
executed. The dump
command prints the value of the x
variable
as a null, and the print *x
command reveals that you cannot
dereference a null pointer.
% cat testProgram.c
#include <stdio.h>
int factorial(int i)
main() {
int i,f;
for (i=1 ; i<3 ; i++) {
f = factorial(i);
printf("%d! = %d\en",i,f);
}
}
int factorial(int i)
int i;
{
int *x;
x = 0;
printf("%d",*x);
if (i<=1)
return (1);
else
return (i * factorial(i-1) );
}
% cc -o testProgram -g testProgram.c
% testProgram
Memory fault - core dumped.
% ladebug testProgram core
Welcome to the Ladebug Debugger Version n
------------------
object file name: testProgram
core file name: core
Reading symbolic information ...done
Core file produced from executable testProgram
Thread terminated at PC 0x120000dc4 by signal SEGV
(ladebug) where
>0 0x120000dc4 in factorial(i=1) testProgram.c:13
#1 0x120000d44 in main() testProgram.c:4
(ladebug) dump
>0 0x120000dc4 in factorial(i=1) testProgram.c:13
printf("%d",*x);
(ladebug) print *x
Cannot dereference 0x0
Error: no value for *x
(ladebug)
a.out
is the name of the executable and
core
is the name of the core file.
You need to collect a variety of files from the original system. These
include the executable, the core file, shared libraries used by the
executable, and /usr/shlib/libpthreaddebug.so
if the POSIX Threads
Library is involved.
Do the following steps (1 through 4) on the original system:
% ladebug a.out core
(ladebug) listobj
(ladebug) quit
/usr/shlib/
.
/usr/shlib/libpthread.so
is one of the files, add
/usr/shlib/libpthreaddebug.so
to the list.
(If you have a privately delivered libpthread.so
, there
should be a privately delivered corresponding libpthreaddebug.so
; use
the privately delivered one.)
a.out
, core
and shared objects,
for example, into a
tar
file. Be sure to use the tar h
option to force tar
to
follow symbolic links as if they were normal files or directories.
% tar cfvh mybug.tar
On the current system, the executable and core file are generally put in the
current working directory, the shared objects are put in an "application"
subdirectory, and libpthreaddebug.so
is put in a "debugger"
subdirectory.
% mkdir mybug
% cd mybug
% mv <wherever>/mybug.tar .
applibs
and dbglibs
:
% mkdir applibs dbglibs
tar s
option to strip off
any leading slashes from pathnames during extraction.
% tar xfvs mybug.tar
/usr/shlib
and are now in usr/shlib
) into applibs
:
% mv usr/shlib/* applibs
If the tar xfvs
output in step 9 moved shared objects into other
directories, move them into applibs
as well.
libpthreaddebug.so
exist in the dbglibs
directory,
for example, by linking it to the file in the applibs
directory.
% ln -s ../applibs/libpthreaddebug.so dbglibs/libpthreaddebug.so
libpthreaddebug.so.
% env LADEBUG_COREFILE_LIBRARY_PATH=applibs \
LD_LIBRARY_PATH=dbglibs \
ladebug a.out core
applibs
subdirectory
rather than in /usr/shlib/
:
(ladebug) listobj
For an alternative method when the debugger cannot be run on the original
system, see the corefile_listobj.c
example.
(ladebug)
% a.out -segv
Segmentation fault (core dumped)
% ladebug a.out core
Welcome to the Ladebug Debugger Version 4.0-n
------------------
object file name: a.out
core file name: core
Reading symbolic information ...done
Core file produced from executable a.out
Thread 0x5 terminated at PC 0x3ff8058b448 by signal SEGV
(ladebug) listobj
section Start Addr End Addr
------------------------------------------------------------------------------
a.out
.text 0x120000000 0x120003fff
.data 0x140000000 0x140001fff
/usr/shlib/libpthread.so
.text 0x3ff80550000 0x3ff8058bfff
.data 0x3ffc0180000 0x3ffc018ffff
.bss 0x3ffc0190000 0x3ffc01901af
/usr/shlib/libmach.so
.text 0x3ff80530000 0x3ff8053ffff
.data 0x3ffc0170000 0x3ffc0173fff
/usr/shlib/libexc.so
.text 0x3ff807b0000 0x3ff807b5fff
.data 0x3ffc0210000 0x3ffc0211fff
/usr/shlib/libc.so
.text 0x3ff80080000 0x3ff8019ffff
.data 0x3ffc0080000 0x3ffc0093fff
.bss 0x3ffc0094000 0x3ffc00a040f
(ladebug) quit
libpthread.so
is included, so add
/usr/shlib/libpthreaddebug.so
to the list.
% tar cfv mybug.tar a.out core \
/usr/shlib/libpthread.so /usr/shlib/libmach.so \
/usr/shlib/libexc.so /usr/shlib/libc.so \
/usr/shlib/libpthreaddebug.so
a a.out 128 Blocks
a core 2128 Blocks
a /usr/shlib/libpthread.so 928 Blocks
a /usr/shlib/libmach.so 208 Blocks
a /usr/shlib/libexc.so 96 Blocks
a /usr/shlib/libc.so symbolic link to ../../shlib/libc.so
a /usr/shlib/libpthreaddebug.so 592 Blocks
Note that libc.so
is a symbolic link. Therefore, use
the tar
h
option to force tar
to follow symbolic
links as if they were normal files or directories:
% tar hcfv mybug.tar a.out core \
/usr/shlib/libpthread.so /usr/shlib/libmach.so \
/usr/shlib/libexc.so /usr/shlib/libc.so \
/usr/shlib/libpthreaddebug.so
a a.out 128 Blocks
a core 2128 Blocks
a /usr/shlib/libpthread.so 928 Blocks
a /usr/shlib/libmach.so 208 Blocks
a /usr/shlib/libexc.so 96 Blocks
a /usr/shlib/libc.so 3193 Blocks
a /usr/shlib/libpthreaddebug.so 592 Blocks
Now you have a package that you can transport.
% mkdir mybug
% cd mybug
% mv <wherever>/mybug.tar .
tar
file
using the s
option:
% mkdir applibs dbglibs
% tar xfvs mybug.tar
blocksize = 256
x a.out, 65536 bytes, 128 tape blocks
x core, 1089536 bytes, 2128 tape blocks
x usr/shlib/libpthread.so, 475136 bytes, 928 tape blocks
x usr/shlib/libmach.so, 106496 bytes, 208 tape blocks
x usr/shlib/libexc.so, 49152 bytes, 96 tape blocks
x usr/shlib/libc.so, 1634400 bytes, 3193 tape blocks
x usr/shlib/libpthreaddebug.so, 303104 bytes, 592 tape blocks
applibs
, and make
libpthreaddebug.so
exist in the dbglibs
directory,
for example, by linking it to the file in the applibs
directory:
% mv usr/shlib/* applibs
% ln -s ../applibs/libpthreaddebug.so dbglibs/libpthreaddebug.so
In this example, all shared objects were in usr/shlib/
, so no other
moving is needed.
% ls -lR
total 4904
-rwxr-xr-x 1 user1 ladebug 65536 Sep 17 11:20 a.out*
drwxrwxr-x 2 user1 ladebug 8192 Sep 17 11:36 applibs/
-rw------- 1 user1 ladebug 1089536 Sep 17 11:21 core
drwxrwxr-x 2 user1 ladebug 8192 Sep 17 11:24 dbglibs/
-rw-rw-r-- 1 user1 ladebug 3737600 Sep 17 11:23 mybug.tar
drwxrwxr-x 3 user1 ladebug 8192 Sep 17 11:36 usr/
./applibs:
total 2632
-rw-r--r-- 1 user1 ladebug 1634400 Dec 7 1998 libc.so
-rw-r--r-- 1 user1 ladebug 49152 Jun 26 1998 libexc.so
-rw-r--r-- 1 user1 ladebug 106496 Dec 29 1997 libmach.so
-rw-r--r-- 1 user1 ladebug 475136 Dec 7 1998 libpthread.so
-rw-r--r-- 1 user1 ladebug 303104 Dec 7 1998 libpthreaddebug.so
./dbglibs:
total 0
lrwxrwxrwx 1 user1 ladebug 29 Sep 17 11:24 libpthreaddebug.so@ -> ../applibs/libpthreaddebug.so
./usr:
total 8
drwxrwxr-x 2 user1 ladebug 8192 Sep 17 11:36 shlib/
./usr/shlib:
total 0
%
If other files need to be moved into applibs
, do
that as well and then re-observe the file system. In this example, there
are none.
% env LADEBUG_COREFILE_LIBRARY_PATH=applibs \
LD_LIBRARY_PATH=dbglibs \
ladebug a.out core
Welcome to the Ladebug Debugger Version 4.0-n
------------------
object file name: a.out
core file name: core
Reading symbolic information ...done
Core file produced from executable a.out
Thread 0x5 terminated at PC 0x3ff8058b448 by signal SEGV
listobj
command to ensure the application libraries
are coming from applibs/
. Find any that are not,
either from the original system, or unpacked from the tar file but
not yet moved into applibs
.
(ladebug) listobj
section Start Addr End Addr
------------------------------------------------------------------------------
a.out
.text 0x120000000 0x120003fff
.data 0x140000000 0x140001fff
applibs/libpthread.so
.text 0x3ff80550000 0x3ff8058bfff
.data 0x3ffc0180000 0x3ffc018ffff
.bss 0x3ffc0190000 0x3ffc01901af
applibs/libmach.so
.text 0x3ff80530000 0x3ff8053ffff
.data 0x3ffc0170000 0x3ffc0173fff
applibs/libexc.so
.text 0x3ff807b0000 0x3ff807b5fff
.data 0x3ffc0210000 0x3ffc0211fff
applibs/libc.so
.text 0x3ff80080000 0x3ff8019ffff
.data 0x3ffc0080000 0x3ffc0093fff
.bss 0x3ffc0094000 0x3ffc00a040f
(ladebug) where
>0 0x3ff8058b448 in nxm_thread_kill(0x140091c68, 0xb, 0x1, 0x0, 0x0, 0xfffffffffffffcc0) in applibs/libpthread.so
#1 0x3ff80578c58 in pthread_kill(0x140091c68, 0xb, 0x1, 0x0, 0x0, 0xfffffffffffffcc0) in applibs/libpthread.so
#2 0x3ff8056cd34 in UnknownProcedure3FromFile69(0x140091c68, 0xb, 0x1, 0x0, 0x0, 0xfffffffffffffcc0) in applibs/libpthread.so
#3 0x3ff807b22d8 in UnknownProcedure4FromFile1(0x140091c68, 0xb, 0x1, 0x0, 0x0, 0xfffffffffffffcc0) in applibs/libexc.so
#4 0x3ff807b3824 in UnknownProcedure17FromFile1(0x140091c68, 0xb, 0x1, 0x0, 0x0, 0xfffffffffffffcc0) in applibs/libexc.so
#5 0x3ff807b3864 in exc_unwind(0x140091c68, 0xb, 0x1, 0x0, 0x0, 0xfffffffffffffcc0) in applibs/libexc.so
#6 0x3ff807b3af0 in exc_raise_signal_exception(0x140091c68, 0xb, 0x1, 0x0, 0x0, 0xfffffffffffffcc0) in applibs/libexc.so
#7 0x3ff8057a328 in UnknownProcedure6FromFile80(0x140091c68, 0xb, 0x1, 0x0, 0x0, 0xfffffffffffffcc0) in applibs/libpthread.so
#8 0x3ff800d6a30 in __sigtramp(0x140091c68, 0xb, 0x1, 0x0, 0x0, 0xfffffffffffffcc0) in applibs/libc.so
#9 0x120001d94 in mandel_val(cr=0.01, ci=0.16, nmin=0, nmax=255) "mb_pi.c":62
#10 0x12000274c in smp_fill_in_data(raw_mthread=0x11fffe998) "mb_pi.c":338
#11 0x3ff80582068 in thdBase(0x0, 0x2, 0x0, 0x0, 0xff, 0x1) in applibs/libpthread.so
(ladebug) quit
%
First, do the following steps on the original system:
ladebug a.out core
listobj; quit
/usr/shlib/libpthreaddebug.so
, if libpthread.so
tar cfvh mybug.tar a.out core <shlibs>
mkdir mybug
cd mybug
mv mybug.tar
mkdir applibs dbglibs
tar sfvc mybug.tar
mv usr/shlib/* applibs
ln -s ../applibs/libptheaddebug.so dbglib/libptheaddebug.so
cd dbglibs
ln -s ../applibs/libpthreaddebug.so libpthreaddebug.so
cd ..
env LADEBUG_COREFILE_LIBRARY_PATH=applibs \
LD_LIBRARY_PATH=dbglibs \
ladebug a.out core
listobj
This chapter discusses kernel debugging, and contains sections for each type of kernel debugging that you may use.
This chapter contains the following sections:
Local kernel debugging is useful for examining the state of the running kernel, or any of its modules or components. If a process is hung, a system administrator might want to debug the kernel to find out what the process is caught on. The debugger has no ability to stop a local kernel, because that will stop the debugger too.
When a local kernel crashes, systems personnel typically want to know why. The kernel has been designed to save a copy of its memory state to a core file just before crashing. A copy of the kernel that crashed is also saved. These two files can be loaded into the debugger, and the state of the kernel just prior to the crash can be examined, to determine what went wrong.
Remote kernel debugging is useful for systems engineers who are building and testing kernels, and who need to have more control over the kernel. Breakpoints can be set in a kernel that is debugged remotely, which allow it to be stopped and examined more closely. Remote kernel debugging requires at least two machines, with the debugger running on one and the kernel to be tested on the other.
The kernel is typically owned by root, so you may need to be the superuser
(root
login) to examine either the running system or crash dumps.
Whether or not you need to be the superuser to debug a kernel directly depends
on the directory and file protections of the files you attempt to examine.
Ideally, the kernel should be compiled without full optimization and without stripping the kernel of its symbol table information, so that the debugger can provide you with the most information in a most friendly manner. However, most of the time this is not the case, and you are working with a stripped-down, highly optimized kernel. In these cases the debugger is limited in what it can display. Information relating to source files is not available, and often function parameters and other variables are "optimized away."
The kernel is a complex piece of software. It contains kernel processes denoted by a process ID, or pid. Some of these processes relate to user processes, and some are kernel-specific.
NOTE: Because the debugger supports multi-processing as well as kernel debugging, we need to be able to distinguish between processes that the debugger is managing, and processes being managed within the kernel.
Because the debugger command for managing multiple processes is
process
, we
will refer to a process being debugged as a process, and we will
refer to a process within the kernel being debugged as a pid.
The debugger maintains two extra debugger variables when debugging a kernel:
$pid
and $tid
. These variables assist
the user in establishing and changing the user context while debugging the
kernel.
The $pid
variable contains the current pid that you are
examining. You can switch the context to another pid within the kernel by
setting $pid
to the desired value. The debugger variable
$curprocess
, which is read-only,
does not change. The value in the $curprocess
variable is how the
debugger refers to the kernel process as a whole. Typically, this value is
the actual kernel process listed as [kernel idle]
with the
ps
system command (or ladebug kps command - see below), but
not always. In any case, the $pid variable controls the pid that you are
examining within the kernel.
The $tid
variable contains the current thread ID that you
are examining. It, too, can be used to switch the user context to a different
thread (it simply calls the
thread
command with its new value).
The debugger also supplies a kps
command, which displays all
the pids in the kernel:
kernel_debugging_command
: kps
For example, if you wanted to examine the stack of the kloadsrv
daemon, you would first find out its pid:
(ladebug) kps
00000 kernel idle
00001 init
00003 kloadsrv
00020 update
02082 dtexec
02092 dtterm
02093 csh
...
And then set the $pid
accordingly and enter the
where
command:
(ladebug) set $pid = 3 (ladebug) where >0 0xfffffc00002b3a10 in thread_block()
From within the debugger, you can use the
patch
command to
correct bad data or instructions in an executable disk file. You can patch the text,
initialized data, or read-only data areas. You cannot patch the bss
segment because it does not exist in disk files. For example:
(ladebug) patch @foo = 20
You can specify addresses in the KSEG segment by prefixing the
hexadecimal offset of the address with 0k
; the debugger will add the
KSEG base address to any such hexadecimal constant. For example,
the constant 0k2400
will be converted by Ladebug into the
actual address for the location at offset 0x2400 into the KSEG segment.
When you have a problem with a process, you can debug the running kernel or examine the values assigned to system parameters. (It is generally recommended that you avoid modifying the value of the parameters, which can cause problems with the kernel.)
Invoke the debugger with the following command:
# ladebug -k /vmunix /dev/mem
The -k
flag maps virtual to physical addresses to
enable local kernel debugging. The /vmunix
and
/dev/mem
parameters cause the debugger to operate
on the running kernel (the /dev/mem
parameter is
optional when debugging the live kernel, the debugger knows to look there for
the kernel address space).
Now you can use debugger commands to display information such as the current
list of pids (kps
), and trace the execution of processes. Note that
the debugger motion commands such as cont, next, rerun, run, step,
return,
and stop
are not
available, nor can you change values in registers when you do local kernel
debugging (stopping the kernel would also stop the debugger).
If your system panics or crashes, you can often find the cause by using the debugger to analyze a crash dump. Keep in mind that the debugger is only one useful tool for determining the cause of a crash. Other tools and techniques are available to system personnel to aid in analyzing crash dumps. Some of them are mentioned briefly here.
NOTE: You cannot perform crash dump analysis remotely with this debugger.
The operating system can crash in the following ways:
trap()
function being invoked.
panic()
function.
If the system crashes because of a hardware fault or an unrecoverable software
state, a dump function is invoked. The dump function copies the core memory
into the primary default swap disk area as specified by the
/etc/fstab
file structure table and the
/sbin/swapdefault
file. At system reboot time, the information is
copied into a file, called a crash dump file. Crash dump files are either
partial (the default) or full. See Compaq TRU64 UNIX Kernel
Debugging for more information.
You can analyze the crash dump file to determine what caused the crash. For
example, if a hardware trap occurred, you can examine variables, such as
savedefp
, the program counter ($pc
), and the stack
pointer ($sp
), to help you determine why the crash occurred. If a
software panic caused the crash, you can use the debugger to examine the crash
dump and use the uerf
utility to examine the error log. Using these
tools, you can determine which function called the panic()
routine.
In examining crash dump files, there is no one way to determine the cause of a system crash. However, the following guidelines should help you identify the events that led to the crash:
pmsgbuf
, and in the
panicstr
global variable.
where
command.) Most likely, this thread will contain the
events that led to the panic.
For more information and for examples, see Compaq TRU64 UNIX Kernel Debugging. This manual contains detailed information on the following topics related to crash dump analysis:
crashdc
utility
You can find Compaq Tru64 UNIX crash dump files in /var/adm/crash
.
There you will find a copy of the kernel that crashed
(vmunix.number
) and the core memory file
(vmcore.number
or
vmzcore.number
, depending on the operating system
version). The number appended to these files distinguishes crashes, with the
highest number denoting the most recent crash. These files are owned by
root
, so you must have root permissions to access them.
To invoke the debugger on a kernel crash dump numbered "0", enter the following command:
# ladebug -k vmunix.0 vmzcore.0
On startup, the debugger analyzes the core file to determine the final PC address of the crash, and outputs that information. You can use the debugger to inspect kernel data structures, global variables (such as the panic string), and kernel thread stacks, in order to determine why the kernel crashed.
If you are going to view the stack using the
where
, up
,
down
, and dump
commands, you may want to set the control variable
$stackargs
to zero (0) to suppress
the output of argument values, The kernel is typically compiled for high
performance, which means those argument values have been optimized away. If
the debugger is set to look for those arguments and cannot find them, it
notifies the user with error messages, causing the stack output to be full of
repetitious warnings.
When debugging a kernel memory fault, verify that the core memory has not been
corrupted; otherwise, the debugger may present erroneous information. One quick
way to check this is by comparing the global panic string with the panic string
in the machine_slot
structure of the machine that caused the
crash. Select the appropriate machine_slot
structure name depending
on your operating system version, as follows:
machine_slot[paniccpu]
processor_ptr[paniccpu].m
If the strings are different, the core memory file may be corrupted. The following example shows how to compare these strings:
# ladebug -k vmunix.0 vmzcore.0 Welcome to the Ladebug Debugger Version 4.0-64 (built Nov 12 2000 for Compaq Tru64 UNIX) ------------------ object file name: vmunix.0 core file name: vmzcore.0 Reading symbolic information ...done Thread terminated at PC 0xfffffc0000457a48 done (ladebug) print panicstr 0xfffffc0000640970="kernel memory fault" <== memory fault (ladebug) print utsname struct utsname { sysname = "OSF1"; nodename = ""; release = "X5.1"; <== 5.n system version = "730"; machine = "alpha"; } (ladebug) print processor_ptr[paniccpu].m struct machine_slot { is_cpu = 1; cpu_type = 15; cpu_subtype = 22; running = 1; cpu_ticks = [0] = 0,[1] = 0,[2] = 0,[3] = 0,[4] = 0; clock_freq = 1200; error_restart = 0; cpu_panicstr = 0xfffffc0000640970="kernel memory fault"; <== strings match cpu_panic_thread = 0xfffffc0001c51180; }
When you debug your code by working with a crash dump file, you can examine the
exception frame using the debugger. The variable savedefp
contains
the location of the exception frame. (No exception frames are created when you
force a system to dump.) Refer to the header file
/usr/include/machine/reg.h
to determine where registers are stored
in the exception frame. The following example shows an exception frame:
(ladebug) print savedefp/33X ffffffff9618d940: 0000000000000000 fffffc000046f888 ffffffff9618d950: ffffffff86329ed0 0000000079cd612f . . . ffffffff9618da30: 0000000000901402 0000000000001001 ffffffff9618da40: 0000000000002000
You can use the debugger to extract the preserved message buffer from a running system or use dump files to display system messages logged by the kernel. For example:
(ladebug) print *pmsgbuf struct msgbuf { msg_magic = 405601; msg_bufx = 1851; msg_bufr = 1343; msg_bufc = "Alpha boot: available memory from 0x6ca000 to 0x3f16000\nTru64 UNIX V.n (Rev. 564); Fri Jul 11 11:25:29 EDT 1997 \nphysical m"; }
The print
command is regulated in length by the
$maxstrlen
debugger variable. Also,
the print
command does not expand the new-line character. To see the
full message string as formatted text, use the following command:
(ladebug) printf "%s",pmsgbuf->msg_bufc
The crashdc
utility collects critical data from operating system
crash dump files or from a running kernel. You can use the data it collects to
analyze the cause of a system crash. The crashdc
utility uses
existing system tools and utilities to extract information from crash dumps. The
information garnered from crash dump files or from the running kernel includes
the hardware and software configuration, current processes, the panic string (if
any), and swap information.
See Compaq TRU64 UNIX Kernel Debugging and
crashdc
(8) for more information.
For remote kernel debugging, the Ladebug debugger is used in conjunction with
the kdebug
debugger, which is a tool for executing, testing, and
debugging test kernels.
Used alone, kdebug
has its own syntax and commands, and allows
local non-symbolic debugging of a running kernel across a serial line. See
kdebug
(8) for information about kdebug
local
kernel debugging.
You use Ladebug commands to start and stop kernel execution, examine variable
and register values, and perform other debugging tasks, just as you would when
debugging user-space programs. The kdebug
debugger, not the Ladebug
debugger, performs the actual reads and writes to registers, memory, and the
image itself (for example, when breakpoints are set).
The kernel code to be debugged runs on a test system. The Ladebug debugger runs on a remote build system and communicates with the kernel code over a serial communication line or through a gateway system.
You use a gateway system when you cannot physically connect the test and build systems. The build system is connected to the gateway system over a network. The gateway system is connected to the test system by a serial communication line.
The following diagram shows the physical connection of the test and build systems (with no gateway):
Build system Serial line Test system (with the Ladebug <-------------------------> (kernel code here) debugger)The following diagram shows the connections when you use a gateway system:
Build system Network Gateway Serial line Test system (with the Ladebug <-----------> system <-------------> (kernel code debugger) with here) kdebug daemon
The serial line provides a physical connection between communication ports on two systems; it consists of a BC16E cable and two H8571-J DECconnect Passive Adapters:
The test system always uses the same communication port for kdebug
debugger input and output:
/dev/tty00
at installation time.
ace
console serial interface operating as the test system, this
device is always the serial communications port 2 identified as
/dev/tty01
.
The build or gateway system, whichever is at the other end of the serial line
from the test system, uses /etc/remote
to specify the device to use
for kdebug
debugger input and output. Serial communication ports 1
and 2 correspond to device names /dev/tty00
and
/dev/tty01
, respectively:
/dev/tty00
at installation time.
kdebug
in /etc/remote
. By
default, this device is the serial communications port 1 identified as
/dev/tty00
, but it may be changed if desired by modifying
/etc/remote
.
The following line in /etc/remote
defines /dev/tty00
as the device to use for kdebug
debugger input and output:
kdebug:dv=/dev/tty00:br#9600:pa=none:
For AlphaStation and AlphaServer systems, it is possible to change this
definition to /dev/tty01
so the same serial port can be used for
remote kernel debugging whether the system is used as a build, gateway, or test
system:
kdebug:dv=/dev/tty01:br#9600:pa=none:
The first field, kdebug
, is a label and has no significance except
as an identifier, and "kdebug" is the default name for the serial line used by
the debugger for kdebug
debugger input and output.
For AlphaStation and AlphaServer systems, it is also possible to redirect the test system console input and output to the build or gateway system at the other end of the serial line. This requires a second serial line connected between the communications ports of the build or gateway system and the test system that are not used for kdebug debugger input and output.
To configure a second serial line, follow these steps:>>> set console serial
This redirects all console input and output to serial communication port 1
(/dev/tty00
).
/etc/remote
file to
define this second line. For example, in order to change the serial line used
for kdebug
debugger input and output to /dev/tty01
and
create a useful label for /dev/tty00
to use for the test system
console input and output, replace the original definition for
kdebug
in /etc/remote
on the build or gateway system
with the following:
kdebug:dv=/dev/tty01:br#9600:pa=none: tstsys:dv=/dev/tty00:br#9600:pa=none:
% tip tstsys
You can use this separate window as the console for the test system.
>>> set console graphics
tip
on the build or gateway system by entering a
tilde and a period (˜.
).
The test, build, and (if used) gateway systems must meet the following
requirements for kdebug
:
Test system: Must be running Version 2.0 or higher of the Tru64 UNIX operating system, must have the Kernel Debugging Tools subset loaded, and must have the Kernel Breakpoint Debugger kernel option configured.
Build system: Must be running Version 3.2 or higher of the Tru64 UNIX operating system. Also, this system must contain a copy of the kernel code you are testing and, preferably, the source used to build that kernel code.
You can verify the status of each of the system requirements by the using the following commands:
Tru64 operating system version: Enter the command:
% uname -a
Kernel Debugging Tools subset: Enter the command:
% setld -i | grep -i kernel | grep installed
Kernel Breakpoint Debugger kernel option: There are two methods to verify this option:
% /sbin/sysconfig -s kdebug
This should indicate that kdebug
is loaded and configured.
Look for a file in /sys/config
with the same name as the
node in question, except in all uppercase characters. For example, if
the name of the node is "mine", look for a file named
/sys/config/MINE
and search it for a line containing
"options KDEBUG". If present, it means the Kernel Breakpoint Debugger
kernel option has been configured.
To use the kdebug
debugger, do the following:
Attach the test system and the build system or the test system and the gateway system. See your hardware documentation for information about connecting systems to serial lines and networks.
Recompile kernel files, if necessary. By default, the kernel is compiled
with only partial debugging information, occasionally causing the debugger
to display erroneous arguments or mismatched source lines. To correct this,
recompile selected source files specifying the CDEBUGOPTS=-g
argument.
Copy the kernel to be tested to /vmunix
on the test system.
Retain an exact copy of this image on the build system.
Install the Product Authorization Key (PAK) for the Developers' kit (OSF-DEV) if it is not already installed. For information about installing PAKs, see the Compaq Tru64 UNIX Installation Guide.
Determine the debugger variable settings or command-line options you will
use. On the build system, add the following lines to your
.dbxinit
file if you need to override the default values (and
you choose not to use the corresponding options).
Alternatively, you can use these lines within the debugger session, at the
(ladebug)
prompt:
(ladebug) set $kdebug_host="<name_of_your_gateway_system>" (ladebug) set $kdebug_line="<name_of_your_serial_line>" (ladebug) set $kdebug_dbgtty="<name_of_your_tty>"
$kdebug_host
specifies the node or address of the gateway
system. By default, $kdebug_host
is set to
localhost
, when a gateway system is not used. For example:
(ladebug) set $kdebug_host="decosf"
$kdebug_line
specifies the serial line to use as defined in
the /etc/remote
file of the build system (or the gateway
system, if one is being used). By default, $kdebug_line
is
set to kdebug
. For example:
(ladebug) set $kdebug_line="kdebug"
$kdebug_dbgtty
sets the terminal on the gateway system to
display the communication between the build and test systems, which is
useful in debugging your setup. To determine the terminal name to supply
to the $kdebug_dbgtty
variable, enter the tty
command in the desired window on the gateway system. By default,
$kdebug_dbgtty
is null. For example:
(ladebug) set $kdebug_dbgtty="/dev/ttyp2"
Instead of using debugger variables, you can specify any of the following
options on the ladebug
command line:
The -rn
option specifies the node or address of the gateway
system, and can be used instead of $kdebug_host
.
The -line
option specifies the serial line, and can be used
instead of $kdebug_line
.
The -tty
option specifies the terminal name, and can be
used instead of $kdebug_dbgtty
.
The preceding three options require the -remote
option or its
alternative, the -rp kdebug
option, for example:
# ladebug -remote -rn "decosf" -line "kdebug" -tty "/dev/ttyp2" /usr/test/vmunixThe
-rn
, -line
, and -tty
options on
this command line produce the same result as the preceding
set
command examples. This example assumes a
copy of the test system's vmunix
is in /usr/test
on the build system.
The variables you set in your .dbxinit
file override any
options you use on the ladebug
command line. In your debugging
session, you can still override the .dbxinit
variable settings
by using the set
command at the
(ladebug)
prompt, prior to issuing the
run
command.
If you are debugging on an symmetric multiprocessing (SMP) system , set the
lockmode
system attribute to 4, as shown:
# sysconfig -r lockmode = 4
Setting this system attribute makes debugging on an SMP system easier.
When the setup is complete, start the debugger as follows:
Invoke the Ladebug debugger on the build system, supplying the pathname of
the copy of the test kernel that resides on the build system. Set a
breakpoint and start running the Ladebug debugger as follows (assuming that
vmunix
resides in the /usr/test
directory):
# ladebug -remote /usr/test/vmunix ... (ladebug) stop in panic [2] stop in panic (ladebug) stop in ttyretype [3] stop in ttyretype
Because you cannot use Ctrl/C as an interrupt, set at least one breakpoint
if you want the debugger to gain control of kernel execution. You can set a
breakpoint any time after the execution of the
kdebug_bootstrap()
routine. Setting a breakpoint prior to the
execution of this routine can result in unpredictable behavior. Setting a
breakpoint in panic
enables regaining control after a panic, and
setting a breakpoint in ttyretype
enables returning control to
the debugger whenever Ctrl/R is entered at the console.
NOTE: Pressing Ctrl/C causes the remote debugger to exit, not to interrupt as it does during local debugging.
Halt the test system:
# shutdown -h now
At the console prompt, set the boot_osflags
console variable to
contain the value k
(the default is usually the value
a
). For example:
>>> set boot_osflags k
Alternatively, you can enter the following command:
>>> boot -flags k
You can abbreviate the boot
command to b
and the
-flags
option to -fl
. The
boot
command without the -flags
option boots the
machine using the current value for boot_osflags
; with the
-flags
option, it uses the value specified in the option and
does not change the value of the boot_osflags
console variable.
Other useful commands from the console prompt include show
,
which lists the values of console variables, and help
, which
provides information about other commands. For more information about the
boot_osflags
values, see the Compaq Tru64 UNIX
System Administration Manual and the Compaq Tru64 UNIX
Installation Guide.
With the Ladebug debugger started and waiting at a (ladebug)
prompt with breakpoints already set and the test system waiting at the
console prompt (>>>), start both the Ladebug debugger and test system kernel
executing. You can start them in either order as follows:
Start the Ladebug debugger:
(ladebug) run
Start the test system:
>>> bootor
>>> boot -flags k
If you set breakpoints in code that is executed on an SMP system, the breakpoints are handled serially. When a breakpoint is encountered on a particular CPU, the state of all the other processors in the system is saved and those processors spin, similar to how execution stops when a simple lock is obtained on a particular CPU.
When the breakpoint is dismissed (for example, because you entered a
step
or cont
command
to the debugger), processing resumes on all processors.
kdebug
setup and it fails to work, refer
to the following list for help:
Be sure the serial line is attached properly. Use the
tip
command to test the connection. Log on to
the build system (or the gateway system if one is being used) as root and
enter the following command:
# tip kdebug
If the command does not return the message "connected," another process,
such as a print daemon, might be using the serial line port that you have
dedicated to the kdebug
debugger. To remedy this condition, do
the following:
Check the /etc/inittab
file to see if any processes are
using that line. If so, disable these lines until you finish with the
kdebug
session. See the inittab
(4) reference
page for information on disabling lines.
Use the ps
command to see if any processes
are using the line. For example, if you are using the
/dev/tty00
serial port for your kdebug
session, check for other processes using the serial line as follows:
# ps agxt00
If a process is using tty00, kill that process.
Determine whether any unused kdebugd
gateway daemons are
running:
# ps agx | grep kdebugd
If one is running, kill the process.
If the test system boots to single user or beyond, kdebug
has not been configured into the kernel as specified in the section Getting Ready to Use the kdebug Debugger. Ensure
that the boot_osflags
console environment variable
specifies the k
flag and try booting the system again:
>>> set boot_osflags k >>> boot
Be sure you defined the Ladebug debugger variables in your
.dbxinit
file correctly, or specify them correctly on the
command line. Determine the pseudoterminal line from which you ran
tip
by issuing the /usr/bin/tty
command.
For example:
# /usr/bin/tty /dev/ttyp2
The example shows that you are using pseudoterminal
/dev/ttyp2
. Edit your $HOME/.dbxinit
file on
the build system as follows:
Set the $kdebug_dbgtty
variable to
/dev/ttyp2
with this command:
(ladebug) set $kdebug_dbgtty="/dev/ttyp2"
Set the variable $kdebug_host
to the host name of the
system from which you entered the tip
command. For example,
if the host name is decosf
, the entry in the
.dbxinit
file should be:
(ladebug) set $kdebug_host="decosf"
Remove any settings of the $kdebug_line
variable:
(ladebug) set $kdebug_line=""
Start the Ladebug debugger on the build system. You should see informational
messages on the pseudoterminal line, /dev/ttyp2
, which
kdebug
is starting.
If you are using a gateway system, ensure that the inetd
daemon
is running on the gateway system. Also, check the TCP/IP connection between
the build and gateway system using one of the following commands:
rlogin
, rsh
, or
rcp
.
Only those users familiar with machine-language programming and executable-file-code structure will find low-level debugging useful.
This chapter contains the following sections:
/
and ?
)
display the values stored in memory.
print
command,
with the appropriate pointer arithmetic, prints the value contained at the
address in decimal.
printregs
command
prints the values of all machine-level registers./
and ?
) to print the
value contained at the address in one
of a number of formats (decimal, octal, hexadecimal, and so on). See
Memory Display Commands for more information.
The debugger also maintains the
$readtextfile
debugger variable that allows you to view the
data from the text section of the executable directly
from the binary file, rather than reading it from memory. You can use
this variable to speed up the reading of instructions during kernel
debugging, however, remember that you are reading from the file and
NOT from the live image, which could be different.
print
command, the syntax is as
follows:
print *(int *)(address)
Using the same pointer arithmetic, you can use the assign
command to alter the
contents of a single address. Use the following syntax:
assign *(int *)(address) = value
The following example shows how to use pointer arithmetic to examine and change
the contents of a single address:
(ladebug) print *(int*)(0x10000000)
4198916
(ladebug) assign *(int*)(0x10000000) = 4194744
(ladebug) print *(int*)(0x10000000)
4194744
(ladebug)
printregs
command prints the values of all machine-level registers.
The registers displayed by the debugger are machine dependent. The values are
in decimal or hexadecimal, depending on the value of the $hexints
variable (the default is 0, decimal). The register aliases are shown; for
example, $r1 [$t0]
. See the
printregs
command for more information.
stepi
and nexti
commands let you step through program
execution incrementally, like the step
and next
commands. The
stepi
and nexti
commands execute one machine instruction at a
time, as opposed to one line of source code. The following example shows
stepping at the machine-instruction level:
(ladebug) stop in main
[#1: stop in main ]
(ladebug) run
[1] stopped at [main:4 0x120001180]
4 for (i=1 ; i<3 ; i++) {
(ladebug) stepi
stopped at [main:4 0x120001184] stl t0, 24(sp)
(ladebug) [Return]
stopped at [main:5 0x120001188] ldl a0, 24(sp)
(ladebug) [Return]
stopped at [main:5 0x12000118c] ldq t12, -32664(gp)
(ladebug) [Return]
stopped at [main:5 0x120001190] bsr ra,
(ladebug) [Return]
stopped at [factorial:12 0x120001210] ldah gp, 8192(t12)
(ladebug)
At the machine-instruction level, you can step into, rather than over, a
function's prologue. While within a function prologue, you may find that the stack
trace, variable scope, and parameter list are not correct. Stepping out of the
prologue and into the actual function updates the stack trace and
variable information kept by the debugger.
Single-stepping through function prologues that initialize large local variables
is slow. As a workaround, use the next
command.
The debugger interaction with the target modifies the target state enough that the store conditional is guaranteed to fail. So that users can make progress, the debugger normally steps over the entire sequence, as though it were one big instruction. This allows the application to continue normally.
To debug inside the sequence, while understanding
that this implies failure of the store, set a
breakpoint inside the sequence and continue to the breakpoint.
From there, you will be able to step
.