SAS/C Development System
User's Guide
Volume 2:
Debugger, Utilities, Assembler
Version 6.0
SAS Institute Inc.
SAS Campus Drive
Cary, NC 27513
The correct bibliographic citation for this manual is as follows: SAS Institute
Inc.,
SAS/C Development System User's Guide, Volume 2: Debugger, Utilities,
Assembler,
Version 6.0, Cary, NC: SAS Institute Inc., 1992. 363 pp.
SAS/C
Development System User's Guide, Volume 2: Debugger, Utilities,
Assembler,
Version 6.0
Copyright
1992 by SAS Institute Inc., Cary, NC, USA.
ISBN
1-55544-497-0
All
rights reserved. Printed in the United States of America. No part of this
publication
may be reproduced, stored in a retrieval system, or transmitted, in
any form
or by any means, electronic, mechanical, photocopying, or otherwise,
without
the prior written permission of the publisher, SAS Institute Inc.
1st
printing, June 1992
The SAS
System is an integrated system of software providing complete
control
over data access, management, analysis, and presentation. Base SAS
software
is the foundation of the SAS System. Products within the SAS System
include
SAS/ACCESS, SAS/AF, SAS/ASSIST, SAS/CPE, SAS/DMI, SAS/ETS,
SAS/FSP,
SAS/GRAPH, SAS/IML, SAS/IMS-DL/I, SAS/OR, SAS/QC,
SAS/REPLAY-CICS,
SAS/SHARE, SAS/STAT, SAS/CALC, SAS/CONNECT,
SAS/DB2,
SAS/EIS, SAS/ENGLISH, SAS/INSIGHT, SAS/LAB;
SAS/LOOKUP,
SAS/NVISION, SAS/PH-Clinical, SAS/SQL-DS,
SAS/TOOLKIT,
and SAS/TUTOR software. Other SAS Institute products are
SYSTEM
2000 Data Management Software, with basic SYSTEM 2000,
CREATE,
Multi-User, QueX, Screen Writer, and CICS interface software;
NeoVisuals
software; JMP, JMP IN, and JMP Serve software; SAS/RTERM
software;
and the SAS/CI Compiler and the SAS/CX Compiler. MultiVendor
Architecture
and MVA are trademarks of SAS Institute Inc. SAS Institute
also
offers SAS Consulting and On-Site Ambassador services.
SAS
Communications, SAS Training, SAS Views, the SASware Ballot, and
Observations
are published by SAS Institute Inc. All trademarks above are
registered
trademarks or trademarks of SAS Institute Inc. in the USA and
other
countries. (r) indicates USA registration.
The Institute is a private company devoted to the support and further
development of its software and related services.
Amiga Includes and Development Tools Version 2.0
Copyright (c) 1990 Commodore-Amiga, Inc. All rights reserved.
Amiga Workbench Version 2.0
Copyright (c) 1988, 1990 Commodore-Amiga, Inc. All rights reserved.
Installer
Copyright(c) 1991-1992 Commodore-Amiga, Inc. All rights reserved.
AmigaGuide and WDisplay
Copyright(c) 1991-1992 Commodore-Amiga, Inc. All rights reserved.
Distributed under license from Commodore.
Amiga, AmigaDOS, Workbench, and AmigaGuide are registered trademarks
or trademarks of Commodore-Amiga, Inc. Commodore is a registered
trademark or trademark of Commodore Electronics Limited.
Other brand and product names are registered trademarks or trademarks of
their respective companies.
Doc S17, Ver212.0, 062492
Contents
vii Reference Aids
ix Credits
xi Acknowledgments
xiii Using This Book
Part 1 Using the SAS/C Debugger
Page 3 Chapter 1 Introduction to CodeProbe
3 Introduction
4 CodeProbe Overview
9 Compiling and Linking Your Program
9 Running CodeProbe
12 CodeProbe Windowing Interface
16 Entering Commands
25 Chapter 2 Sample CodeProbe Session
25 Introduction
25 A Walk through a Typical Application
35 Chapter 3 Debugging Your Program
35 Introduction
37 Sample Program 1
39 Controlling Program Execution
53 Sample Program 2
57 Examining Data and Data Structures
73 Chapter 4 Setting Up the Debugging Environment
73 Introduction
77 Determining Source File Location
78 Choosing Command-line Options
81 CodeProbe Initialization
82 Setting and Showing Options within CodeProbe
89 Customizing Dialog Window Commands
95 Chapter 5 Working in Cross-Development Mode
95 Introduction
95 Why Debug in Cross-Development Mode?
96 Using the
Cross Debugger
iv Contents
101 Chapter 6 Using AREXX Macros with CodeProbe
101 The AREXX Interface
101 Macros Provided by CodeProbe
102 Invoking Macros
103 Values Returned from CodeProbe Commands
105 Chapter 7 Debugging Resident Libraries
105 Introduction
105 Setting Breakpoints
106 The symload Command
106 The libraries.cpr AREXX Macro
106 Cautions
106 Limitations
106 Example
107 Chapter 8 Debugging Multitasking Programs
107 Introduction
108 Types of Tasks
108 How CodeProbe Handles Tasks
109 Commands Used to Control Tasks
113 Design Considerations for Debugger Compatibility
115 Chapter 9 Commands and Built-in Functions
115 Introduction
115 CodeProbe Commands
118 Special Parameters
126 Command Reference
202 Built-in Functions
203 Built-in Function Reference
Part 2 Using the SAS/C Utilities
215 Chapter 10 Utility Reference
Part 3 Using the SAS/C Macro Assembler
299 Chapter 11 Using Assembly Language with C Language
299 Introduction
300 Writing Assembly Language Functions
314 Communicating between Assembly Language and C Language
323 Running the Assembler
v Contents
Part 4 Using the SAS/C opeimizer
329 Chapter 12 Optimizing Your Code
329 Introduction
329 The Global Optimizer
334 The Peephole Optimizer
334 Running the Optimizers
Part 5 Appendix
341 Appendix diff File-Matching Algorithm
343 Index
vi
vii
Reference Aids
Displays
12 1.1 Initial CodeProbe Screen
13 1.2 CodeProbe Windows
28 2.1 Source Window Showing Mixed Mode
28 2.2 Source Window Showing Assembly Mode
Figures
275 10.1 Example File Dependencies
317 11.1 The Stack after the func Module Is Called
Tables
17 1.1 Command Line Editing Functions
18 1.2 Escape Sequences in Character Strings
19 1.3 Escape Sequences in Commands
20 1.4 Pull-down Menu Items
23 1.5 Function and Special Keys
24 1.6 Menu Accelerator Keys
viii
ix
Credits
Software
The SAS/C Development System is designed, built, and tested through
the combined effort of many people at SAS Institute. The AmigaDOS
development group includes the following individuals:
Principal Steve Krueger, Douglas Walker, Michael S.
Developers Whitcher
Testing and Twilah K. Blevins, Jim Cooper, Bob Patten,
Technical Khristi Tomlinson
Support
These individuals continue to support future development of the
SAS/C Development System.
Others who have contributed to the SAS/C Development System are
as follows:
Development Edmund Burnette, Dave Frederick, Russell
Gonsalves, Tony Hefner, loe Hutchinsoll, Glenn
Musial, John Roth
Testing and Alan R. Beale, John W. Gillikin, Charles Tudor
Technical
Support
Documentation
Composition Candy R. Farrell, Denise T. Jones, Pamela A.
Troutman
Graphic Design Creative Services Department
Proofreading Patsy P. Blessis, Heather B. Dees, Laurie J.
Medley, Karen A. Olander, Josephine P. Pope,
Christian Schwoerke, Susan E. Willard
Technical Review Elizabeth Brownrigg, Edmund Burnette, Jim
Cooper, Steve Krueger, Johll Roth, Khristi
Tomlinson, Douglas Walker, Michael S. Whitcher
Writing and Jeanne Ferneyhough, Hanna lIicks, Keith Wagner,
Editing Steve Krueger, Douglas Walker, Helen Weeks,
Khristi Tomlinsorl
x
xi
Acknowledgments
Many people make significant and continuing contributions to the
development of the SAS/C Development System. First among them is
John A. Toebes VIII, who was instrumental in the development of
Versions 4.0 and 5.0 and who directed the early development of
Version 6.0.
Others who have contributed to the development and testing of
Version 6.0 of the SAS/C Development System include Ralph Babel,
Bruce M. Drake, Nathan S. Fish, Maximilian Hantsch, Randell Jesup,
David N. Junod, Andrew Kopp, Martin J. Laubach, Christian Ludwig,
Andrew N. Mercier, Mike Meyer, Larry Rosenman, Carolyn
Scheppner, Steve Shireman, Michael Sinz, Martin Taillefer, Steve
Tibbett, John Wiederhirn, Loren Wilton, and Kenneth Yarnall.
The final responsibility for the SAS/C Development System lies with
SAS Institute alone. We hope that you will always let us know your
feelings about our product and its documentation. It is through such
communication that the progress of SAS software continues to be
accomplished.
Not to mention the two pirates who spent hours of their own time
reproducing this document. Mikey The Bad & Deicide still live!
xii
xiii
Using This Book
Purpose
SAS/C Development System User's Guide, Volume II: Debugger,
Utilities, Assembler describes how to use some of the major
tools available to the SAS/C programmer under AmigaDOS: the
debugger, the macro assembler, the optimizer, and the various
utilities that are part of the SAS/C Development System.
"Using This Book" describes how you can best use this book. It
describes the book's intended audience, the audience's prerequisite
knowledge, the book's organization and its conventions, and additional
documentation that is available to you.
Audience
The information in this book is written for experienced
C programmers. This book assumes you have a working knowledge of
the C language and the AmigaDOS operating system. To use the SAS/C
Macro Assembler, you also need a working knowledge of assembly
language. For a list of publications you can use to learn the C language
or the AmigaDOS operating system, refer to the "Additional
Documentation" section at the end of "Using This Book."
How to Use This Book
This section gives an overview of the book's organization and content.
The book's chapters are described, followed by a section on how to use
each chapter.
Organization
SAS/C Development System User's Guide, Volume II: Debugger, Utilities,
Assembler is divided into four parts plus an appendix; the chapters
contained in each part and the appendix are described here:
Part 1: Using the SAS/C Debugger
Part 1 contains nine chapters that discuss CodeProbe and how to use it
to debug your program.
Chapter 1, "Introduction to CodeProbe"
explains what CodeProbe does, how it works, and what tasks are
involved in debugging a program. This chapter also describes how
to compile and link your program under CodeProbe control.
xiv Using This Book
Chapter 2, "Sample CodeProbe Session"
contains a brief sample session using the lines.c program in the
sc:examples drawer. You can follow this sample session to gain
experience with the most commonly used debugger commands.
Chapter 3, "Debugging Your Program"
describes the CodeProbe commands most frequently used for
stepping through your program, displaying code and data, and
modifying code or data.
Chapter 4, "Setting Up the Debugging Environment"
describes the commands and options you can use to customize the
environment in which you debug your program.
Chapter 5, "Working in Cross-Development Mode"
describes how to run your executable code from a serially-
connected Amiga system.
Chapter 6, "Using AREXX Macros with CodeProbe"
describes how to use AREXX macros from inside CodeProbe. This
chapter contains a list of valid AREXX commands.
Chapter 7, "Debugging Resident Libraries"
describes how to use CodeProbe to debug resident libraries.
Chapter 8, "Debugging Multitasking Programs"
describes how to use CodeProbe with applications that spawn
additional tasks.
Chapter 9, "Commands and Built In Functions"
describes each CodeProbe command and built-in function in detail.
Part 2: Using the SAS/C Utilities
Part 2 contains only one chapter. This chapter discusses the SAS/C
utilities.
Chapter 10, "Utility Reference"
describes each of the utilities (such as smake, scopts, and tb)
provided by the SAS/C Development System.
Part 3: Using the SAS/C Macro Assembler
Part 3 contains only one chapter. This chapter discusses how to use
assembly language with C language.
Chapter 11, "Using Assembly Language with C Language"
describes how to communicate between C language and the
assembler. You can incorporate assembler routines as part of your
C program or
call C functions from assembly language.
xv Using This Book
Part 4: Using the SAS/C Optimizer
Part 4 contains only one chapter. This chapter discusses how to use
the SAS/C Optimizer.
Chapter 12, "Optimizing Your Code"
describes what the global and peephole optimizers do and how to
run the optimizers during compilation.
The appendix, "diff File-Matching Algorithm," describes the
algorithm used by the diff utility to compare files.
What you should read.
The following table points you to specific chapters in this book for
information on particular topics. For other references, refer to
"Additional Documentation" later in this section.
For information on You should read
compiling, linking, and running your program Chapters 1 and 4
under the debugger
using the most common debugger commands Chapters 2 and 3
customizing your debugging environment Chapter 4
running your program on one machine and Chapter 5
debugging it on another machine
using AREXX macros Chapter 6
debugging resident libraries Chapter 7
debugging multitasking programs Chapter 8
Conventions
This section covers the typographical and syntax conventions used in
this book.
Typographical Conventions
The SAS/C books for AmigaDOS use special fonts to depict specific
Conventions types of information. These typographical conventions are as follows:
roman is the basic type style used for most text.
monospace is used to show example statements or programs.
Monospace is used also for items specific to the
xvi Using this Book
C language, such as the names of functions, header
files, and keywords.
obligue is used for arguments or variables whose values are
supplied by the user; for example, you should enter an
appropriate filename when you see filename.
italic is used for terms that are defined. Italic is also used to
indicate arguments for which you supply a value.
Syntax Conventions
This book uses the following conventions for syntax:
monospace indicates commands, keywords, and switches that
should be spelled exactly as shown. These arguments
may or may not be optional, depending on whether
they are enclosed in square brackets.
italic indicates arguments for which you supply a value.
[] indicate an optional argument when they surround the
(square argument.
brackets)
. . . (ellipsis) indicates that you can repeat the argument or group of
arguments preceding the ellipsis any number of times.
| means to choose one item from a group of items
(vertical bar) separated by the bars.
The following example illustrates these syntax conventions:
env [function | integer]
env
is a command name, so it appears in monospace type.
function
is a function for which you supply the name, so it appears in italic
type.
[function | integer]
are both optional, so they are enclosed in square brackets.
function | integer
indicates that you can specify only one of the items separated by the
vertical bar.
xvii Using This Book
Additional Documentation
The following sections list documentation you may find helpful in using
the SAS/C Development System.
SAS Documentation
If you are interested in SAS documentation, you need to contact the
Book Sales department by writing to the following address or by
calling the following number:
SAS Institute Inc
Book Sales Department
SAS Campus Drive
Cary, NC 27513
919-677-8000
SAS/C Development System
This book is part of a set of publications for the SAS/C Development
System. There are three other publications in the set:
SAS/C Development System User's Guide, Volume I: Introduction,
Compiler, Editor describes how to
install the SAS/C Development System on your Amiga system
use your development environment
create files in the editor
compile and link C files.
SAS/C Development System Library Reference describes how to
access libraries
create your own libraries
use header files to reduce the amount of time and space required
by your program.
SAS/C Development System Quick Reference, Version 6.0 contains
reference tables for the library functions, compiler and linker
options, and debugger commands.
These volumes are sold together as a set. You can order them by
specifying order #A56l85.
Other Documentation
The following sections list additional reference material specific to the
C language, Amiga and AmigaDOS programrning, and the Motorola
68xxx microprocessor.
xviii Using This Book
C Language
The following books describe the C programming language:
American National Standards Committee (1990), American National
Standard for Information Systems--Programming Language C, Document
Number X3J11/90-013, Washington, D.C.: X3 Secretariat: Computer
and Business Equipment Manufacturers Association.
Harbison, Samuel P. and Steele, Guy L., Jr. (1990), C: A Reference Manual,
Third Edition, Englewood Cliffs, NJ: Prentice-Hall, Inc.
Kernighan, Brian W. and Ritchie, Dennis M. (1988), The C Programming
Language, Second Edition, Englewood Cliffs, NJ: Prentice-Hall, Inc.
Amiga and AmigaDOS
The following books provide information specifically about
programming on the Amiga system. Most of the examples in these
books are written in the C or assembler languages.
Commodore-Amiga, Inc. (1991), Amiga Hardware Reference Manual, 3rd
Edition, Reading, MA: Addison-Wesley Publishing Company.
Commodore-Amiga, Inc. (1991), Amiga ROM Kernal Reference Manual:
Devices, 3rd Edition, Reading, MA: Addison-Wesley Publishing
Company.
Commodore-Amiga, Inc. (1991), Amiga ROM Kernal Reference Manual:
Includes and Autodocs, 3rd Edition, Reading, MA: Addison-Wesley
Publishing Company.
Commodore-Amiga, Inc. (1991), Amiga User Interface Style Guide,
Reading, MA: Addison-Wesley Publishing Company.
Commodore-Amiga, Inc. (1991), The AmigaDOS Manual, 3rd Edition, New
York, NY: Bantam Books.
Commodore-Amiga, Inc. (1992), Amiga ROM Kernal Reference Manual:
Libraries, 3rd Edition, Reading, MA: Addison-Wesley Publishing
Company.
Motorola 68xxx
The following books contain information specifically about
programming the Motorola 68xxx microprocessor.
Motorola, Inc. (1987), MC68881/MC68882 Floating-Point Coprocessor
User's Manual, First Edition, Englewood Cliffs, NJ: Prentice-Hall, Inc.
Motorola, Inc. (1989), MC68030 Enhanced 32-Bit Microprocessor User's
Manual, Second Edition, Englewood Cliffs, NJ: Prentice-Hall, Inc.
Motorola, Inc. (1989), Programmer's Reference Manual, Phoenix, AZ:
Motorola
Literature Distribution.
xix Using This Book
Contacting CATS
You can contact Commodore Application and Technical Support at the
following address:
1200 Wilson Drive
West Chester, PA 19380
215-429-0643
1
Part 1
Using the SAS/C
Debugger
Chapters 1 Introduction to CodeProbe
2 Sample CodeProbe Session
3 Debugging Your Program
4 Setting Up the Debugging Environment
S Working in Cross-Development Mode
6 Using AREXX Macros with CodeProbe
7 Debugging Resident Libraries
8 Debugging Multitasking Programs
9
Commands and Built-in Functions
2
3
1 Introduction to CodeProbe
3 Introduction
4 CodeProbe Overview
4 Basic Features
4 Multitasking Features
S Summary of Changes and Enhancements for Version 6.0 of
the CodeProbe Debugger
5 Terminology
7 How CodeProbe Works
9 Compiling and Linking Your Program
9 Running CodeProbe
9 The cpr Command
10 The quit Command
10 Workbench Support
11 Line Mode
12 CodeProbe Windowing Interface
12 Screen Layout
14 CodeProbe Windows
16 Entering Commands
16 Command Line
20 Pull-Down Menus
22 Function and Special Keys
23 Menu Accelerator Keys
Introduction
CodeProbe is a powerful source-level debugger that enables you to
monitor, line by line, the behavior of programs written in C language,
assembly language, or a combination of the two. CodeProbe has many
useful features and commands designed to aid you in tracking down
your program's problems. Some of these aids provide the ability to
examine and modify variables, address and data registers, and user-
specified memory locations. CodeProbe gives you absolute control over
the execution of your program by enabling you to stop execution at
any point. It also enables you to examine both the C source and the
(Throughout this manual, the terms CodeProbe and the debugger are used
interchallgeably to refer to this debugger program.)
4 Chapter 1
assembler generated for your program at the same time so you can see
what is really occurring at the assembly language level.
This chapter explains what CodeProbe does, how it works, and what
is involved in debugging a program.
CodeProbe Overview
CodeProbe implements a number of commands and features
specifically designed to ease the debugging of C programs. In addition
to a command-line interface, the debugger provides you with a
sophisticated, screen-oriented interface where you can take advantage
of multiple windows and pull-down menus. Shortcuts that are built
into the program enable you to issue commands with a couple of
keystrokes or mouse clicks.
Basic Features
As a source-level debugger, CodeProbe allows you to
single-step through programs either in C source code or the
generated assembler code
set breakpoints on C source lines, or an individual assembly
language statement
continue program execution until a specified function or line number
is reached, or until a variable contains a specified value or its value
changes
examine variables and code at the C language level
display C data types--including structures, unions, arrays, enums,
typedefs, and bit fields--in their C formats
display memory dumps in a variety of formats
continuously watch any C variable, array element, or structure
member
assign a value to a C variable
fill an area of memory
copy one C array or structure to another
copy a string from one place to another
view and manipulate register data
access storage classes of data, including automatic, static, and
register as well as external.
Multitasking Features
CodeProbe allows you to debug multitasking programs. Any new tasks
or processes created by a program that is being debugged are
automatically under debugger control. The following multitasking
features are provided:
Breakpoints can be set and trapped for any task generated under
debugger
control.
5 Introduction to CodeProbe
The state of any task in a multitasking application can be displayed
including the stack and registers.
Tasks can be started and stopped selectively.
Tasks that are executing independently of the debugger can be
intercepted and attached to the debugger. This can be useful if a
process enters an infinite loop or waits indefinitely on a message
port.
Summary of Changes and Enhancements for Version 6.0 of CodeProbe Debugger
The following changes and enhancements are introduced with
Version 6.0 of the CodeProbe debugger:
Cross debugger support IS provided via the serial port or a
communications network.
Debugging of shared libraries and devices has been simplified.
C expression parsing is allowed with most debugger commands.
The ability to display ranges within arrays is provided.
The alias and define commands provide greater flexibility.
68881 floating-point registers are supported.
Motorola fast floating-point format (ffp) display is provided.
The env and where commands enable you to look back up the
function call chain.
The args command displays arguments to the current function.
More compact debugging format saves space on disk.
The AmigaDos Version 2.0 look and feel is provided, including
public screens and three-dimensional look.
The call command enables you to call application functions
directly from the debugger.
The source command enables you to specify the new name of a
source file.
The symbol, shell, and window commands have been added.
Calls, Modules, and Memory windows have been added.
Enhanced AREXX support is provided.
Cross-referenced online help is provided in a separate window.
The log command provides a Dialog window command logging
capability.
The jump command provides the ability to change the current
location.
Terminology
This book frequently uses terms that you may not be familiar with. The
following definitions are new or have unique meanings to the
CodeProbe documentation:
breakpoint
is an address used to control program execution. Program execution
is suspended
when the breakpoint address is reached.
6 Chapter 1
call frame
is the stack area associated with a function's formal parameters,
automatic variables, temporaries, saved registers, and the return
address. There is one call frame per function invocation.
cross-debugging
is a debugging technique that uses two machines that are linked
together. CodeProbe runs on one machine, and the application runs
on the other. (See host machine and target machine later in this
list.)
environment
in CodeProbe documentation, environment means the state of the
machine. The state of the machine consists of the contents of
memory, the contents of the registers, the contents of the stack, and
the point of execution in the source code.
The run environment is the actual environment at which you are
stopped.
The user environment is the last environment set with the env
command. This environment is used when displaying registers and
variables. It is reset to the run environment after a go command or
any of the commands that step the program.
host machine
when cross-debugging, the host machine is the machine that is used
to display the CodeProbe user interface. The actual debugging
session takes place on this machine. (See cross-debugging earlier in
this list.)
image
is an executable program, an AmigaDOS shared library, or an
AmigaDOS device. The name of the image is the same as the name
of the disk file from which the image is loaded. An image can be
specified with several CodeProbe commands as part of the location
parameter.
line boundary
is the imaginary boundary in the machine code that specifies the
end of the code generated for a C source line.
log file
is a file created by CodeProbe that contains details of all of the
activity that occurred in the Dialog window. A log session can be
turned off and on with the log command. By default, the log file is
turned off.
7 Introduction to CodeProbe
module
is all code generated by a single C source file. The name of the
module is the same as the name of the C source file that generated
pass count
is the number of times that a line has been executed. The after
parameter is used with commands such as go and break to specify
a pass count.
symbol
is a series of letters and numbers that specify a function, memory
location, or a variable.
target machine
when cross-debugging, the target machine is the machine used to
run the application. (See cross-debugging earlier in this list.)
How CodeProbe Works
CodeProbe requires debugging information to be present in the
executable files before you can use most of its powerful debugging
features. This means that if you want to run CodeProbe and view the
C source file while it is running, you must compile that C source file
with one of the debugging options, such as line, full, or symbol.
The compiler will then include information in the executable files that
will enable CodeProbe to reflect accurately the state of your application
program in the Source window.
The compiler supports several debugging options specifying the
amount of debugging information that is passed on to the linker. The
linker (slink) also allows you to add symbolic debugging information
to modules compiled without debugging information or to strip all
debugging information from the executable file. Refer to Chapter 4,
"Setting Up the Debugging Environment," for a complete discussion of
debugging options.
When CodeProbe runs your program, it uses debugging information
present in executable files to keep track of which C source lines
correspond to which assembler instructions.
When you specify one of the debug options to the compiler, the
compiler generates debugging information in the form of H_DEBUG
hunks that get placed into the object module for that source. The
compiler can generate two different types of H_DEBUG hunks, line and
symbolic. It also can vary the amount of information that goes into the
symbolic H_DEBUG hunks based on the debug option. Hunks and
H_DEBUG hunks are explained in Chapter 12, "How the Compiler
Works," in the SAS/C Development System User's Guide, Volume I:
Introduction, Compiler, Editor.
8 Chapter 1
If you specify debug=line, then the compiler generates an
H_DEBUG hunk that contains the source filename and a table of source
line numbers to address offset pairs. CodeProbe uses this table to
match up the line numbers for the source with the assembly
instructions as your program is executing.
In addition to debug=line, if you specify the addsym option to
the linker (slink), then slink generates an H_SYMBOL hunk in the
final executable file. The H_SYMBOL hunk contains a table of global
symbols and their offsets into the data section. If you compile and link
using the sc command, the addsym option is added automatically to
the slink command line, provided that you specify any debug option
except nodebug.
Using the global symbol information, CodeProbe can locate the start
of the symbol but not its size or type. CodeProbe assumes all such
symbols are of type long. This feature can be useful if you are
debugging large projects on small machines where there might not be
enough memory to load symbolic debugging information.
If you specify the debug=symbol or debug=full options to the
compiler, then the compiler generates an H_DEBUG hunk containing
high-level symbolic debugging information for the source. This includes
information for external identifiers, information for structure or union
tags and typedefs, local variables, and so on. CodeProbe searches this
information when trying to display an item in C source mode.
Controlling CodeProbe
Among CodeProbe's controls are pull-down menus, Intuition-based
windows, and mouse support. The debugger also has powerful
commands that can be entered in the Dialog window. In addition,
CodeProbe offers a number of special functions and keyboard
shortcuts, including programmed function and menu accelerator keys
to maximize efficiency.
Debugging a Program
Debugging a program using CodeProbe involves three basic steps:
1. Compile with debug information. (Use one of the debug= options
with the sc command.)
2. Invoke the debugger.
3. Execute the program under debugger control.
The next two sections of this chapter present the basic information
you need to perform these steps.
9 Introduction to CodeProbe
Compiling and Linking Your Program
Before invoking CodeProbe you must compile and link your program
as described in Chapter 8, "Compiling and Linking Your Program," of
the SAS/C Development System User's Guide, Volume I: Introduction,
Compiler, Editor.
The degree to which the debugger can access symbols defined in any
module is determined by the compiler and linker options. Refer to
Chapter 4, "Setting Up the Debugging Environment," to determine
which options you need to use. In most cases, the
debug=symbol flush option to the sc command specifies sufficient
information to debug your program. A typical way to compile and link
your program is with the following commands:
sc debug=symbolflush link filename.c
The sc command invokes the compiler, and debug=symbo 1 f lush
(or debug=sf) causes the compiler to generate line number
information, generate symbolic debugging information for variables in
that module, and make sure those variables are flushed back to
memory at line boundaries. The link option causes sc to invoke the
linker. The addsym option is automatically passed to the linker
because of the inclusion of a debug option. The addsym option forces
slink to generate symbolic information for global symbols in libraries
and for any file that does not have debug information. The
filename.c argument specifies the source file.
Running CodeProbe
This section describes how to
use the cpr command to invoke CodeProbe from the Shell
use the quit command to stop the debugger at any time
use CodeProbe to run applications from either a Shell or Workbench
screen
run CodeProbe as a line-mode debugger.
The cpr Command
The cpr command is invoked from a Shell to start CodeProbe for the
first time during your debugging session. The cpr command uses the
following syntax:
cpr
[cpr-options]application-name [application-arguments]
10 Chapter 1
The application-name and application-arguments parameters are
determined by your application. You can specify any of the following
cpr-options:
-buffer -noprofile -wdialog
-cli -screen -wregister
-command -startup -wsource
-i -w -wwatch
-line -wb -cli
Each of these options is discussed in the section "Choosing
Command-line Options" in Chapter 4.
When the cpr command is invoked, CodeProbe makes the following
assumptions:
The program specified on the command line exists in the current
directory or somewhere on the command search path, as specified
by the AmigaDOS path command.
The modules making up the program to be debugged have been
compiled with one or more of the debugging options discussed
earlier and have been linked using the addsym option of the linker.
Source files for modules that you will be accessing exist in either the
current directory, your special source path list (as specified by the
opt search command), or the directory in which the module was
compiled.
The quit Command
The quit command can be issued from the Dialog window to stop the
debugger at any time. However, you should allow your program to run
to completion before using the quit command. While CodeProbe will
attempt to do some cleanup for your program by calling the normal C
exit routine, you should allow your program to do its own cleanup.
Refer to Chapter 9 for more information about the quit command.
Workbench Support
CodeProbe can be run from the Amiga system's Workbench screen as
well as from a Shell. Furthermore, CodeProbe itself can run
applications in either a Shell or Workbench environment from either
location. By default, CodeProbe runs its application in the same type of
environment that invoked the debugger.
11 Introduction to CodeProbe
The following options to the cpr command are used to change the
default environment:
-cli forces the application to run under the debugger as
if it were invoked from a Shell.
-wb forces the application to run under the debugger as
if it were invoked from the Workbench screen.
To facilitate debugging from the Workbench screen, a small stub tool
called DEBUG can be placed in a project directory along with a
corresponding tool icon. Both the tool and its icon may be found in the
sc:starter_project drawer. DEBUG invokes CodeProbe and
passes to it all Workbench startup messages. The SCSETUP utility
automatically copies DEBUG and its icon into your project directories.
To invoke CodeProbe from the Workbench screen, click once on the
cpr or debug icon. Then, while holding down the Shift key, double-
click on the icon for the application's executable.
To set up CodeProbe command-line options, use the Workbench
screen's Information menu item on the cpr or debug icon from the
Workbench menu. Place the debugger command-line options in the
ToolTypes field of the icon. The debugger will parse the options as if
they were entered on the command line. The options may be placed on
one ToolType edit line or they can be spread across several lines.
To invoke CodeProbe on a program requiring command-line options,
edit the debug icon the same way that you would edit it to set up
CodeProbe command-line options. Add the -cli option as the last
cpr option and follow it with the name of the executable file followed
by its command-line options.
By default debug invokes sc: c/cpr. If you rename or move cpr,
DEBUG can find it if you assign the full pathname of the debugger to
the environment variable sc/cprpath. This is done easily using the
AmigaDOS setenv command as follows:
setenv sc/cprpath pathname
Line Mode
You also can run CodeProbe as a line-mode debugger by starting it
with the -line option. In line mode the debugger displays its output
in the current Shell window. The -line option can be used to start
the debugger from a remote Shell that has been started from an
rlogin or from a Shell started across a serial line. For information
about starting a Shell over a serial line, see the description of the
AUX: device in The AmigaDOS Manual, 3rd Edition.
12 Chapter 1
CodeProbe Windowing Interface
CodeProbe provides a sophisticated windowing interface with multiple
windows and pull-down menus. Windows are used to issue debugger
commands, to receive output from CodeProbe commands, or to browse
through the source code for your program.
Screen Layout
CodeProbe starts with the Source and Dialog windows open, as shown
in Display 1.1. (BUY THE PROGRAM!)
13 Introduction to CodeProbe
Once CodeProbe is running, you can opell, close, move, and resize
windows. Display 1.2 is a sample CodeProbe screen showing the
following windows:
Source window
Dialog window
Memory window
Register window
Watch
window.
14 Chapter 1
CodeProbe Windows
CodeProbe has 11 types of windows. You control the actual number of
windows open during a debugging session. No matter how many
windows are displayed, one of them will be the active window that is
currently receiving, or waiting for, input. The title bar of the active
window is highlighted (AmigaDOS Version 2.0 changes the color, and
Version 1.3 ghosts the title bar when a window is not activated). The
following list explains the function of each type of window:
Calls window
displays a stack traceback showing the calling sequence for the
program being debugged. Each level of the traceback represents the
state of the machine when a function was called. The state of the
machine is also known as its environment. By double-clicking on a
desired traceback entry in the Calls window, you can return
CodeProbe to a previous environment. You will then see the code
that was being executed at that time in the Source window, and you
can see the contents of the registers as they were before the call in
the Register window. The state of memory cannot be replicated for
previous environments, so the Memory window reflects your
current environment. A message is also displayed in the Dialog
window informing you of your current location.
As an example, suppose you have a main function that calls a
function named s ort, which in turn calls a function named swap.
When the execution of your program reaches the swap function,
the calling sequence main, sort, swap is displayed in the Calls
window. By double-clicking on the entry for the main function, you
can return the machine to the state it was in when ma in called
sort. You will see the source code that was executed and be able
to view what was in the registers at the point at which ma in called
sort; however, your program will still be executing at the same
point in the swap function. Therefore, you can examine local
variables, and they will have the values they had when main called
sort, but global variables may have changed. If you single-step
through the program, the code displayed in the Source window
returns back to the last line executed in swap, and execution
continues.
Dialog window
enables you to enter commands and review the results of those
commands. Many of the same commands available through the pull-
down menus can be invoked directly at the command line in the
Dialog window.
Help window
displays help information for each of the CodeProbe commands as
well as other
selected topics.
15 Introduction to CodeProbe
Input window
automatically opens to request input for a task you are performing.
Input windows allow you to enter data, such as selecting a value for
the default number of lines to be displayed by the list command.
You can exit out of an Input window without entering input by
pressing the escape (Esc) key.
Memory window
displays a dump of memory in both character and hexadecimal
format or disassembles code.
Message window
displays text passed to it by the wmsg command.
Modules window
displays a list of all the modules within the application program.
Output window
displays output that is directed to the terminal by your C program
from functions such as printf. The Output window is the initial
Shell if the program is run from the Shell, or the Shell Workbench
window opened by the startup code otherwise.
Register window
displays the contents of the registers. This window is most useful to
assembly-level programmers. It is also valuable for checking
registerized variables defined in C source code. Once opened, it
displays the current contents of all registers and the current values
of the processor flags. Any registers that have been modified since
the last breakpoint are highlighted. The Register window can be
opened by pressing the F4 key.
Source window
displays the source code for the module currently being executed.
As execution proceeds, the Source window is continually updated to
reflect the current position. The Source window highlights the
current position (the line about to be executed) and any
breakpoints.
Watch window
watches and displays the value of variables. For installce, you can
set a watch break such that the application will be stopped as SOOII
as the watch variable changes value. The Watch window can be
opened by pressing the Fl key.
Opening Windows
With the exceptions of the Input and Message windows, you can use
the View menu to open any window. (See "Pull-Down
Menus" later in
16 Chapter 1
this chapter.) Input windows open automatically when user input is
required. The Message window is used to display messages from
scripts and is opened automatically to display output from the wmsg
command. The Help window can be opened with the Help icon or the
help command, as well as from the menu. You can also use the
window command to open any of the windows.
Entering Commands
You can issue debugger commands in several different ways. The
methods of issuing commands are presented in the following order:
entering commands from the Dialog window
using pull-down menus to enter commands
using special function keys to enter commands
using menu accelerator keys to enter commands.
Command Line
The most flexible method of entering debugger commands is by typing
them in at the command line of the Dialog window. The command line
is marked by the > prompt. You can enter any of the debugger
commands described in Chapter 9 in this manner.
Command Syntax
In order to understand the individual command descriptions, you must
first understand the syntax conventions described in the "Using This
Book" section.
Command Name Shortcuts
Command names need not be entered in their entirety. Generally, only
the minimum number of characters necessary to uniquely identify a
command is required.
The Help menu, which is displayed in the Dialog window when you
enter the help command, shows required keys in caps for command
names while the rest are shown in lowercase. For example, RETurn in
the Help menu indicates that only the first three letters of the
command are required, but typing in return or retur would work
also.
The syntax conventions used in this book show the optional portion
of a command in square brackets [ ].
Command-line Editing
CodeProbe commands can be typed on the command line of the Dialog
window in either uppercase or lowercase. The following command-line
editing techniques are useful when entering commands in
this manner.
17 Introduction to CodeProbe
Determining Editing Modes
The editing mode affects tne way characters are typed on the commarld
line as well as the functioning of the numeric keypad. The current
editing mode can be determined by examining the left end of the
Dialog window's title bar.
The first character in the title bar will be an I if in insert mode or C
if in overwrite mode. When you are in insert mode, any characters
you type on the command line are inserted between existing
characters. Wherl you are in overwrite mode, any characters you type
overwrite any existing characters. The Ins key on the numeric keypad
is used to switch between insert and overwrite mode. (Use the zero key
to switch between insert and overwrite modes on the A1000.)
The second character in the title bar is always a slash (/), and the
third character will be an F if tne numeric keypad is in functiorl mode
or an N if in numeric mode. The keypad must be in functiorl mode to
use the editing functions described in the next section. I o toggle
between the numeric and function modes, press F10.
Editing Function Keys
Three control key sequences in function mode and the numeric keypad
are used to perform command-line editing functions. In order to
perform these functions you must be editing in function mode.
Table 1.1 describes the command-line editing functions.
Table 1. 1 Command Line Editing Functions
Keys Description
Ctrl X erases the current line
Ctrl A toggles insert/overstrike
Ctrl keypad-l erases from the cursor to the end of the line
keypad-1 moves the cursor to the end of the line
keypad-7 moves the cursor to the start of the line
keypad-O starts inserting at the cursor
keypad-. (Del) deletes the character urlder the cursor
keypad-4 moves the cursor left one position
keypad-6 moves the cursor right one position
Shift keypad 4 moves the cursor left one word
(continued)
18 Chapter 1
Table 1.1 (continued)
Keys Description
Shift keypad-6 moves the cursor right one word
keypad-Enter sends the line to the program as input
keypad-8 recalls the previous Dialog window command
keypad-2 goes to the next Dialog window command
keypad-9 (PgUp) moves the page up
keypad-3 (PgDn) moves the page down
Extending Commands across Lines
A command line can extend across several input lines by ending all but
the last line with a backslash (\) followed immediately by a carriage
return. A command line can be up to 256 characters in length.
Using Escape Characters
There are three places where you might want to use escape characters:
in character strings
in character constants
in commands.
C character strings consist of text surrounded by double quotes ("").
Standard C escapes starting with the backslash character are supported
as shown in Table 1.2.
Table 1.2 Escape Sequences in Character Strings
Escape Sequence Meaning
\n newline (0xOa)
t tab (0xO9)
b backspace (0x08)
\r return (0xOd)
\f form feed (0xOc)
\v vertical tab (0xOb)
\NNN octal constant (NNN is 3 octal digits.)
\xNN hex constant (NN is 2 hexadecimal
digits.)
19 Introduction to CodeProbe
In a character string, a backslash followed by any other character
will be interpreted as itself. Therefore, "\\" is a string consisting of a
single backslash, and " a \ " b " is three characters long, an " a ", a
double quote, and a "b".
C character constants consist of a single character surrounded by
single quotes (' '). The standard C escape sequences shown in
Table 1.2 can be used with character constants.
Escape characters also can be used in CodeProbe commands.
Table 1.3 lists escape characters that can be used outside of character
strings and constants.
Table 1.3 Escape Sequences in Commands
Escape Sequence Meaning
\\ backslash
\; command delimiter
\, argument delimiter
\" character string/constant delimiter
\' constant delimiter/constant delimiter
\( when or macro delimiters
\) when or macro delimiters
Outside of quotes, a backslash followed by any other character is not
assigned any special meaning; it is interpreted as two distinct
characters. Therefore, "b \mod\func" sets a breakpoint at function
func of module mod, and not at a function called modfunc.
Escape sequences are especially useful in the alias command, as in
these examples:
alias tb where;d x /* this is two commands */
alias tb where\;d x /* this is one command */
The first example runs an a 1 ias command followed by a display
command; the second runs a single alias command. After executing the
second example, tb is aliased to where;d x.
Note, however, that these special escape sequences are not accepted
in certain places that do not make sense. For example, you cannot use
escape sequences in command and alias names.
20 Chapter 1
Pull-Down Menus
The most common debugger activities can be performed by using pull-
down menus. As with other Amiga applications, you use the right
mouse button to control menu functions. CodeProbe has seven pull-
down menus that enable you to enter commands. Table 1.4 lists the
menu items along with their command-line equivalents.
Table 1.4 Pull-down Menu Items
Menu Item Command-line Equivalent
File Menu
Module list \module
Line list [ line ] | [ address ]
Find Current Line env
Execute execute [ script-name ]
Refresh Ctrl L
Paste <none>
Quit quit
Options Menu
Source Mode opt source
(c|asm|mixed)
Radix Default opt radix ( hex | decimal)
Context Lines opt context [integer]
List Default opt list [integer]
Unassemble Default opt unassemble [ integer]
String Length opt strlen [ integer]
Array Length opt arrdim [integer]
Range Length opt rangelen [ integer]
Autoswap Mode opt autoswap (on | off )
Echo Mode opt echo ( on | off )
(continued)
21 Introduction to CodeProbe
Table 1.4 (continued)
Menu Item Command-line Equivalent
Instruction Bytes opt ibytes (on | off)
Ignore Path opt ignorepath (on | off)
Case Sensitivity opt case ( on | off)
Maximum Bad Characters opt badchar [ integer]
Step Into ResLib opt reslib ( on | off )
Catch New Devices opt devices ( on | off )
Catch New Tasks opt catch ( on | off )
View Menu
Calls window calls
Modules window modules
Register window register
Watch window watch
Source window source
Dialog window dialog
Output window output
Memory window memory
Help window help
Run Menu
Trace Into trace
Proceed Over proceed
Go go
Go Until go [ location ]
Return return [ value ]
Startstart [command line]
Break Menu
Set break [ location ]
(continued)
22 Chapter 1
Table 1.4 (continued)
Menu Item Command-line Equivalent
List blist
Clear bclear [arguments]
Enable benable [arguments]
Disable bdisable [arguments]
All Clear bclear *
Watch Menu
Set watch [location]
Breakw break [arguments]
List wlist
Clear wclear [arguments]
Enable wenable [arguments]
Disable wdisable [arguments]
All Clear wclear *
Memory Menu
Size (Long, Word, Byte) <none>
Display As (Data, Code) <none>
Base Address (Static, Dynamic) <none>
The File menu has two items called Line and Find Current Line that
automatically list lines of source code in the Dialog window. These
options are displayed as Address and Find Current Address when the
debugger is in assembler mode. When prompted for an address after
choosing the Address item, you should enter a hexadecimal va]ue. A
'0x" prefix is not required. The Source window will disassemble code
beginning at the specified address.
Function and Spaecial Keys
The actions of the function keys (F1 through F10) are indicated on the
debugger screen title bar. In addition to the function keys, there are
three keys with
special functions: Help, Ctrl L, and Ctrl W. I hese keys
23 Introduction to CodeProbe
are not shown in the title bar. Table 1.5 explains the use of the
function and special keys in more detail.
Table 1.5 Function and Special Keys
Key Action
F1 toggles for opening/closing the Watch window
Shift F1 toggles for opening/closing the Source window
F2 zooms or unzooms the active window to the
size of the screen
F3 recalls the last command *
Shift F3 recalls the previous command *
F4 toggles for opening/closing the Register window
F5 re-executes the last command *
F6 activates the next window
F7 steps into a line/instruction (trace)
F8 steps over a line/instruction (proceed)
F9 toggles for swap screens between the
debugger and application screens
F10 toggles the numeric keypad mode
Help executes the help command
Ctrl L refreshes the screen
Ctrl W refreshes the screen
* The Dialog window must be active to recall or re-execute commands.
Menu Accelerator Keys
Menu accelerator keys are familiar to most Amiga system users. Menu
items with shortcuts can be executed from the keyboard by striking the
right-Amiga key in combinatioIl with another specified key. If a
menu item has an accelerator key, it is displayed on the menu after the
item. The actions performed by the menu accelerator keys are shown
in Table 1.6.
24 Chapter 1
Table 1.6 Menu Accelerator Keys
Key Menu Action
A Break Clears all breaks
B Break Sets a breakpoint
C Break Clears a breakpoint
D Break Disables a breakpoint
E Break Enables a breakpoint
F File Refreshes the screen
G Run Executes the go command
H File Finds the current line
L Break Lists the breakpoints
M File Changes the currellt module
N File Finds the line/address
P Run Proceeds (steps over the current line/instruction)
Q File Quits the debugger
R Run Returns from the current function
S Run Starts (restarts the program with same command
line)
T Run Traces (steps into the current line/instruction)
W Run Where (displays stack frame backtrace)
X File Executes a debugger command script from a file
25
2 Sample CodeProbe
Session
25 Introduction
25 A Walk through a Typical Application
25 Starting the Debugger
26 Using the go and restart Commands
26 Using Online Help
27 Controlling the Debugging Session
34 Quitting the Debugger
Introduction
The best way to understand how to use CodeProbe is to walk through
a sample debugging session. This chapter provides an example session
that demonstrates several debugger commands and options. It also
explains how to maneuver in the debugger's windows.
The chapters that follow this one provide the necessary details to
help you get the most out of CodeProbe.
A Walk through a Typical Application
The source code for the sample program, l ines . c, used in this
chapter is located in the s c: e x amp 1 e s drawer.
Starting the Debugger
To start your debugging session you must first compile and link the
application program and then invoke the debugger. This chapter
provides instructions for performing these tasks with the sample
program, lines.c. Additional information about compiling, linking,
and invoking the debugger is located in Chapter 1, "Introduction to
CodeProbe," and Chapter 4, "Setting Up the Debugging ~nvironment."
Compiling and Linking the Program
To compile the sample program, lines.c, invoke the compiler, SC,
with the debug=symbolf lush (sf) option. This option outputs full
debugging information for those symbols and structures referenced by
the program. The link option invokes the linker automatically.
sc
debug=sf link lines.c
26 Chapter 2
Invoking the Debugger
To start the debugger, type in c pr followed by the executable
program's filename.
cpr lines
Note that the Dialog window and the Source window open by
default. The Dialog window highlights the current edit line. In the
same manner, the Source window highlights the next line of the
program's source code to be executed.
Using the go and restart Commands
In order to use the debugger efficiently, you need to become familiar
with both the go and the restart commands. The go command
begins execution of your application program, which runs until a
breakpoint is hit or the program exits. The restart command causes
the application program to be reloaded and execute up to the first line
of the main function. Both of these commands are described in
Chapter 9, "Commands and Built-in Functions."
When you invoke CodeProbe, a go main command is automatically
issued unless you specified the -startup option when you invoked
the debugger. This initial go command causes your application to run
to the first line of the main function. You can always return to this
point by entering as many go commands as necessary to cause your
application program to run to completion and then issuing a single
restart command.
Using the restart command incorrectly can crash your machine.
You can issue a restart command at any point in your program,
which causes execution to jump back to the beginning of your code
and run up to the first line of the main function. However, restart
does not finish executing the rest of your program before it returns to
the beginning, and cleanup procedures located at the end of a program
are not executed. These cleanup procedures return memory and
registers to a state expected by the operating system and other
programs. Failing to complete execution of your program before
restarting or exiting CodeProbe may leave the machine in an
unacceptable state that will later cause a crash.
Using Online Help
At any point in your debugging session, you can use the help
command to get online help regarding debugger commands and other
CodeProbe features. The help command can be issued from the
command line using either of the following forms:
h[elp] [command]
? [command]
Sample CodeProbe Session 27
The optional command parameter specifies the debugger command for
which help information is to be displayed. A brief description, a
summary of command syntax, some sample uses, and references to
other commands is provided.
If you enter the help command without the command parameter, a
list of debugger commands is displayed along with other topics for
which online help is available. To make a selection from the list,
double-click the mouse pointer on one of these commands or topics.
Controlling the Debugging Session
After you have invoked the debugger, you control your debugging
session by entering debugger commands as described in Chapter 1,
"Introduction to CodeProbe." Reference information for each of the
debugger commands is provided in Chapter 9, "Commands and Built-in
Functions."
Setting the Source Mode
The source mode controls the way the source code is displayed in the
Source window. You can use a pull-down menu to change the source
mode. Hold down the right mouse button and drag the pointer through
the menu items under the Options menu. The Source Mode option
appears as a menu item and indicates C as the default mode. When the
Source Mode option is highlighted, three subitems are offered as
choices: C, Asm, and Mixed. Modifying the selected choice alters the
appearance of the lines in the Source window accordingly. For
instance, Display 2.1 shows the results of selecting mixed mode, while
Display 2.2 shows the results of selecting assembly mode. When
debugging a C application, you should usually choose C mode. Refer to
the section
"Source Mode" in Chapter 4 for additional information.
28
29 Sample CodeProbe Session
Activating Autoswap Mode
You also can activate Autoswap mode from the options nlellu. ~-he
autoswap mode is on, the screen containing the application's OlltpUt is
pushed to the front each time CodeProbe gives cont1ol to the
application. When a breakpoint is reached, the debugge1 screen is
pushed again to the front. If autoswal) mode is not on, you must
change to the output screen manually using functio1l key 19 or the
keyboard shortcut left-Amiga-m. Regardless of what metllo(l yoll
use to swap screens, you must activate each screen by first clicking the
left mouse button before entering any input.
Stepping Over Code
One of most useful features of the debugger is the ability to step
through code. The proceed command enables you to single step over
function calls. If you need to step into a called functioll you can use
the trace command. Since the proceed command is the most
frequently used command, CodeProbe is designed so that pressing the
Return key causes the proceed command to be executed. Step over
the first few lines of code as follows:
lines:\lines.c\main 71
>
lines:\lines.c\main 72
>
lines:\lines.c\main 73
>
lines:\lines.c\main 74
Select the Options menu and turn Autoswap mode on. Now step
over several more lines of code. Notice the qllick flashing due to the
display of the application window (the initial Workben( 1l ( Ll window)
during each step.
lines:\lines.c\main 79
>
lines:\lines.c\main 80
>
lines:\lines.c\main 81
>
lines:\lines.c\main 82
30 Chapter 2
You will notice also that the debugger does not stop at every line.
This is due to the fact that code is not generated for all lines. Code is
not generally produced for lines that declare variables, such as lines
66-68, or lines that are blank or contain only comments.
Continuing Execution
If you do not want to take the time to execute each line individually,
you can use the go command, which executes your application until it
either encounters a breakpoint (a flag to stop execution) or the end of
the program. You should always use go to complete execution of your
program before quitting CodeProbe or using the restart command.
Displaying a Structure Or an Array
The display command, which can be abbreviated as d, allows you to
display structures, arrays, and variables easily. For instance, to display
the structure nw, issue the following command in the Dialog window:
>display nw
struct NewWindow {
LeftEdge = 100 (0x64)
TopEdge = 100 (0x64)
Width = 300 (0x12C)
Height = 100 (0x64)
DetailPen = '\x02' 2 (0x02)
BlockPen = '\x01' 1 (0x01)
IDCMPFlags = 514 (0x202)
Flags = 1039 (0x40F)
FirstGadget = 0x0
CheckMark = 0x0
Title = 0x00226028
Screen = 0x0
BitMap = 0x0
MinWidth = 50 (0x32)
MinHeight = 50 (0x32)
MaxWidth = 640 (0x280)
MaxHeight = 400 (0x190)
Type = 1 (0x1)
}
Use F2 to zoom the Dialog window to full size so that the entire
structure can be viewed at once. The value of the character pointer
Title will
probably be different on your screen, but the other values
31 Sample CodeProbe Session
should be the same. When you have finished viewing, press F2 to
restore the Dialog window to its original size.
To display the two-dimensional array ox, issue the following
command from the Dialog window:
> display ox
{
[0] = {
[0] = 0
[1] = 0
[2] = 0
.
.
.
Then press F2 again to zoom the Dialog window to full size. While the
values are not noteworthy, you can get an idea of the format that is
displayed. Notice that the entire array does not fit in a full-size
window. To see the beginning values, use the mouse and the Dialog
window's vertical scroll bar to scroll backwards.
Individual members of structures and unions, as well as elements of
arrays, can be displayed using the display command, as in the
following examples:
> display nw.Type
1 (0x1)
> display xIl]
0 (0x0)
> display w->RPort
0x07F000FC
> display 0x[1][5]
0 (0x0)
> display nw.Title
0x00226028
> dzero nw.Title
"Nervous Lines"
You probably will find different results for the third and fifth
examples. Notice that the last command dzero indicates that
nw . Title should be treated as a pointer to a null terminated string
and its contents displayed rather than the pointer
itself.
32 Chapter 2
Setting a Breakpoint
A breakpoint is an address at which program execution stops whenever
encountered. To set a breakpoint, move the pointer to a given line of
code in the Source window. Using the left mouse button, double-click
on the line. This sets a breakpoint on the line, and the line is
highlighted. If there is no code generated at the line, an error message
is displayed in the Dialog window. The breakpoint can be removed
easily by double-clicking again on the particular line of code.
Executing up to a Breakpoint
Use your mouse to scroll down to line 111 in the Source window and
double-click on line 111 to set a breakpoint. Now execute the program
up to the breakpoint by typing the go command on the command line.
The breakpoint line is now highlighted in a different way to indicate
that execution has proceeded to that point. Double-clicking on the line
turns off the breakpoint. The line reverts back to normal, highlighting
just the text, indicating this is the next line to be executed.
Displaying the Value and Type of a Variable
The debugger will display a variable's value and tell what type it is.
Enter the following commands in the Dialog window:
> display i
2 (0x2)
> whatis i
auto register variable in d7 (2 bytes)
short i;
> whatis x
extern at 0022625E (8-byte array of 2 4-byte element(s))
int x[2];
> whatis nw
extern at 00226036 (48 bytes)
struct NewWindow nw;
Notice that the whatis command can provide information about the
location and attributes of any variable. This is particularly useful for
keeping track of automatic variables, which may be placed in registers
by the compiler, even though they were not explicitly declared as type
register.
Using the watch and watch break Commands
A watch allows you to monitor a variable or area of memory to see
when the value of
the variable changes or when the area of memory is
33 Sample CodeProbe Session
altered. Create a watch for the variable x by issuing the following
command:
> watch x
Open the Watch window by pressing the ~1 key. You may have to
adjust the size of the Watch window to see the entire display. Note
that the output shown in the Watch window is a hex dump of the
variable x:
1 <dynamic> x : 00 00 00 51 00 00 00
The number 1 at the left of the display identifies the watch. It is
used by other commands that manipulate the Watch window.
A watch break is similar to a watch but acts as a breakpoint when
the variable or area of memory is changed. Create a watch break for
the variable y by issuing the following command:
> wbreak y
At this point the Watch window should appear as follows:
1 <dynamic> x : 00 00 00 51 00 00 00
2! <static 0x36C472> y : 00 00 00 30 00 00 00
Notice that the watch break is highlighted and has an exclamation
mark (!) following the watch break number. The exclamation mark
indicates that it is a watch break and not simply a watch.
Executing Until the Variable Changes Value
The Watch window is updated when control is returned to you by the
debugger, such as at a breakpoint, and the new values of the watched
areas are displayed. Note that runrling with set watch breaks can be a
slow process because the CPU executes the application in trace mode.
This means that control returns to the debugger after every
instruction. The debugger must then check the memory for all watch
breaks before restarting the application. The watch break feature is a
powerful tool, and it is particularly useful for locating obscure bugs
that cause memory to be overwritten from unusual places in the code;
however, it should not be used indiscriminantly.
34 Chapter 2
To see the effect of the watch break, click in the Dialog window and
issue the go command:
> go
break (watch #2)
2! <static 0x36C472> y: 00 00 00 38 00 00 00
lines:\lines.c\main 117
Notice that the debugger reports the watch break number that
caused the breakpoint to occur. Also, notice that the line that modified
the variable was actually the previous line. Line 116 is the next line to
be executed.
Clearing All Watches and Watch Breaks
To clear watches and watch breaks, issue the following Dialog window
command:
> wclear *
The asterisk (*) is a wild card representing all watch and watch
break identifiers.
Now that all watches and watch breaks have been cleared, issue the
go command to start the program l ines . c. Notice that no
breakpoints can be reached now, so the program will continue until
completion. Standard input/output is written to the application window
on the Workbench screen.
To see the application as it is running, you can use the
left-Amiga-m key sequence to swap screens. The demo will run
until the close gadget is activated on the l ines.c application window.
After closing the application window, swap screens back to CodeProbe.
The Dialog window should now display the following:
Program exited with code 0.
The code value cited, 0 in this case, is the return code from the
program.
Quitting the Debugger
To quit the debugger, issue the command quit at the command line,
or use the
pull-down menu item in the File menu.
35
3 Debugging Your Program
35 Introduction
36 CodeProbe Commands
37 Sample Program 1
37 Source Code
39 Running Program 1
39 Controlling Program Execution
39 The go Command
44 Single Stepping
45 The trace Commands
46 The proceed Commands
47 Breakpoints
48 The break Command
53 Sample Program 2
54 Source Code
56 Running Program 2
57 Examining Data and Data Structures
57 The display Command
61 The dump Command
66 The register Command
68 The whatis Command
69 Walches and Watch Breaks
70 The watch and wbreak Commands
Introduction
This chapter explains the use of several common CodeProbe commands
to perform the following tasks:
control program execution
examine data and data structures
modify data
use watches and watch breaks.
The commands used to perform these tasks also are explained in this
chapter because they can be complex to use effectively.
36 Chapter 3
CodeProbe Commands
This chapter introduces the following complex CodeProbe commands:
break go watch
display proceed wbreak
dump trace whatis
There are additional commands that are not discussed here. For a
complete listing of the commands and detailed reference information,
refer to Chapter 9, "Commands and Built-in Functions."
Commands for Running Sample Programs
The following commands are useful when running the sample
programs described in this chapter:
bclear
clears one or more breakpoints
blist
displays a list of all the breakpoints that have been set
restart
reloads your program and reinitializes your static data allowing you
to start over from the top.
Note: The restart command is an advanced command. Before
using it to debug your programs, you should review carefully the
restart command in Chapter 9.
Additional Commands
In addition to the commands described in this chapter, you should
become familiar with the following commands, which are described in
Chapter 9, to get the most out of CodeProbe:
bdisable rflag wdisable
benable set wenable
call symbol wlist
jump where
return wclear
37 Debugging Your Program
Sample Program 1
To view the commands described in the first part of this chapter, you
should compile, link, and debug Sample Program 1. It is a simple
program consisting of three modules (smain.c, sort.c, and
swap.c) that first initializes an array of integers from O to 9 and then
sorts the array into reverse order.
The examples in this chapter are designed so that you start
CodeProbe only once, at the beginning of the section, and then run
each example in order. Running the examples out of order can
produce results that do not agree with the documentation. Extra go
and restart commands are included with several of the examples to
position the file back at its beginning. The same results can be
achieved by entering go, quitting CodeProbe, and starting a new debug
session with the same program. Note, however, that you should always
allow your program to run to completion before restarting or quitting
CodeProbe.
Source Code
The following source code for Sample Program 1 is provided in the
sc:examples/debugger drawer:
/* SMAIN.C */
(1) #define ASIZE 10
(2)
(3) void init(int *, int);
(4) int sort(int *, int);
(5)
(6) int array[ASIZE];
(7)
(8) void main(void)
(9) {
(10) init(array,ASIZE); /* initialize array[] */
(11)
(12) /* Keep swapping elements until sorted */
(13) while (sort(array,ASIZE) != 0)
(14) ;
(15) }
/* SORT.C */
(1) void swap(int *, int *);
(2)
(3) void init(int *ip, int
size)
38 Chapter 3
(4) {
(5) int i;
(6) int *p;
(7)
(8) p = ip;
(9) for (i = 0; i < size; i++)
(10) *p++ = i;
(11) }
(12)
(13) /* Reverse sort elements of an array */
(14)
(l5) int sort(int *ip, int size)
(16) {
(17) int i, s;
(18) int *p;
(19)
(20) p = ip;
(21) s = 0; /* no swaps performed yet */
(22)
(23) for (i=0; i < size - 1; i++)
(24) if (p[i] < p[i+1] )
(25) {
(26) swap(&p[i], &p[i+1] );
(27) s = 1; /* indicate a swap took place */
(28) }
(29)
(30) return(s);
(31) }
/* SWAP.C */
(1) void swap(int *x, int *y)
(2) {
(3) int tmp;
(4)
(5) tmp = *x;
(6) *x = *y;
(7) *y = tmp;
(8) }
39 Debugging Your Program
Running Program 1
To run Sample Program 1, compile, link, and load it into the debugger
as follows:
1. Compile and link Sample Program 1 using the following
command:
sc debug=sf link sort.c smain.c swap.c
2. Start CodeProbe by entering the following command:
cpr sort
Controlling Program Execution
With CodeProbe you can exercise a high degree of control over
program execution. You can single step through your program (at
either the assembly or C source level), step over or into function calls,
set breakpoints at source line or instruction addresses, or go to a
specific location.
This section describes the following Dialog window commands for
controlling program execution:
break
sets a breakpoint at the specified location.
go
starts the execution of the program you are debugging and
continues until it hits a breakpoint or the end of the program.
Execution begins at the line highlighted in the Source window.
proceed
single steps through your program or steps through it a given
number of times, stepping over function calls, unless they contain a
breakpoint.
trace
single steps through your program or steps through it a given
number of times breaking at a function call.
The go Command
The go command starts the execution of the program you are
debugging. This command uses the following syntax:
g[o] [location
[after(integer)] [when(expression) ]]
40 Chapter 3
The go command has three different parameters: location,
after(integer), and when(expression). Note that the parentheses
around the expression and integer parameters must be typed in.
The optional location parameter indicates where execution should
terminate. When the go command is used, the debugger sets a
temporary (non-sticky) breakpoint at a specified location. This
breakpoint is temporary in the sense that the breakpoint is deleted
after it is encountered. If you already have a normal breakpoint at a
particular location and execute the go command to that location, the
original breakpoint is cleared.
The after clause uses the integer parameter to specify the number
of times that the line indicated by the location parameter should be
executed. This is called a pass count and program execution stops after
the line is passed the specified number of times.
The when clause uses the expression parameter to specify the
circumstances under which execution is suspended at location.
In its most general form, the go command can be read as: go until
location has been executed integer number of times and stop the next
time location is reached when the expression is true.
When used without parameters, the go command starts the
execution of your program, which runs to normal completion if no
active breakpoints are encountered.
Specifying a Location
The location parameter specifies the point in your program at which
you want execution to stop. You can specify either an address or line
number in a source file and a breakpoint will be set at that location. A
location can take any of the following forms:
address
line
function
function line
\module\function [line]
image: function
image: function [line]
image:\module\function [line]
The address form of the location parameter is used to specify an
explicit address constant. This form is useful for setting breakpoints at
specific
addresses when debugging in assembly mode.
41 Debugging Your Program
The line parameter is usually a number referring to the line number
where you want execution to stop. Other possibilities for line are the
following:
$
refers to the current line
e[ntry]
refers to the first instruction of the specified function, or the
current function if none is specified
r[eturn]
refers to the last instruction of the specified function, or the current
function if none is specified.
A line number is always relative to the beginning of the module. The
line parameter can be used in conjunction with the function parameter
to describe a location. For instance, in the form
function line
line refers to the line number of the module containing function. If the
specified line is not inside the specified function, an error is printed. If
a function is specified without a line parameter, the entry point to the
function is assumed.
When the specified location is reached, a message is displayed
describing the source filename, the function name, and the line
number. If mixed or assembly mode has been specified, the
information is preceded by the breakpoint address. For example, using
Sample Program 1 shown earlier in this chapter, the session log
displayed in the Dialog window would look as follows, if C mode is
currently chosen:
> go swap 5
sort:\swap.c\swap 5
> opt source mixed
> go swap 7
at 0x38974C sort:\swap.c\swap 7
> opt source c
> go
program exited with code 0.
> restart
starting "sort"
sort:\smain.c\main 10
42 Chapter 3
Here execution has stopped after the second go command was
issued, at line 7 of the file swap.c, and within the function swap.
If the module is not specified, a search will be made among your
modules, beginning with the current module, until function is found. In
the unlikely event that you have defined two functions in separate
modules with the same name and belonging to the same static storage
class, then it is necessary to specify the module.
If a function is not specified, the currently executing function is
assumed.
If an image parameter is specified, it refers to the name of a
program or shared library that may or may not have been loaded. If it
is not yet loaded, the debugger sets a deferred breakpoint in the
library or program. When the library or program is loaded a
breakpoint is set and program execution proceeds. If the debugger
cannot find the debugging information for the image, it will halt when
the image is loaded. At this point you can use the symload command
to specify the location of the version to be debugged. For example, the
following go command causes the program to execute until
mylib.library is loaded, a breakpoint is then set at LIBmyfunc,
and program execution continues. This example command will not
work with Sample Program 1.
go mylib.library:LIBmyfunc
Specifying the after Clause
As previously described, the after(integer) parameter is used to
specify a pass count, which is the number of times that the line
indicated by the location parameter should be executed. For example,
if you enter the following command in the Dialog window after starting
CodeProbe with Sample Program 1, execution will stop after the
while statement on line 13 of the program has executed 5 times:
> go 13 after(5)
sort:\Work:examples/smain.c\main 13
Specifying the when Clause
The when ( expression ) parameter is used to further control program
execution. An expression can be any valid C expression. For example,
any of the following expressions can be used with a when clause:
i == 7
i < 12 || i > 5
i != 4
&& strlen(string) != 7
43 Debugging Your Program
Consider the following loop in the sort routine of Sample Program
1:
for (i = 0; i < size - 1; i++)
if (p[i] < p[i + 1])
You may want to stop at a point within the loop, but only after a
certain number of iterations of the loop have been executed. Assuming
that the f or statement is on line 23, this can be accomplished with
the following go command:
> go sort
sort:\Work:examples/sort.c\20
> go 4 when (i == 7)
sort:\Work:examples/sort.c\sort 4
This has the effect of planting a non-sticky breakpoint at line 24 of
the current module. That is, the breakpoint will be triggered only if the
when condition is true; otherwise execution will continue past the
specified line. Note that the specified line is the line after the loop. This
is because breakpoints are set at the beginning of a line, before the
code on the line is executed. If the breakpoint had been set at the line
on which the for statement occurs, the breakpoint would never have
been encountered while the loop was executing. For example, if you
give the following command the breakpoint would not be triggered,
because i will never be less than 0 and the program will run to
completion:
> go 24 when (i == -1)
program exited with code 0.
Breakpoints are discussed in greater detail later in this section.
If you make any mistakes in syntax when entering the condition,
errors are not detected until the first time the specified location is
reached and the debugger attempts to evaluate the condition. If the
debugger cannot evaluate the condition, the breakpoint is triggered and
an error message is displayed. The message indicates the position in
the condition where syntax rules have been violated. For
example, the
44 Chapter 3
following message indicates that ! < violates rules governing permitted
relational symbols:
> restart
> go sort
> go 24 when (i !< 1)
Processing the when clause:
(i !< 1)
^-------------syntax error
sort:\sort.c\sort 24
Examples
The following are examples of ways to use the go command:
go main
goes until the entry point of function main
go return
goes until the end of the current function
go 0xc80200
goes until the address 0xc80200 is reached
go sort 24 when ( i==5 )
goes until line 24 of the sort function when i equals 5
go init 10 after(5) when (i>4)
goes until pass 5 at line 10 in the init function when i is greater
than 4
Single Stepping
The proceed and trace commands can be used to single step your
program. Each command has two variations: one to single step at the
assembler level and the other to single step at the C source level. The
difference between the two commands lies in their handling of function
calls.
The proceed commands step over function calls; if a function call
is encountered during the execution of a proceed command, the
function is executed without a break occurring (unless one has been
deliberately set in the function), and then the next line after the
function call is highlighted. Execution continues in the calling function.
This is in contrast to a trace command, which steps into function
calls, highlighting the first line of the function as the next line to be
executed.
45 Debugging Your Program
The trace Command
The trace commands, t and ts, are used to single step your
program. The t command is for single stepping assembler instructiolls.
The ts command stands for trace source and is used for single
stepping C code. The syntax for the trace commands is as follows:
t[racel [integer]
ts [integer]
The optional integer parameter indicates the number of steps to be
executed; if absent, a single step is executed. A step is considered to be
either one assembler instruction or a single line of C source code.
Either trace command will step into any function calls encountered
during the step. That is, the called function is entered and execution is
suspended at its first instruction.
The actions of these commands depend on the current source mode
of the debugger. In C source mode, the two trace commands act
identically, causing the execution of one line of C source code up to
any imbedded function call. In assembly or mixed mode, t executes
one machine instruction; ts always executes a single C source line.
Both trace commands step into function calls. Regardless of the
mode, if the current line contains a function call, then the first line of
that function is executed and subsequent t commands execute lines
within that function. In assembly mode, if the current line contains a
JSR (Jump to SubRoutine) or a BSR (Branch to SubRoutine)
instruction, then that instruction is executed and subsequent t
commands execute instructions in the called function.
Using Sample Program 1 given earlier in this chapter and starting
over from main with the restart command, trace for several steps
in source mode as shown here:
> go
program exited with code 0.
> restart
sort:\smain.c\main 10
> trace
sort:\sort.c\init 4
> trace
sort:\sort.c\init 8
> trace 3
sort:\sort.c\init 9
sort:\sort.c\init 9 (+0x2)
sort:\sort.c\init
10
46 Chapter 3
sort:\sort.c\init 9 (+0x2)
sort:\sort.c\init 10
sort:\sort.c\init 9 (+0x2)
The first trace command carries us to the init call in main. The
second then moves us into the init function. The third illustrates the
use of a numeric argument to execute several steps.
To step by a single machine instruction, you can set the source to
either asm or mixed. For instance, you can set your source mode to
asm by using the pulldown Options menu or by issuing the following
command:
opt source asm
Similarly, you can set your source to mixed with the following
command:
opt source mixed
At this point, you can enter the trace command to step over an
assembler instruction.
If source mode is set to asm and no line information is available,
using the ts command is regarded as an error, and an appropriate
error message is displayed. In mixed mode, the trace command
causes stepping by machine instruction while the ts command causes
stepping by C source line.
The proceed Commands
The proceed commands, p and ps, also are used to single step your
program or to step it a given number of times. Unlike trace,
however, a proceed command steps over function calls rather than
stepping into them. That is, if a call to a function is encountered in the
process of the step, the function is not stepped into as in the trace
commands.
The syntax for the proceed commands is as follows:
p[roceedl [integer]
ps [integer]
47 Debugging Your Program
The integer parameter indicates the number of steps to be executed.
The proceed and ps commands are analogous to the trace and ts
commands with respect to source mode.
Looking at the previous example, notice how the results of the
proceed commands differ compared to the trace commands (C
source mode is used again):
> go
program exited with code 0.
> restart
sort:\smain.c\main 10
> proceed
sort:\smain.c\main 13
> proceed
sort:\smain.c\main 14
> proceed
sort:\smain.c\main 13
Here, a single step has been made for each source line of the
function main. Function calls were made in the process of this
stepping, but none of the called functions were entered.
Pressing the Return key is equivalent to entering the p command.
Continuing where the previous example left off, the following example
demonstrates how this works:
> <Return>
sort:\smain.c\main 14
> <Return>
sort:\smain.c\main 13
Using the ps command in assembly mode is regarded as an error if
no source line information is available, while proceed can be used in
mixed or assembly mode to single step by machine instruction. The ps
command can be used in mixed mode to step by C source line in a
manner similar to the ts command.
Breakpoints
A breakpoint is an address at which program execution stops. The
break command enables you to suspend the execution of your
program or to execute a set of debugger commands at any point you
choose.
By setting conditional breakpoints or by using a pass count to specify
the number of times a program should pass a breakpoint before
execution is
stopped, you can suspend program execution at just the
48 Chapter 3
right stage of your program. This means, for example, that you can set
a breakpoint at a line within a loop so that the program stops after
going through 500 iterations of the loop. By triggering a breakpoint in
this way, you are able to easily reach the point in the program that
you want to examine.
Besides breakpoint setting, additional commands allow you to
manage your breakpoint list. bc lear provides you with the ability to
clear a breakpoint, bdisable temporarily disables a breakpoint,
benable enables it again, and blist lists the current breakpoints.
The break Command
The break command enables you to specify a breakpoint. Breakpoints
are used to suspend the execution of a program at any point or execute
a set of debugger commands instead of suspending execution. You can
also set and clear breakpoints by double-clicking the mouse on a line in
C source mode or an assembly instruction in asm or mixed mode.
The syntax of the break command has two forms:
b[reak] $
b[reak]location[after(integer)][when(expression)]
[tr[ace]] [q[uiet]] [te[mp]] [{cmd-list}]
In the first form, a breakpoint is set at the current location (which in
C source mode is the cutrent line). This is handy when you have
stepped to a certain point in your program and want to set a
breakpoint quickly at the current line. Here is an example:
> go sort
sort:\sort.c\sort 20
> <Return>
sort:\sort.c\sort 21
> <Return>
sort:\sort.c\sort 23
> break $
> go
sort:\sort.c\sort 23
In this case we have single stepped twice by pressing Return (the same
as a proceed command). When the breakpoint is set with the break
command, line 23 in the Source window is highlighted. A breakpoint
also can be easily and quickly set or removed by double-clicking on the
line in the Source window where you want the breakpoint.
49 Debugging Your Program
The second form of the break command allows you to set a
breakpoint at a specified line number and to ensure that the breakpoint
is not triggered until that line has been executed a specified number of
times.
For example, suppose you want to set a breakpoint at the if
statement in the sort routine, but you want the breakpoint triggered
only after the fifth time that statement is executed. You can use the
following commands:
> break sort 24 after(5)
> blist
1 0xC32DCA sort:\sort.c\sort 23 (1 hit)
2 0xC32DD4 sort:\sort.c\sort 24
after(5)
> go
sort:\sort.c\sort 24
> display i
4 (0x4)
The fact that the value of i is 4 indicates that the loop has already
executed five times. You will find the pass count feature to be
especially useful in debugging programs containing loops that iterate
many times.
Conditional Breakpoints
Although breakpoints with pass counts are a kind of conditional
breakpoint, the break command also allows for a more generally
useful kind of conditional breakpoint. Using the when option, you can
specify a condition that depends upon the values of variables in your
program. You might, for example, want to stop at the i f statement in
sort when the value of p[i] is 8:
> bclear *
> break sort 26 when (p[i] == 8)
> go
sort:\sort.c\sort 26
> display p[i]
8 (0x8)
Any valid C expression can be used as an argument in a when
clause.
Of course the after option can be used to specify a pass count in
conjunction with the when clause. Both the pass count and
the when
50 Chapter 3
clause conditions must be met. You may, for example, want to see if
there is an instance where the array element is equal to the array
index after three or more executions of a given line:
> bclear *
> go
program exited with return code 0.
> restart
> break sort 26 after (3) when(p[i]==i)
> go
sort:\sort.c\sort 26
> dump i decimal
reg d6: 2
> dump plil decimal
00C28708 2
Attaching Actions to Breakpoints
Instead of just stopping at a breakpoint, you may want to have the
debugger perform one or more actions. You can do this with the
cmd_list parameter. The cmd_list parameter is a sequence of
debugger commands enclosed in braces ({}) and separated by
semicolons (;). The following example shows how to use the
cmd_list parameter to stop at line 25 of the sort function and
have the debugger automatically display the value of p[i] and the
value of i.
> bclear *
> break sort 26 {display "p[i] = ", p[i] ; display "i = ", i}
> go
sort:\sort.c\sort 26
p[i] = 2 (0x2)
i = 3 (0x3)
> go
sort:\sort.c\sort 26
p[i] = 2 (0x2)
i = 4 (0x4)
> go
sort:\sort.c\sort 26
p[i] = 2 (0x2)
i = 5 (0x5)
51 Debugging Your Program
In fact, you can arrange for the debugger not to stop at the
breakpoint but to continue by issuing the go command as the last
command in your list, as in the following example:
> bclear *
> go
program exited with code 0.
> restart
sort:\smain.c\main 10
> break sort 26 when (i < 3) {dump p L 4; go}
> break sort 24 when (i >= 3)
> blist
10 0xC32D4C sort:\sort.c\sort 26
when (i < 3) {dump p L 4; go}
11 0xC32D2C sort:\sort.c\sort 24
when (i >= 3)
> go
sort:\sort.c\sort 26
00C31260: 00000000 00000001 00000002 00000003
sort:\sort.c\sort 26
00C31260: 00000001 00000000 00000002 00000003
sort:\sort.c\sort 26
00C31260: 00000001 00000002 00000000 00000003
sort:\sort.c\sort 24
In this way, you can actually see the sort taking place and you do
not need to type in the go command repeatedly. Using the trace
option on the break command eliminates the need to include a final
go in the command list parameter. This is demonstrated in the
following example:
> bclear *
> break sort 26 when (i > 5) {dump p L 4;
break sort 26 when (i == 8) trace; blist}
> blist
12 0xC32D4C sort:\sort.c\sort 26
when (i > 5) {dump p L 4;
break sort 26 when (i == 8) trace; blist}
> go
sort:\sort.c\sort 26
00C31260: 00000001 00000002 00000003 00000004
15 0xC32D4C sort:\sort.c\sort 26
when (i == 8) trace
sort:\sort.c\sort 26
52 Chapter 3
Here a breakpoint is set at line 26 of sort and is to be triggered
when i has a value greater than 5. When triggered, the breakpoint
action displays the first four elements (16 bytes) of the array
referenced by p, sets a new breakpoint at the same line, lists the new
breakpoint, and continues execution. The new breakpoint is then
triggered when its when condition is satisfied.
This nesting of breakpoints within action lists is a powerful feature
of the debugger. Since nested breakpoints may become complex, you
should take great care in using them or you may lose your place in the
program when some breakpoints replace themselves with others.
You must also be aware that a breakpoint with an action may have
an effect (and perhaps an unexpected one) on program execution. To
consider a simple case, suppose you set a breakpoint on line 26 of
sort and attach to it an action that will alter the value of i:
> bclear *
> break sort 26 when (i == 5) [set i = 2]
> go
sort:\sort.c\sort 26
> dump i decimal
reg d6: 2
> go
sort:\sort.c\sort 26
> dump i decimal
reg d6: 2
In this simple case you have managed to create an infinite loop by
means of your breakpoint and action list. Such a simple mistake is easy
to find, but if you have planted a number of breakpoints or if your
breakpoints are deeply nested, the error might be very difficult to
detect. This example also demonstrates that the action for a breakpoint
is executed before control is returned to you; by the time you examine
the value of i, it has already been set to its new value by the set
command.
You can also use the trace, quiet, and temp options with the
break command. The trace option causes execution to continue
after the breakpoint is hit, the quiet option suppresses the default
message that is
printed when the breakpoint is hit, and the temp
53 Debugging Your Program
option deletes the breakpoint after it is hit. The following example
illustrates the use of these options:
> go
> restart
> bclear *
> break sort 26 trace quiet (display i)
> break sort 30 temp
> blist
1 0xC32D4C sort:\sort.c\sort 26
trace quiet (display i)
2 0xC32D66 sort:\sort.c\sort 30
temp
> go
0 (0x0)
1 (0x1 )
2 (0x2)
3 (0x3)
4 (0x4)
5 (0x5)
6 (0x6)
7 (0x7)
8 (0x8)
sort:\sort.c\sort 30
> blist
1 0xC32D4C sort:\sort.c\sort 26
trace quiet (display i)
Sample Program 2
To view the commands described in the second part of this chapter,
you should compile, link, and debug Sample Program 2. It is a simple
program consisting of one module (data.c).
Sample Program 2 defines and initializes various data structures. It
is intended only for exploring the data manipulatiorl fullctiolls of
CodeProbe and has no practical use. The following sections use
examples based on Sample Program 2 to explore various colnnlallds to
display data and data structures.
54 Chapter 3
Source Code The following source code for Sample Program 2 is provided in the
sc:examples/debugger drawer:
#inclUde <stdio.h>
void main (void)
{
struct X {
int a;
int b[3];
int c;
} x;
struct Y {
int a;
int b;
} Y;
typedef struct X *XPTR;
struct W {
int x;
struct Y y[2];
int z;
} w;
struct Z {
char c;
struct Y d;
int e;
} z;
struct X3D {
int a;
int b[2][3][2];
int c;
} x3d;
int i,j;
int arrayl[0];
int
*intptr;
55 Debugging Your Program
long lng;
short shrt;
float fl;
double db;
char *string = "Hello, World";
/* Initialize data structures. */
i = 33;
j = 44;
intptr = &i;
lng = 6456;
shrt = 89;
fl = 3.14;
db = 33.5;
array[O] = 5;
array[1] = 15;
array[2] = 25;
array[3] = 35;
array[4] = 45;
array[5] = 55;
array[6] = 65;
array[7] = 75;
array[3] = 89;
array[9] = 95;
x.a= 5;
x.b[0] = 1;
x.b[1]=2;
x.b[2]=3;
x.c=11;
y.a=5;
y.b=6;
w.x= 4 ;
w.y[0] = y;
w.y[1] = y;
w.z =
9;
56 Chapter 3
z.c = 'r';
z.d = Y;
z.e=3;
intptr = &j;
x3d.a=2;
x3d.b[0][0][0] = 41;
x3d.b[0][0][1] = 42;
x3d.b[0][1][0] = 43;
x3d.b[0][1][1] = 44;
x3d.b[0][2][0] = 45;
x3d.b[0][2][1] = 46;
x3d.b[1][0][0] = 47;
x3d.b[1][0][1] = 48;
x3d.b[1][1][0] = 49;
x3d.b[1][1][1] = 50;
x3d.b[1][2][0] = 51;
x3d.b[1][2][1] = 52;
x3d.c=90;
printf("%s!\n",string);
}
Running Program 2
To run sample program 2, compile, link, and load it into the debugger
as follows:
1. Compile and link using the following command:
sc debug=sf link math=standard noautoregister data.c
2. Start CodeProbe by entering the following command:
cpr
data
57 Debugging Your Program
Examining Data and Data Structures
CodeProbe offers several commands that you can use to display the
data referenced by your program. This section describes the following
commands for examining data and data structures:
display
displays an object, area of memory, or the result of an expression
dump
examines the value of any variable in a program, an arbitrary range
of memory, a register, or an expression
register
displays or modifies the current settings of the machine integer
registers
watch
sets a variable or area of memory to be watched
wbreak
sets a breakpoint when a watched variable or area of memory
changes
whatis
determines the type and address of a variable or the fundamental C
type to which a typedef identifier resolves.
The display Command
The display command displays C data structures and objects and
can display an object or area of memory interpreted as a specified type
of object.
The syntax of the display command is as follows:
d[isplay] (expression["format"] | string)[,...]
The expression parameter can be any C expression containing
constants, variables, and function calls from the program being
debugged except expressions involving the comma operator (,), the ?:
operator, the various assignment operators (+=, -=, and so on), or the
prefix and postfix operators (++ and --)
To override the default format, a format specification like those used
with the printf statement can be used after each expression. The
forrnat parameter can contain up to two conversion operators for short
and long types, but only one for all other types. No error checking is
done on the format and strange results are possible.
If an address is specified as the expression parameter, and it is an
address constant, then, in the absence of a forrnat parameter, the
address is assumed
to be of type char *.
58 Chapter 3
The string parameter can be any standard C string as described
earlier in this chapter. The string is echoed in the Dialog window.
The display command can accept multiple arguments, each of the
following form:
(expression["format"] | string)
The arguments must be separated by commas. Given this information,
the following are examples of the display command:
> display i
> display 0xC80FF8
> display i "i is equal to %d"
> display a "a=%10.5e"
> display p->d[5] + myfunction(3)
> display x "X is %d", j "J is %d"
Before using Sample Program 1 in the examples shown in this
section, enter the following command to execute all of the data
initialization code:
> go 110
Now you can display the value of an integer variable as shown here:
> display i
33 (0x21)
To display its address, use the following command:
> d &i
0xC309B8
Note that register variables do not have an address; if you try to use
the and (&) operator on a register variable, you will get an error
message. This is why the example program was compiled with the
noautoregister
option.
59 Debugging Your Program
It is equally simple to display an array element as follows:
> d *array
5 (0X5)
> d array[0]
5 (0x5)
You can display an entire array as follows:
> display array
{
[0] = 5 (0x5)
[1] = 15 (0xF)
[2] = 25 (0x19)
[3] = 35 (0x23)
[4] = 45 (0x2D)
[5] = 55 (0x37)
[6] = 65 (0x41)
[7] = 75 (0x4B)
[8] = 85 (0x55)
[9] = 95 (0x5F)
}
Structures are also easy to analyze using the display command as
follows:
> d x
struct X {
a = 5 (0x5)
b = {
[0] = 1 (0x1)
[1] = 2 (0x2)
[2] = 3 (0x3)
}
c = 11 (oxB)
}
60 Chapter 3
> display z
struct Z {
c = 'r' 114 (0x72)
d = struct Y {
a = 5 (0x5)
b = 6 (0x6)
}
e = 3 (0x3)
}
Multidimensional arrays are displayed in a format that enhances
analysis as follows:
> d x3d
struct X3D {
a = 2 (0x2)
b= {
[0] = {
[0] = {
[0] = 41 (0x29)
[1] = 42 (0x2A)
}
[1] = {
[0] = 43 (0x2B)
[1] = 44 (0x2C)
}
[2] = {
[0] = 45 (0x2D)
[1] = 46 (0x2E)
}
}
[1] = {
[0] = {
[0] = 47 (0x2F)
[1] = 48 (0x30)
}
[1] = {
[0] = 49 (0x31)
[1] = 50 (0x32)
}
61 Debugging Your Program
[2] = {
[0] = 51 (0x33)
[1] = 52 (0x34)
}
}
c = 90 (0x5a)
}
A conversion string can also be used as a format parameter:
> display i "i is equal to %d"
i is equal to 33
The dump Command
The dump command provides a simple way for yoll to examine the
value of any variable in your program or to examille an arbitrary
range of memory. The syntax of the dump comlllalld is as follows:
du[mp] [variable | address | range ] [$] [style . . . ]
The variable, address, or range parameter specifies the location to be
dumped.
The style parameter controls the format of the dulllp. I or complete
details on usirlg the dump comman(t, see tne dump section in
Chapter 9.
Dumping a Variable
In its simplest form, dump displays the melllory at the address (tile
contents) of a variable. For example, the followillg comlrlall(t disl)lays
memory starting at the address of i:
> dump i
003c8466: 00000021
Note that the hexadecimal value 00000021 eqllals the decimal value
33, the value of i. By default, dump displays memory in the
hexadecimal format. The number to the left of the hexadecimal value,
003C8466, is the address of i. Tlle dump comlllarld always displays
the addresses of the memory blocks displayed. To display memory in
decimal format, use the decimal option.
62 Chapter 3
> dump i decimal
003C8466: 33 0 0 0
003C8476: 0 0 0 0
003C8486: 0 0 0 0
003C8496: 0 0 0 0
The variable parameter can be any valid C variable. When a variable
parameter is specified, the amount of memory dumped is determined
by the size of the object (or in the case of a pointer, the size of the
object to which it points.) However, in the case of a character pointer
or an address constant, 64 bytes of data are always displayed as
follows:
> dump string ascii
00394728: H e l l o , W o r l d \0 \0 % s
00394738: ! \n \0 \0 \0 \0 \0 \0 \0 \0 @ \0 \0 \0 \0 \0
00394748: \0 \0 \0 \0 \0 \0 \0 01 \0 \0 \0 \0 \0 \0 \0 \0
00394758: \0 \0 \0 01 \0 \0 \0 \0 \0 \0 \0 01 \0 \0 \0 01
Dumping an Address
You can specify any valid address in the dump command, even
addresses not under the control of your program. The following
command specifies the address of the variable i. Note that the address
parameter is preceded by a 0x. Here is an example:
> dump 0x3c8466 decimal
003C8466: 33000
003C8476: 0000
003C8486: 0000
003C8496: 0000
Dumping a Range
When a range parameter is specified, exactly that amount of data is
displayed, unless the size of the range is not perfectly divisible by the
size of the specified type of data items. For example, the following
command specifies to dump 7 bytes of integer data starting at the first
address:
> dump 0x3c8466..0x3c846c decimal
0042D366: 33 -749469637
The dump actually includes an additional 1 byte of data to make up
the second 4-byte integer. The dump command automatically rounds
63 Debugging Your Program
the range up to the size necessary to correctly display at least all of the
memory specified as the data type specified.
You can also specify ranges by indicating the number of elements of
a data type to display, starting at a specified address or variable. The
following command dumps the decimal value of the integer i and the
next 12 bytes of memory (three additional integers of 4 bytes each):
> dump i L 4 decimal
003C8466: 33 2 41 4
The amount of memory that is displayed with a range option of this
type depends on the size of the data type. A command with a range of
four elements of type decimal will display 16 bytes. The default length
of f loat for the dump command is 8, so a command with a range of
four elements of type float will display 32 bytes.
Dumping a Pointer
Dumping pointers and memory pointed to by pointers can be
confusing. In the Sample Program 2 (data . c) the following variables
are defined and initialized:
int i;
int *intptr;
i = 33;
intptr = &i;
The following commands dump the contents of the variable i:
> dump i decimal
003C8466: 33
> dump intptr decimal
003C8466: 33 2 1 2
003C8476: 3 4 5 6
003C8486: 7 8 9 10
003C8496: 11 12 97 1927282688
> dump *intptr decimal
003C8466: 33
64 Chapter 3
> dump &i decimal
003C8466: 33 2 1 2
003C8476: 3 4 5 6
003C8486: 7 8 9 10
003C8496: 11 12 97 1927282688
All of these commands are equivalent. The dump command treats
variables that are addresses as already de-referenced. The dump
command assumes that, if you specify a pointer, you want to look at
what the pointer is pointing at. If you want to see the actual address
contained in the pointer, you can look at the first address in the dump.
You will note that all of the preceding dumps have O 0 3C8 4 6 6 as the
address containing 33, which is the address of i.
To dump the actual address of the pointer variable, use the following
command:
> dump &intptr
0064F676: 003C8466
The address of the pointer is the first number displayed. Sometimes
the compiler automatically stores a variable in a register. If this has
occurred for a variable, the preceding command will yield the
following result:
> dump &intptr
^------cannot be applied to registers or constants
Dumping Floating-Point Numbers
The float option is used with the dump command to specify the
format of floating-point numbers. The default number of bytes dumped
by the float option is 8. This is equivalent to type double under C.
Note that there is no double format specifier. To specify a 4-byte
f loat, equivalent to type float under C, use the f loat4 option.
Using the wrong format for a variable will cause the variable's value
to appear incorrect. For example, compare the following commands
and their results for the double variable db = 33.5 and the float
variable f1 = 3.14:
> dump db float4
004103FE: +3.0117187
> dump db float
004103FE:
+ 33.5
Debugging Your Program 65
> dump f1 float4
00410406: +3.1400001
> dump f1 float
00410406: +49.92001667991304
Dumping Integers
The decimal option is used with the dump command to specify the
format of integers. The decimal option dumps 32-bit (4 byte)
integers. This is equivalent to type long under C, and type int if the
shortinteger compiler option was not used. Note that the dump
command cannot distinguish between modules compiled with 16-bit
integers (using the shortintegers option) and those compiled with
32-bit integers (using the default.) Using the wrong format for a
variable will cause the variable's value to appear incorrect. The
following commands will dump an integer, a long, and a short.
Note the required format for the short:
> dump i decimal
00410436:33
> dump lng decimal
00410402: 6456
> dump shrt decimal
00410400: 5832704
> dump shrt decimal2
00410400: 89
Dumping Characters and Strings
Characters and strings may be dumped in several ways. The simplest is
to use the ASCII option as follows:
> dump z.c ascii
00410472: r
> dump string ascii
003BlB88: H e l l o , W o r l d \0 \0 % s
003BlB98: ! \n \0 \0 \0 \0 \0 \0 \0 \0 @ \0 \0 F E4
003BlBA8: \0 \0 \0 \0 \0 \0 \0 01 \0 \0 \0 \0 \0 \0 \0 \0
003BlBB8: \0 \0
\0 01 \0 \0 \0 \0 \0 \0 \0 01 \0 \0 \0 01
66 Chapter 3
When using the ASCII option, certain nonprintable characters
appear as their usual C escape sequences:
\b backspace
\f formfeed
\n new line
\r carriage return
\t horizontal tab
\v vertical tab
\o null byte (string terminator)
Other characters are represented by the two-digit hexadecimal codes.
You can also use the text option to display a block of data in
character format. The text option displays the address of the data items
on the left, the hexadecimal values in the middle, and the printable
characters on the right.
> dump string text
003BlB88: 48656C6C 6F2C2057 6F726C64 00002573 Hello, World..%s
003BlB98: 210A0000 00000000 00004000 0046E420 !.........@..F.
003BlBA8: 00000000 00000001 00000000 00000000 ................
003BlBB8: 00000001 00000000 00000001 00000001 ................
The dzero command can also be used to display an ASCII text
string terminated by a NULL character (\0) as shown here:
> dzero string
"Hello, World"
The string at that location is displayed in double quotes. Normally
you would use either a character pointer or an array name as the
argument to this command.
The register The register command has two forms, with and without parameters
Command as follows:
r[egister]
r[egister]
[register[ [=] expression ]]
67 Debugging Your Program
The first form of the register command displays the contellts of
all the registers, while the second form results in the specified value
being placed in the named register.
Displaying the Contents of Registers
If you use the register command without parameters, the current
contents of the registers are displayed in hexadecimal followed by the
current flag settings as shown here:
> register
dO=OOOOOOOl dl=00000002 d2=000003ED d3=00000000 d4=00000000
dS=OOOOOOOO d6=00000000 d7=00000000 aO=OOC2C102 al=000223BO
a2=OOC25CCO a3=OOC2C106 a4=OOC28F08 a5=00000000 a6=OOCOB9C8
sp=000229A8 pc=OOC32E82 ccr=OOOOOOOO na pl nz nv nc
sort:\smain.c\main 110
Registers dO through d7 and aO through a6 are labeled and
displayed. Register a7 is the stack pointer and is labeled sp. I'he
program counter is labeled pc, and the condition code register is
labeled ccr and is summarized by the two-letter flag abbreviations
immediately following.
Note that the current source line number is displayed immediately
after the display of the registers and flags.
~Itering the Contents of Registers
The second form of the register command is similar to the set
command. It allows you to alter the contents of registers. You can
specify the value you want placed in a register as an expression. Here
is an example:
> register
d0=00000001 d1=00000002 d2=000003ED d3=00000000 d4=00000000
d5=00000000 d6=00000000 d7=00000000 a0=00C2C102 a1=000223B0
a2=00C25CC0 a3=00C2C106 a4=00C2BF08 a5=00000000 a6=00C0B9C8
sp=000229A8 pc=00C32E82 ccr=00000000 na pl nz nv nc
sort:\smain.c\main 110
> register d7=5
> register a2=0x24la4a
> register
d0=00000001 d1=00000002 d2=000003ED d3=00000000 d4=00000000
d5=00000000 d6=00000000 d7=00000005 a0=00C2C102 a1=000223B0
a2=00241A4A a3=00C2C106
a4=00C2BF08 a5=00000000 a6=00C0B9C8
68 Chapter 3
sp=000229A8 pc=00C32E82 ccr=00000000 na pl nz nv nc
sort:\smain.c\main 110
You also can set a register by using a program variable or other
expression:
> display i
33 (0x21)
> register d3=i
> register
dO=00000001 d1=00000002 d2=000003ED d3=00000021 d4=00000000
dS=00000000 d6=00000000 d7=00000005 a0=00C2C102 a1=000223B0
a2=00241A4A a3=00C2C106 a4=00C2BF08 a5=00000000 a6=00COB9C8
sp=000229A8 pc=00C32E82 ccr=00000000 na pl nz nv nc
sort:\smain.c\main 110
To set floating-point registers, refer to the fregister command in
Chapter 9.
The whatis The whatis command is used to determine the type of an object or
Command the configuration of a type of object. It has two forms:
wha[tis] expression
wha[tis] (type)
The expression and type parameters can be any expression or data
types, including structures and unions, provided by the C language.
Sample Program 2 defines the following objects:
struct X {
int a;
int b[3];
int c;
} x;
typedef struct X *XPTR;
The whatis command yields the following:
> whatis x
auto at 00221FBC (20 bytes)
struct X x;
69 Debugging Your Program
> whatis x.a
object at 00221FBC (4 bytes)
int a;
> whatis x.b101
object at 00221FC0 (4 bytes)
int
> whatis (XPTR)
typedef struct X {
int a;
int b[3];
int c;
} *XPTR;
> whatis (int)
int
> whatis (struct X)
struct X {
int a;
int b[3];
int c;
};
Notice that the typedefs are expanded in terms of the more
fundamental types.
Watches and Watch Breaks
The watch commands allow you to set, list, disable, enable, and clear
watches and watch breaks. A watch (also called a watch point) allows
you to monitor a variable, an address, or a range of memory in order
to see when the value of the variable changes or the area of memory is
altered. A watch break is similar to a watch but acts as a breakpoint if
the variable or area of memory changes.
Like breakpoints, watches and watch breaks remain in memory until
you clear them or exit the debugger. You may restart the program
being debugged and still retain these watch settings. This allows you to
run through the program again and again without resetting the
watches and watch breaks.
Watches and watch breaks are displayed in the Watch window. This
window is updated when the debugger returns control to the user (as
at a breakpoint), at which point the new values of the watched areas
are displayed. You can open the Watch window with the F1 function
key.
You also can display the values of the watched areas by using the
wlist command. For example, if a watch break is set on the variable
tmp in the
function swap in Sample Program 1, then execution will
70 Chapter 3
stop at line 6 of swap when the value of tmp changes. At this point,
entering a wlist command will display the value of the watch as
shown here:
sort:\swap.c\swap 6
> wlist
1! <static register> tmp : 0 (0x0)
The 1! refers to the numbered entry in the watch list.
Watches provide a convenient way to watch memory on a continuing
basis. It is often easier to examine the Watch window instead of
entering a display or dump command after every step or breakpoint.
You can also use the Memory window to keep track of an area of
memory.
Watch breaks can help you locate problem areas with precision.
Often a variable or block of memory may be altered or corrupted at an
unknown point in a program's execution. It can be very difficult to
pinpoint the exact location where the corruption took place. By setting
a watch break on the variable and executing the program, the problem
can be isolated quickly.
The watch and wbreak Commands
The watch command is used to set watches, while the wbreak
command is used to set watch breaks. The syntax of these commands
is as follows:
w[atch] variable | address | range [s[tatic] | d[ynamic]]
wb[reak] variable | address | range [ s[tatic] | d[ynamic]]
The variable, address, or range parameter specifies the location of the
watch or watch break. The optional static or dynamic flag
specifies the way in which the debugger evaluates the location of the
object being watched. (See Chapter 9 for more information.)
By default, watches are dynamic. This means that an expression
being watched is re-evaluated whenever control is returned to the
debugger. The static flag causes the address of a watched
expression to be evaluated once when the watch is set.
Conversely, watch breaks are static by default. The dynamic flag is
used to specify that the address of a watch break should be re-
evaluated every time control is returned to the debugger.
With the watch command, the new value of the watched object is
displayed in the
Watch window whenever control is returned to you
Debugging Your Program 71
(for example, at a breakpoint). If the Watch window is not open, you
can use the wl i st command as a way of determining the new value.
Watches (and watch breaks) can be set on structures or arrays by
name. When this is done, the specification of the aggregate name is
treated as an implicit range and a watch is set on that range. Assume
the following declarations are in effect:
struct x
{
int i;
char a[20] ;
double d;
} x;
char string[80] ;
A watch can be set on ranges as follows:
> watch x
> watch string[5] L 10
> watch &string[17].. &string[19]
Watches and watch breaks can be set on formal or automatic
variables. In this case the watch is in effect only as long as the
function-defining variable is executing. If you set a watch on a formal
or automatic variable, the watch list displays the watch as not active
when execution is taking place outside its defining function. When the
function is re-entered, the watch is re-activated.
You should, however, use caution when using variables to specify a
range. For example, suppose that aut is an automatic variable and
sta is a static variable. Issuing the following command sets a watch
on the memory between the address of aut and the address of sta as
follows:
> watch &aut &sta
Of course, the address of aut could change a number of times as its
function is entered, executed, and exited. In the case of such artificial
ranges the debugger translates the symbolic names into their current
absolute address equivalents and sets the watch on the absolute
address range. It is this absolute address range that is displayed in the
watch list. In general, this sort of translation from symbolic range to
absolute range takes place when the two variables you use
to specify
72 Chapter 3
the range do not resolve to addresses within the same aggregate
(structure, union, or array).
While watch breaks can be useful in monitoring program execution,
they are expensive in terms of execution time. You should expect your
program to execute hundreds of times more slowly when watch breaks
are enabled. This is not true of watches since the information for these
is updated only when control is returned to you by the debugger.
Watch breaks should be disabled whenever possible to speed
execution. One way you can do this is to enable and disable a watch
break dynamically depending on program conditions as shown here:
> wbreak i
> wdisable 1
> break sort 9 {we 1; go sort 20; wd 1; go}
This command sequence installs a watch break whose number in the
example is assumed to be 1 and then it sets a breakpoint that
automatically enables the watch break, executes up to a certain point,
disables the watch break, and continues execution. In this way, you
can force the watch break to be active only when a certain portion of
your program is
executing.
73
4 Setting Up the Debugging
Environment
73 Introduction
74 The debug= Options
76 Which Debugging Option To Use
77 Determining Source File Location
78 Choosing Command-line Options
81 CodeProbe Initialization
82 Setting and Showing Options within CodeProbe
83 Source Mode
84 Echo Mode
84 Instruction Bytes
85 Ignore Path
85 Case Sensitivity
85 Context
86 List Default
86 Unassemble Default
86 Radix Default
86 String Length
86 Array Dimension
87 Range Length
87 Maximum Bad Chars
87 Search Path:
88 Autoswap Mode
88 Catch New Devices
88 Step Into ResLib
89 Current Task
89 Catch New Tasks
89 Customizing Dialog Window Commands
89 The Alias Command
92 The Unalias Command
92 The Define Command
94 The Undefine Command
Introduction
To use CodeProbe efficiently, you need to know how to set up the
optimal debugging
environment for your particular application. This
74 Chapter 4
involves choosing the best debugging option to use, determining where
to locate source files, and selecting necessary command-line options.
This chapter discusses these and other topics pertinent to customizing
your debugging environment.
This section also describes the command used to invoke CodeProbe,
cpr. Selecting the correct options for CodeProbe can determine
whether a debugging session will be productive and useful.
The debug= Options
The degree to which CodeProbe can access symbols defined in a
module is determined by the compiler debugging option used in
compiling that module.
The debug= option can be used with any of the following keywords
to activate the debugging mode of the SAS/C Compiler:
line or l
generates the line number/offset table only.
symbol or s
in addition to the line number/offset table, generates full debugging
information for those symbols referenced in the module.
symbolflush or sf
in addition to the line number/offset table, generates full debugging
information for those symbols referenced in the module. Also forces
the code generator to flush all registers to variable locations at line
boundaries.
full or f
in addition to the line number/offset table, generates full debugging
information for all symbols declared in the module even if there is
no reference to them in the generated code.
fullflush or ff
in addition to the line number/offset table, generates full debugging
information for all symbols declared in the program even if there is
no reference to them in the generated code. Also causes the code
generator to flush all registers at line boundaries.
Each of the debug= options is described in more detail later in this
section.
You can mix modules compiled with different levels of debugging in
the same program.
The nodebug option can be used to suppress the generation of
debugging information. nodebug is the default.
The addsym option can be used to tell the linker to add symbol
information to files that are compiled without debugging information.
If a file was compiled with debugging information, addsym is not
required.
75 Setting Up the Debugging Environment
The debug=line Option
Specifying the debug=line option causes the compiler to output the
line number/offset table only. As a result of using the line option,
the debugger can match the lines in a source file with the loaded code.
This allows you to set breakpoints at source lines and step through the
source code. In addition, some limited symbolic information is
available for external variables and functions. Only the address of a
symbol is available. There is no information about the symbol's
attributes. For this reason, the debugger will attempt to display any
variable as a long by default with the following warning message:
> display fahr
accessing extern with unknown attributes - assuming long
1101004800 (0x41A00000)
To display a variable in its proper form, use a type cast with the
display command as follows or use one of the dump commands.
> display (float) fahr
20
See Chapter 9, "Commands and Built-in Functions," for details on the
display and dump commands.
While the line option provides limited information to the debugger,
it is useful with large programs or when disk space is limited because
it produces much smaller object files. The line option also provides
all the information needed by the disassembler, omd.
The debug=symbol Option
Specifying debug=symbol causes the compiler to output full
debugging information for all global and local variables, all functions,
and all types referenced in the module, including s tructure,
union, enum, and typedef types. If a module is compiled with this
option, you can set breakpoints at source lines, display or alter data
symbolically, set watches on variables or areas of memory, and list
source code. The display command will properly format all data
declared in the module.
Debug information for a structure or union definition is generated
only if it is used in a typedef declaration or as either a global or
local variable. That is, if the structure or union is defined in a header
file that is included by your program, but the tag associated with that
structure or union is not used by your program, then no debug
information will be generated for that tag. Most source
modules use
76 Chapter 4
numerous include files that contain definitions that are never actually
used. By limiting debug information to include only referenced
definitions, the output module size is greatly reduced.
The compiler will often manipulate a variable's contents in registers
over several lines of code without replacing the results in the variable.
If a breakpoint is reached in this section of code, the debugger will
display the value in memory, not in the register. If you suspect that
the debugger is not displaying the proper values, the code can be
inspected in mixed mode, or the file can be recompiled with the
symbolflush option. Note that register variables (automatic and
formal variables that are only assigned to registers) will always be
found in their proper register.
The debug=symbolflush Option
Specifyillg debug=symbolflush causes the compiler to output full
debugging information for all global and local variables, all functions,
and all types referenced in the module, including structure,
union, enum, and typedef types. It does not generate debugging
information for types that are defined but not referenced in the
module.
The symbolflush option also causes the code generator to Tflush
all registers to variable locations at C source line boundaries. This can
be useful because the debugger takes the value of a variable from its
memory location, not a temporary register. While this option is
recommellded for use with the debugger, it causes inefficient code
generation. Any module compiled with this option should be
recompiled before it is placed into production.
The debug=full Option
The debug=full option is similar to the debug=symbol option
except that inforrnation for all declarations and definitions is generated
including those that are defined but not referenced in a module.
The debug=fullflush Option
The debug=fullflush option is similar to the symbolflush
option except that information for all declarations and definitions is
generated including those that are defined but not referenced in a
module.
Which Debugger Option to Use
In order to make full use of the debugger's features, you should always
use either the symbol, symbolflush, full, or fullflush option.
If the cornpiler keeps the value of a variable in a register, as it may in
order to eliminate unnecessary loading and storing of
values in its
77 Setting Up the Debugging Environment
registers, then the true value of a variable at any given time may be in
a register rather than in the variable's memory location. As a
consequence, the value of the variable displayed by the debugger may
not be its correct value. The s ymbolflush and fullflush options
force the correct values of variables to be in the memory locations of
the variables at line boundaries but at the cost of generating extra code
required to store, and perhaps reload, the values.
Only the symbolflush and fullflush options affect the quality
of code generated by the compiler. The other options do not affect code
generation and differ only in the amount of symbolic information they
pass on to the linker. If you want to debug exactly the program you
intend to use, you should use symbol or full rather than
symbolflush or fullflush, and you should debug in mixed mode
so that you can see the machine instructions corresponding to your C
source lines. The opt source mixed command is used to specify
mixed mode. When you do this, you will be able to tell if the value of
a variable is being kept in a register rather than being flushed to
memory, and you can then use the register command rather than
the display or dump commands to determine the variable's value.
See Chapter 9 for more details about these commands. To produce the
final version of your program, use the stripdebug option of slink.
For example, the following command will strip debugging information
from an existing executable file, source-filename, and place it in a
second file, destination-filename:
slink from source-filename to destination-filename stripdebug
If you are not concerned with debugging production quality code,
you should use the symbolflush option, since the difference in
generated code will have little effect. Even if you are attempting to
create a piece of production software, you should begin your debugging
by using the symbolflush option and then recompile with the
symbol option when most of your bugs have been detected and
repaired.
Determining Source File Location
If you have compiled your program with any of the debug= options,
CodeProbe reads the name of the source file from the program being
debugged. By default, this is the same name you passed to the compiler
with the sc command. If you specify a full or partial pathname for
your source file, the pathname is included. You can change the
filename specification in the program's debugging
information by using
78 Chapter 4
the sourceis option when you compile your program. Refer to
Chapter 8, "Compiling and Linking Your Program," in SAS/C
Development System User's Guide, Volume I for more details. You may
want to direct CodeProbe to look for source files on a different disk or
at a different location on the same disk by using the opt search
command described later in this section.
If CodeProbe cannot find the source file for the function it is
currently executing, it displays the following message:
Error: error opening source file filename
Your source code will be displayed as long as you have used some
debugging option, other than the nodebug option, with the compiler.
The CodeProbe source command can be used to override the
filename specified in the debugging information. This new association
is remembered by CodeProbe throughout the current session. This
command can prove useful when the name of the source file has been
changed since the program was compiled.
Choosing Command-line Options
The CodeProbe environment can be customized by including command-
line options when invoking the debugger. The format of the command
is as follows:
cpr [cpr-options] application-name [application-arguments]
For information on how to use command-line options with the
program you are debugging, see Chapter 1, "Introduction to
CodeProbe." If you invoke CodeProbe from the Workbench screen, you
can use command-line options by adding them as tool types to the
debug icon created by scsetup. To add tool types, click on the icon,
then select Info from the Workbench menu under AmigaDOS
Version 1.3, or Information from the Icons menu under AmigaDOS
Version 2.0.
You can use the following command-line options when invoking
CodeProbe:
-buffer
specifies the size of the Dialog window buffer. By default the Dialog
window saves
the last 4096 bytes displayed so that you can scroll
79 Setting Up the Debugging Environment
backwards and review output. This size can be increased or
decreased with this option. The syntax of the option is as follows:
cpr -b[uffer] size
The size parameter specifies the size of the buffer in bytes.
-cli
instructs CodeProbe to invoke the application as a CLI (Shell)
process. CodeProbe passes arguments to the application through the
normal command line interface. This option is the default if
CodeProbe is invoked from a Shell. The option is necessary if
CodeProbe is invoked from the Workbench screen, and you want
your program to run as if invoked from a Shell.
-command
executes debugger commands at startup. The commands are
executed after go main if the -startup option is not specified or
after the profile script if it is specified. Profile scripts are discussed
later in this section.
For example, the commands
cpr -command "proceed; display fahr" program-name
would execute to main, step over 1 line of code, and display the
variable fahr in the Dialog window before giving control to you.
-i
sets up a screen in interlace mode. By default, CodeProbe opens a
new screen using the specifications set up by Preferences for
Workbench screens. To force a screen to be opened in interlace
mode, include the -i option before typing the application command
name.
-line
starts CodeProbe in line mode. Line mode causes the debugger to
run in the current Shell window. The equivalent of the Dialog
window is provided, with no other windows available. Line mode is
probably only useful for running from a script file, redirecting
output using the Shell redirection facility, or running from a remote
terminal over a communications port.
-noprofile
suppresses execution of the CodeProbe startup file. When
CodeProbe is invoked, it automatically executes a script file named
cprinit, which
must be located in either the current directory or
80 Chapter 4
ENV:sc. If the startup file is found in the current directory,
ENV:sc iS not searched.
-screen
instructs CodeProbe to open its windows on the named public
screen. The syntax of the command is as follows:
-sc[reen] name
By default, CodeProbe creates a new public screen when it is
invoked. If this option is specified, CodeProbe looks for an existing
public screen with the given name, and if one is found it uses that
screen to display its windows. If a screen with the given name does
not exist, a new one is created with that name. To use the
Workbench screen, specify -screen workbench. Public screens
are a feature of Intuition 2.0. For users of earlier versions of
Intuition, this option is not generally useful. However, specifying
-screen workbench causes CodeProbe to use the Workbench
screen on older releases.
-startup
suppresses the automatic go main that is normally executed by the
debugger on startup. This option is useful if your application
redefines _main or c.a so that no main function exists, or if you
want to step through such code. If this option is used, no
initialization of any kind will have been performed by the
application process before control is given to you.
If the quit, start, or restart commands are invoked and an
application process has not exited, the debugger normally calls
exit to clean up any process resources that may not have been
freed. However, if the -startup option was used, exit will not
be called.
-w
runs CodeProbe on the Workbench screen. This is the same as
specifying -screen workbench.
-wb
instructs CodeProbe to invoke the application as a Workbench
process. It passes arguments to the application through a
Workbench startup message. This option is the default if CodeProbe
is invoked from a Workbench icon. The option is necessary if
CodeProbe is invoked from a Shell, but you want the application to
run as if
invoked from the Workbench screen.
81 Setting Up the Debugging Environment
-wdialog, -wregister, -wsource, -wwatch
specifies start up window coordinates for the Dialog, Register,
Source, and Watch windows, respectively. Window coordinates are
measured in character positions. A width or height of 0 causes the
window to extend to the screen border on the right or bottom,
respectively. The option names can be abbreviated to two letters:
-wd[ialog] left top width height
-wr[egister] left top width height
-ws[ource] left top width height
-ww[atch] left top width height
Here is an example:
cpr -ws 0 1 50 12 -wd 0 13 50 0 ftoc
Note that the Register and Watch windows will not be displayed
on startup; however, when they are opened by pressing the
appropriate function key (either Fl or F4), they will open to the
coordinates specified on the command line.
-.
suppresses the copyright banner that is displayed at startup.
CodeProbe Initialization
Since you will probably want CodeProbe to start the debugger with the
same options most of the time, CodeProbe allows you to create a
debugger command script file that is executed each time the debugger
is invoked. The profile script, named cprinit, is executed after the
initial go main but before any commands specified with the
-command option are executed. CodeProbe first looks for cprinit in
the current directory and then in the ENV: SC directory. Only one
cprinit script will be run; therefore, if a script is located in both
directories, the one in the current directory is used.
The following are examples of scripts displayed from the Shell
window using the AmigaDOS type command:
1> type cprinit
/* This is the
debugger startup profile */
82 Chapter 4
opt search dh0:mysource, df0:mysource, ram:
opt radix h
opt ibytes off
1> type env:sc/cprinit
/* This is a debugger profile script for a project */
opt source mixed
proceed
display argc, argv
Note that C style comments can be placed in profile scripts as long
as they exist on a single line.
Setting and Showing Options within CodeProbe
In addition to the command-line options discussed above, a number of
options can be set from within CodeProbe to customize the way
information is displayed or handled. Most of these options are modified
with the opt command or through the Options menu. To see the
default options while in the debugger, activate the Options menu or
execute the opt command without any parameters as follows:
> opt
Source mode.........c
Echo mode...........Off
Instruction bytes...Off
Ignore path.........Off
Case sensitivity....Off
Context.............2 lines
List default........6 lines
Unassemble default..4 lines
Radix default.......Decimal
String Length.......128
Array Dimension.....20
Range Length........64
Maximum Bad Chars...3
Search path:
Autoswap mode.......Off
Catch New Devices...No
Step into ResLib....No
Current Task........sort at 0001DC20
Catch New
Tasks.....No
83 Setting Up the Debugging Environment
A CPR initialization script can be used to change options automatically
when you invoke the debugger. See "CodeProbe Initialization" earlier
in this chapter for more information.
Source Mode
There are three source modes: C, assembly, and mixed. The current
source mode can be determined by means of the opt command or by
activating the Options menu. It can be changed by means of the opt
source command or the Source selection in the Options menu. C
source mode is the default.
The syntax of the opt source command is as follows:
op[t] so[urce] c | a[sm] | m[ixed] | n[ext]
Repeatedly choosing opt source next cycles through the three
possible source modes.
C Mode
In C mode, CodeProbe displays C source lines when the trace or
proceed commands are executed or when a breakpoint is triggered.
To change the current source mode to C mode, enter the following
command:
> opt source c
While in C source mode, you cannot single step by assembly
instruction.
Assembly Mode
In assembly mode, disassembled code is displayed in the Source
window. Single trace or proceed commands will step by assembly
instruction.
To change the current source mode to assembly mode, use the
following command:
> opt source asm
Mixed Mode
In mixed mode, both assembly instructions and C source lines, if
available, are displayed in the Source window. For each C source line
displayed, the corresponding assembly instructions are displayed as
well.
84 Chapter 4
To change the current source mode to mixed mode, enter the
following command:
> opt source mixed
In mixed mode, you can take advantage of the two different forms of
the trace and proceed commands in order to step by either C
source line or assembly instruction.
Echo Mode
When echo mode is on, commands are echoed in the Dialog window
before being executed. This option is useful if you want to execute
debugger command files and see the command lines as they are
executed along with their output. Commands that are invoked by menu
selections or double-clicking the mouse are also displayed as they are
executed. By default, this option is set to of f . It is not needed while
entering commands in the Dialog window because command lines are
displayed as they are entered anyway. The syntax is as follows:
op[t] e[cho] [on | off]
Instruction Bytes
The ibytes option affects the display format of disassembled code in
the Source window and the output of the unassemble command. If
the option is set to on, the second field of the disassembly contains a
hex dump of the instruction. The following fields contain the op-code
and its operands. If the option is set to off, the hexadecimal dump is
suppressed. The syntax is as follows:
op[t] ib[ytes] [on | off]
Here is an example:
> opt ibytes on
> unassemble 7
main:
7{
0025F950 48E70130 MOVEM.L D7/A2-A3,-(A7)
0025F954 BFEC0004C MPA.L 0004(A4),A7
0025F958 65001BD6 BCS 00261530
> opt ib off
> unassemble
7
85 Setting Up the Debugging Environment
main:
7 {
0025F950 MOVEM.L D7/A2-A3,-(A7)
0025F954 CMPA.L 0004(A4),A7
0025F958 BCS 00261530
Ignore Path
If the ignorepath option is set to on, CodeProbe ignores the
directory part of the source filename. In this case, CodeProbe looks in
the current directory for the source file. By default, ignorepath is
set to of f and CodeProbe uses the entire pathname when searching
for the source file. The syntax is as follows:
op[t] ig[norepath][ on | off ]
This option is useful in conjunction with the opt search command
to override the source filename specified in the object file. For more
information, see the SOURCEIS option in Chapter 8, "Compiling and
Linking Your Program," of the SAS/C Development System User's
Guide, Volume I: Introduction, Compiler, Editor.
Case Sensitivity
The case option controls case sensitivity for the search command.
The search command is used to search for a string in the Source
window. When case is set to on, a case-sensitive search is made
whenever a search command is executed. The syntax for the case
option is as follows:
op[t] cas[e][ on | off ]
Context
As you proceed through an application program by tracing and
breakpointing, CodeProbe always keeps the current source line or
assembler instruction displayed in the Source window. CodeProbe
attempts to keep at least a minimum number of context lines of code
displayed above and below the current line. The number of these
context lines can be controlled by the context option. Note that, in
mixed mode, it is not always possible to keep the right number of lines
above or below, but the source code line will always be displayed and
the assembler instruction will be displayed if possible. The default
number of context lines is 2. The maximum number of context lines
possible is limited by the number of lines in the Source window. The
syntax is as follows:
op[t] co[ntext]
integer
86 Chapter 4
List Default
The list option determines the number of source lines displayed by
the list command. The list command is discussed in Chapter 9.
The default value for this option is 6. The syntax is as follows:
op[t] l[ist] integer
Unassemble Default
The unassemble option determines the number of instructions
displayed by the unassemble command. The default value for this
option is 4. The syntax is as follows:
op[t] U[nassemble] integer
Note that the default value is only used when no source file is
available. When a source file is available for a section of code,
unassemble displays the disassembly for a single source line by
default.
Radix Default
The radix option controls the default input type for constants. The
choices are decimal and hexadecimal. The default is decimal. When set
to hex, this option can be used to avoid having to type the initial 0x
on hexadecimal constants. The syntax is as follows:
op[t] rad[ix] [d[ecimal] | h[ex]]
String Length
The strlen option controls the maximum number of bytes that are
displayed when a character string is displayed with the di spl ay or
dzero commands. If the string contains bad characters, fewer may be
displayed. The default is 128. The syntax of the strlen option is as
follows:
op[t] st[rlen] integer
The integer parameter specifies the number of bytes.
Array Dimension
The arrdim option specifies the maximum number of array elements
that will be displayed by the display command. The syntax for the
arrdim option is as follows:
op[t] ar[rdim] integer
The integer parameter specifies the maximum number of array
elements. The default value is 20. Arrays with integer or
fewer
87 Setting Up the Debugging Environment
elements are displayed in their entirety. Larger arrays will have their
first integer elements displayed followed by an ellipsis (. . .).
Range Length
The rangelen option controls the default size of memory dumps
when no other source of information is available, for example, when
dumping an absolute addresss. The rangelen option is used when
commands such as display, dump, or watch have only an address
parameter. The rangelen option specifies the number of elements
after the address to display, dump, or watch. The syntax for the
rangelen option is as follows:
op[t] ran[gelen] integer
The integer parameter specifies default range size in number of
elements of a type to be displayed. The default value is 64.
Maximum Bad Chars
The badchar option determines how many nonprintable characters
must be encountered before the dzero or display command stops
printing a string. The syntax of the badchar command is as follows:
op[t] b[adchar] integer
The integer parameter specifies the number of nonprintable characters
allowed. The default value is 3. A 0 indicates no limit.
Search Path:
The search path is used to find the source modules used when
compiling the application. When a module is compiled with one of the
debug options, the full pathname of the source module is saved in the
debug information. CodeProbe always looks for the source module in
its original location first, then it looks in the current directory, and
finally, it walks through each of the directories specified in its search
path in order. If you have moved the source module to some other
location, use the opt search command to add the new location to
your search path.
The opt search command takes four forms:
Op[t] se[arch]
op[t] se[arch] dir[, dir[...]]
op[t] se[arch] + dir[, dir[...]]
op[t] se[arch] - dir[, dir[...]]
88 Chapter 4
The first form lists the current paths in the search path list, which is
empty by default. The second form sets the search path to the list of
directories on the command line. The third form appends the list of
directories on the command line to the current search path. The last
form deletes the list of directories from the current search path. This
list is empty by default. Here are some examples:
> opt search c:, df0:, dh0:mysource
> opt search + df1:test
> opt search - df0:, c:
The search option cannot be set from the Options menu.
Autoswap Mode
When in autoswap mode, the screen containing the application's output
is pushed to the front each time CodeProbe gives control to the
application. When a breakpoint is reached, the debugger screen is
again pushed to the front. If you are single stepping through source
code, the switching of screens will probably appear as a brief flash. If
the autoswap mode is set to of f, which is the default, the application
screen will not be pushed to the front. The autoswap feature can be set
to on or of f with the opt command. The syntax is as follows:
op[t] au[toswap] [ on | off ]
Autoswap mode is particularly useful when debugging programs that
require input from the keyboard. The application's screen is displayed
whenever input is required.
Catch New Devices
When a device is opened for the first time a new task may be created.
If the process that opened the device is under debugger control, then
CodeProbe will catch the new task provided the Catch New Devices
option is set to on. The default setting for this option is off . The
syntax for the devices option is as follows:
op[t] d[evices] [ on | off ]
Step Into ResLib
The Step Into ResLib option allows the user to decide whether to allow
CodeProbe to step into resident libraries while tracing or runrling an
application with watch breaks. This option should remain set to of f
(default) unless you want to debug your own resident libraries. Tracing
into systern libraries such as Exec or Intuition can lead to
problerns. If this option remains off, it is safe to run with watch breaks
on while stepping over system resident libraries.
However, you should
89 Setting Up the Debugging Environment
disable all watch breaks before stepping into a ROM-resident library
routine. The syntax for the reslib option is as follows:
op[t] res[lib] on | off
Current Task
The current task is displayed by entering the opt command with no
parameters. This information cannot be displayed through the Options
menu. The following line indicates that a program named sort is the
current task and that execution has stopped at address 0001DC20.
Current Task........sort at 0001DC20
The current task cannot be changed with the opt command; however,
you can use the jump command to change the execution point.
Catch New Tasks
Whenever a new task is started by a task under CodeProbe's control,
the new task is also under CodeProbe's control by default. This does
not apply to tasks started by a call to the OpenDevice function. The
catch option enables you to turn task catching on or off. The
syntax of the catch command is as follows:
cp[t] ca[tch] [ on | off ]
Customizing Dialog Window Commands
In order to provide CodeProbe with a more versatile command
interface, the alias and def ine commands can be used to customize
the Dialog window commands. Aliases enable you to redefine or
customize commands. This capability is similar to the aliasing
capabilities found in the Shell. Defines provide CodeProbe with a
macro facility modeled after the C language's preprocessor #def ine
facility.
The Alias Command
The alias command is used to create new aliases, display the
definition of an existing alias, or display a list of all currently existing
aliases. The syntax for the alias command is as follows:
a[lias] [name[definition]]
When entered with no parameters, the alias command displays
the list of all
currently defined aliases, with the alias listed on the left
90 Chapter 4
and the associated command on the right. The following example
shows the list of aliases already defined for you by CodeProbe:
> alias
da dump $* $ ascii1
db dump $* $ hex1 text
dc dump $* $ dec1
dd dump $* $ float8
df dump $* $ float4
dffp dump $* $ ffp4
di dump $* $ dec4
dl dump $* $ dec4
dp dump $* $ hex4
ds dump $* $ dec2
dw dump $* $ hex2
The definition for an existing alias is displayed if the alias
command is entered with only the name argument. The following
alias command causes the definition for the dffp alias to be
displayed:
> alias dffp
dffp dump $* $ ffp4
Alias names are only expanded when they occur at the beginning of
a command line. An alias definition can be a simple textual substitution
or it can contain positional parameters to be expanded at execution
time.
Positional parameters are specified as $1, $2, $3, and so on. $0
represents the alias itself. $* represents all command-line parameters.
If no positional parameter is specified in a definition, all parameters
are placed after the expanded definition until it encounters a semicolon
(;) or an end of line. To define an alias that expands into more than
one command, enclose the definition in either double quotes ("") or
curly braces ({ }). If the command string must contain double quotes,
curly braces must be used or the quotes must be escaped. A backslash
(\) can be used
to continue the line.
91 Setting Up the Debugging Environment
The following are examples of the alias command:
> alias print display
> alias dw
dw dump $* S hex2
> alias look2 "g $1; where; g S2; where"
> alias printgo {print "vars: ", S*; gO}
After entering these alias commands you could enter the following
command lines:
> look2 sort swap
sort:\sort.c\sort 20
1* In routine sort:\sort.c\sort 20
2 Called from sort:\smain.c\main 13 (+0xC)
3 Called from 0xC3162E
sort:\swap.c\swap 5
1* in routine sort:\swap.c\swap 5
2 Called from sort:\sort.c\sort 26 (+0x12)
3 Called from sort:\smain.c\main 13 (+0xC)
4 Called from 0xC3162E
> print tmp
10 (0xA)
> dw x
0036c4a4: 0000 0001
> go sort
> printgo i, p[i]
vars: 0 (0x0) 0 (0x0)
Program exited with code 0.
The alias definitions in the previous example expand to the following
commands:
display tmp
dump *y hex 2
g sort; where; g swap; where
display "vars: ", i, p[i]; go
If at least one parameter is specified in a definition, all unused
parameters are thrown away in the expansion. Any unspecified
parameter results in an empty expansion. For example, assume
the
92 Chapter 4
alias given previously for look2. You can enter the following
command lines:
> look2 func1 func2 func3
> look2 func1
These command lines are expanded as follows:
g func1; where; g func2; where
g func1; where; g ; where
Aliases can be nested in the definitions of other aliases. If the
debugger detects a circular reference between aliases, it will expand
until it detects the cycle. If an alias references itself, the reference will
not be expanded. For example, alias where where args does
not cause an infinite loop.
Aliases can be used to redefine any native CodeProbe command
except alias and unalias . To reference a command that has been
aliased, escape the command name with a back-tick character ( ` ). For
example, the following sequence defines aliases for the set and
enter commands so they function as they did in CodeProbe
Version 5.10:
> alias set opt
> alias enter `et
Note the back-tick character used to escape the set command.
The Unalias Command
The unalias command removes entries from CodeProbe's list of
aliases. The syntax for the unalias command is as follows:
unal[ias] name
unal[ias]*
The name parameter should match the alias name to be removed. The
asterisk (*) is used to remove all aliases.
The Define Command
The define command provides a more general macro text
substitution facility than the alias command. Just as with the C
preprocessor's definitions, macros defined in CodeProbe are expanded
anywhere within a line of text unless hidden inside of double quotes.
CodeProbe will not expand macro definitions that have
been escaped
93 Setting Up the Debugging Environment
by a back-tick character. The syntax for the def ine command is as
follows:
[#]def[ine] name [ definition ]
[#]def[ine] name ( parm [, parm . . . ] ) [definition]
The name parameter specifies the text to be replaced, and the definition
parameter is the substitution text. In the second form, parameters are
specified exactly as in the C language. Using the de f i ne command
with no arguments displays all macro definitions currently recognized.
Some examples are as follows:
> define PI 3.14159
> display PI
3.14159
> define ISEQUAL(a,b) (a == b)
> display ISEQUAL(1,5)
0 (0x0)
> expand ISEQUAL(1,5)
(1 == 5)
To define a symbol to nothing, omit the def inition parameter as
shown in the following command:
> define FOO
One difference between the C preprocessor #define capability and
CodeProbe's is that the debugger treats def ine as a command
statement, meaning that it will stop parsing the def ine when a
semicolon is reached. To have CodeProbe treat a semicolon as part of a
definition, precede it with an escape character as follows:
\;
The define command is intended to be used to define expressions.
Although you can use the def ine command to create new commands,
you should use the alias command to create custom
commands.
94 Chapter 4
The Undefine Command
The undef ine command removes a definition from CodeProbe's
definition list. Compiler generated symbols may not be undefined. The
syntax for the undef ine command is as follows:
und[efine] name
und[efine] *
The first form removes the macro with the specified name from the
definition list.
The second form removes all definitions from the list.
95
5 Working in Cross-
Development Mode
95 Introductlon
95 Why Debug in Cross-Development Mode?
96 Using the Cross Debugger
96 Preparing to Use the Cross Debugger
96 Running the Cross Debugger
Introduction
Version 6.0 of the SAS/C Development System comes with a new
debugging capability: cross-debugging. This means that you can have
your program run on one Amiga system, and debug it from another
Amiga system. This is extremely useful when debugging a program that
shuts down WorkBench, partially takes over the machine, or makes
heavy use of graphics.
When running in cross-development mode, CodeProbe communicates
with a small kernel that controls the application via a serial
communications port or over a network.
Why Debug in Cross-Development Mode?
There are several reasons why you may want to debug in cross-
development mode:
It is easier sometimes to see and send input to both the application
and debugger if they have their own separate monitors and
keyboards.
Some applications use low-level graphics control, which takes control
away from Intuition. Since CodeProbe's windowing system is built
on top of Intuition, you cannot communicate with it while such an
application is running.
With very large applications in tight memory situations, there may
not be enough memory available for both CodeProbe and the
application. The CodeProbe cross-debugger kernel that runs on the
machine with the application is small (less than 30K). It allows the
application to use most of the available memory.
Disk space limitations may make it difficult to have the debugger, all
the necessary source files, and a copy of the application
with debug
96 Chapter 5
information available on the same machine along with all the files
needed by the running application.
If the program being debugged crashes, you can continue to work on
the machine with the source code while it is rebooting.
Using the Cross Debugger
In the following discussion, the machine containing the source code
and the cross debugger (CPRX) is referred to as the host machine.
Your actual debugging session occurs on the host machine. The
machine on which the application will run under the kernel's control
is referred to as the target machine.
The cross debugger and kernel communicate with each other over a
serial link or via a named pipe. Using named pipes, you can debug
your program from an Amiga system connected to the target machine
via a network.
Preparing to Use the Cross Debugger
To use the cross debugger, you will need two Amiga machines. You
can use a NULL modem cable to connect the machines, or you can
even debug over the phone, if both Amiga machines are connected to
modems. If you use the serial port, use the serial icon in the
Preferences menu to select the highest baud rate acceptable. With a
NULL modem cable, 19200 works fine. Over the phone you probably
will need to specify the maximum speed accepted by your modems.
Running the Cross Debugger
Two files must be installed on the target machine: the kernel (CPRK),
and the application program that is to be debugged, unless the -x
option is used. CPRX can automatically strip the application program
of debug information and install it on the target machine if the -x
option is used.
CPRK provides direct control of the application program on the
target machine. It communicates with CPRX, which is running on the
host machine, over a serial line or through a pipe across a network.
CPRK displays its copyright information and diagnostic output in a CLI
window. CPRX runs like CodeProbe, except that the program being
debugged runs on another machine.
On the host machine, you need the source to your project and the
executable file for the program you want to debug. The executable file
should have been built with debug information.
Debugging a program in cross development mode is a four-step
process:
1. Start the kernel (CPRK) on the target machine.
2. Start the cross debugger (CPRX) on the host machine.
97 Working in Cross-Development Mode
3. Debug your application program.
4. Enter the f ini sh command in CPRX to terminate CPRK and
CPRX.
Note: When debugging over a serial port, you must start CPRK
before starting CPRX. When using named pipes, the order does not
matter.
Defining the Communications Parameters
CPRX and CPRK take the following command-line options that define
and set parameters for the communications medium:
-pipe [ name ]
specifies that a named pipe is to be used instead of the serial port.
If name is not specified, pipe: cpr is used. CPRX or CPRK will
open two pipes using name as a base, name_ d and name_ k.
To communicate successfully over a network, either CPRX or
CPRK must be invoked with a pipe filename referring to a pipe on
the other machine. If your network allows you to refer to a pipe
device on an attached machine by specifying
net: pipe/<pipename>
you could invoke CPRK on the target machine with the option
-pipe net:pipe/cpr
and invoke CPRX on the host machine with the -pipe option and
no parameters. This method works with the popular freely
redistributable network parnet, written by the Software Distillery.
-device [name]
specifies that the named device should be opened for
communications if -pipe was not specified. The default is
serial.device.
-unit [number]
specifies the unit number of the communications device if -pipe
was not specified. The default is zero (O).
-speed [number]
specifies the baud rate of the communications device if -pipe was
not specified.
The default is the value set in preferences.
98 Chapter 5
searting the Kernel (CPRK)
Start the kernel on the target machine with the following Shell
command:
cprk [options]
The only options CPRK accepts are the communications configuration
options previously listed. CPRK cannot be invoked from the
Workbench screen.
Once invoked, CPRK acts as a server, waiting for a request to start a
debugging session from a CPRX invocation on another machine. Note
that if you are using the serial device, CPRK must be invoked before
CPRX is invoked on the host machine.
Starting the Cross Debugger (CPRX)
Start the cross debugger on the host machine with the following Shell
command:
cprx [options]target-executable-filename [program-options]
CPRX cannot be invoked from the Workbench screen.
The target-executable-filename parameter is the name of the program
to be debugged. By default, CPRX and CPRK look for the program in
the current directory of both the host and the target machines. If the
specified executable name is an absolute path, CPRX and CPRK look in
that location on both machines. If the executable file is located in
different places on the target and host, then use the -symf ile option
on CPRX to specify where the executable file resides on the host
machine. CPRK will still look in the location specified by
target-executable-filename. Anything on the command line after the
target-executable-filename is passed to the target program as command-
line arguments.
CPRX can be invoked with any of the options available to the native
debugger (CPR) or with any of the communications configuration
options previously listed. In addition, CPRX accepts the following
options:
-symfile filename
specifies the location of the executable file on the host machine. Use
this option if the location is not the same on the host and target
machines.
-nok[check]
turns off checksum checking. By default, CPRX and CPRK examine
a checksum on
the executable files on the host and target machines
99 Working in Cross-Development Mode
to verify that both sides are using the same executable file. If the
checksum fails, CPRK does not load the program.
-x
strips all debugging information from the host's version of the
executable file, copies the stripped version to the target machine,
and tells CPRK to invoke the just-transmitted version. This allows
CPRK to run constantly without changing disks or rebooting (as
long as your program does not crash).
Example 1
Suppose you want to start a cross-debugging session to debug a
program named myprog using the serial port at 19200 baud. Assume
that the program to be debugged resides in the current directory on
the host machine, so use -x to copy it over. The following commands
can be entered on the target and host machines:
target machine
cprk -speed 19200
host machine
cprx -x -speed 19200 myprog
Example 2
Suppose you want to start a cross-debugging session to debug a
program named myprog using parnet and named pipes. Assume that
the program to be debugged resides in TEMP: on the target machine
and in work: test on the host machine. The following commands can
be entered on the target and host machines:
target machine
cprk -pipe net:pipe/cpr
host machine
cprx -pipe -symfile work:test/myprog temp:myprog
Debugging Your Application
Once started, the cross debugger behaves just like the normal
debugger, except entering CTRL-C in the CPRX Dialog window does
not always stop the program executing on the target machine. All
interaction with the debugger occurs on the host machine via CPRX;
all interaction with the program being debugged occurs on the target
machine in the normal fashion.
Terminating CPRX and CPRK
If communications have not yet been established, you can terminate
CPRX or CPRK by entering CTRL-C in the Shell window that
you
100 Chapter 5
used to invoke the command. If CPRX does not open its windows after
you invoke it, communications have not been successfully established.
Once the program is loaded, you can choose to terminate debugging
one of two ways:
Terminate both CPRX and CPRK by entering the finish command
in the CPRX Dialog window. The syntax is as follows:
fin[ish]
The program being debugged will automatically be terminated if it
has not yet completed.
Terminate only CPRX by using the normal CPR quit command.
CPRK will continue running for use with a future CPRX debugging
session. The program being debugged will automatically be
terminated if it has not yet completed.
You should allow your program to run to completion if possible before
entering finish
or quit to ensure that it cleans up all resources.
101
6 Using AREXX Macros with
CodeProbe
101 The AREXX Interface
101 Macros Provided by CodeProbe
102 Invoking Macros
103 Values Returned from CodeProbe Commands
103 Return Codes
103 Command Output
The AREXX Interface
AREXX is a multitasking implementation of the REXX language, a
high-level language designed for macro processing and general
programming tasks. CodeProbe supports an AREXX interface for
customization. This interface is provided through CodeProbe's REXX
port, sc_cpr.
Macros Provided by CodeProbe
A number of macros are provided in the sc: rexx directory as
examples. Some simulate commands supported by the Commodore
debugger, wack, including the following:
Macro Description
avail.cpr displays the amount of available memory
dbptr.cpr dumps memory as bytes from a given BPTR
dbstr.cpr dumps memory as bytes for a given BSTR
devices.cpr displays the devices in the system
devs.cpr displays the list of system devices
execbase.cpr dumps exec base information
ints.cpr displays the list of interrupt handlers
(continued)
102 Chapter 6
MacroDescription
libraries.cpr displays the libraries in the system
libs.cpr displays the list of resident libraries
makeaptr.cpr converts a BPTR to an APTR
memory.cpr displays regions of memory
mods.cpr displays system resident modules
ports.cpr displays the list of public ports
regions.cpr displays regions of memory
resource.cpr displays the list of system resources
rsrcs.cpr displays the resources in the system
showcli dumps CLI structure for a given command,
process address, or task
showprocess.cpr takes a process address or name and displays
all of its task and process fields
status.cpr shows all CLI tasks
whichis.cpr identifies the CLI process associated with a
command, task number, or task address
For more details on how to use these macros while debugging,
examine the macros in the text editor. Each macro has comments at
the beginning of the file explaining how to use it.
Invoking Macros
CodeProbe recognizes macros with a.cpr extension. To invoke a
macro from CodeProbe, simply enter the name of the macro from the
command line. (The . cpr extension is optional.) CodeProbe first looks
for the macro in the current directory, then in sc: rexx, and finally
in REXX:.
For example, the following macro, named avail.cpr, uses the
storage function to display the amount of memory available.
/* */
'd "' || storage() 'bytes free"'
exit(0)
103 Using AREXX Macros with CodeProbe
To invoke this macro, enter avail from the command line. The
display command in the avail.cpr macro displays the value
returned by the storage function, 1953944, and the string "bytes
free", as shown here.
> avail
1953944 bytes free
Values Returned from CodeProbe Commands
CodeProbe commands provide return codes that are available to
AREXX macros. Output from the debugger commands also can be
assigned to the AREXX variable results.
Return Codes
CodeProbe commands return status codes to AREXX as follows:
Return
Code Explanation
O The debugger command was successful.
1 The command was syntactically correct, but the program
failed for some other reason.
2 A syntax error occurred.
3 The debugger could not allocate memory for the AREXX
message.
Command Output
In addition to these return codes, an AREXX macro can receive the
Output output of a debugger command as it would normally appear in the
Dialog window by invoking the AREXX command options
results. The output will then be accessible from the variable
result, provided that the debugger returned a 0 return code.
For example, to execute a debugger command from outside the
debugger, you could execute the following REXX script:
/* */
address "SC_CPR" /* only if macro was not invoked from CodeProbe */
options results
'any
CodeProbe Dialog window command'
104 Chapter 6
The output from the CodeProbe command is assigned to the AREXX
variable result.
105
7 Debugging Resident
Libraries
105 Introduction
105 Setting Breakpoints
106 The symload Command
106 The libraries.cpr AREXX Macro
106 Cautions
106 Limitations
106 Example
Introduction
Debugging resident libraries has been simplified considerably with
Version 6.0 of CodeProbe. When debugging a resident library you can
set breakpoints in the library
use the symload command to read symbol information from the
library
use the libraries .cpr AREXX macro to display the libraries in
the system.
Setting Breakpoints
You can set breakpoints in any resident library that your program may
use. For example, the following command sets a breakpoint on the
function myfunc in library mylib. library:
break mylib.library:myfunc
If your program has not yet called OpenLibrary( ) to open
mylib.library, then CodeProbe waits to install the breakpoint until
the library has been opened. When CodeProbe detects that the library
has been opened, it loads the debug information for that library. If
myfunc does not exist, or if debug information for that library cannot
be found, CodeProbe will halt the program at that point. This allows
you to specify a different function or use the symload command to
load debug
information from a different location.
106 Chapter 7
The symload Command
The symload command can be used to load debugging information
for a resident library. For example, the following command loads
debugging information for the library named mylib. library in the
current directory:
symload mylib.library
Refer to Chapter 9, "Commands and Built-in Functions," for a
complete description of the symload command.
The libraries.cpr AREXX Macro
The libraries.cpr AREXX macro can be used to display a list of
the libraries that are currently loaded. To run this macro, enter
libraries on the command line of the Dialog window. Refer to
Chapter 6, "Using AREXX Macros with CodeProbe," for more
information.
Cautions
Since there is only one code segment for a shared library, you must be
careful in setting breakpoints. A breakpoint is just an illegal instruction
that CodeProbe places in the code. When the child process encounters
that instruction, CodeProbe handles the exception. However, if another
process is also using the same library, it will cause a crash when the
program encounters the illegal instruction. Therefore, do not set
breakpoints in libraries that will be used by processes not under
debugger control.
Limitations
When debugging a resident library, you cannot examine global
variables declared in modules outside the library even if you specify
the full pathname of the module.
Example
See the directory sc:examples/reslib for an example resident
library with
debugging instructions.
107
8 Debugging Multitasking
Programs
107 Introduction
108 Types of Tasks
108 How CodeProbe Handles Tasks
109 Commands Used to Control Tasks
109 tasks
110 opt task
111 activate and deactivate
111 detach
112 catch
112 symload
113 Design Considerations for Debugger Compatibility
Introduction
CodeProbe can debug applications that spawn additional tasks. These
applications are designed to take advantage of the Amiga system's
multitasking capabilities. This chapter looks at the commands used to
debug multitasking applications including the following:
tasks
displays all tasks under the debugger's control.
opt task
examines or modifies the state of some task besides the one
currently at a breakpoint.
deactivate
prevents a task from running, even when a go command is
executed from another current task.
activate
reactivates a task affected by the deactivate command.
detach
frees a task from debugger control.
catch
places a task under debugger control.
symload
changes the load module used for collecting debug information
while the
debugger is active.
108 Chapter 8
The discussion concludes by focusing on how to design applications
with debugger compatibility in mind.
CodeProbe is able to debug multitasking applications by intercepting
every call to AddTask( ) and determining the identity of the calling
task. If the calling task is under debugger control and the catch
option is set to on, the new task will also be brought under debugger
control. Any task under CodeProbe's control can be stopped by a set
breakpoint or by single stepping. Also, if you enter Ctrl-C in the
Dialog window while an application is running, all active tasks under
debugger control will be stopped.
Types of Tasks
Two types of tasks can be spawned by an application. The first type,
called a synchronous task, is created, runs to completion, and returns
control to the parent process while the parent process waits. This type
of task is not practical to debug with CodeProbe while running the
parent process. You should debug the task as a separate program
before debugging the parent process.
The second type of task is an asynchronous task. When a parent
process spawns an asynchronous task, control is returned to the parent
process immediately after creation. The two applications then run
independently, but both are under debugger control. This type of task
can be debugged with CodeProbe.
In this chapter, all references are to asynchronous tasks and their
parent processes.
How CodeProbe Handles Tasks
It is important to understand the way tasks are handled when a
breakpoint is hit or when you are stepping through a task. If several
tasks are running under the debugger's control when a breakpoint is
reached, all other tasks on the debugger's list are stopped as well as
the one that encountered the breakpoint. This guarantees that the state
of the application remains consistent while the user examines the task.
The debugger will set the environment to that of the breakpoint task.
That is, the current module, current line, and the registers displayed
will all belong to the breakpointed task. The name and address of the
Task Control Block for the current task are always displayed in the
Dialog window's
title bar.
109 Debugging Multitasking Programs
Commands Used to Control Tasks
CodeProbe provides a number of commands that are used to control
tasks.
tasks
The tasks command displays all tasks under the debugger's control:
>tasks
Address Type Pri State SigWait StackPtr Debug Name
OOC513B8 13 0 Waiting 80000000 OOCSSlCC act multi
Note that there are eight fields (columns) displayed by this
command:
Address
contains the address of the task control block.
Type
indicates the type of node that begins the task control block. The
number 13 is used for processes, while 1 is used for simple tasks.
For a complete list of the possible task types, see the header file
exec/nodes.h.
Pri
contains the priority of the task.
State
indicates the process state.
SigWait
displays the SigWait field of the task control block. This field
indicates which signal bits the task may be waiting on.
StackPtr
indicates the current position of the stack pointer. Note that this
will be somewhat different from the value displayed in the sp
register. The value displayed here includes any information placed
on the stack by the trap handler or exception handler associated
with this task.
Debug
indicates the task's status with the debugger: act denotes an active
task, and inact denotes an inactive task. Tasks not under the
control of the debugger will have no information in this field.
Name
refers to the name of the task as specified in the task's node
structure.
110 Chapter 8
For more information on tasks and any of the fields except the debug
field just discussed, see the Amiga ROM Kernel Reference Manual:
Libraries and Devices.
The tasks command accepts an option called all. This option
causes all tasks in the system to be displayed. This is useful if you
want to catch a task that is not currently under debugger control. For
more details, see the discussion on the catch command later in this
chapter.
opt task
The opt task command makes a new task current. This command is
useful if several tasks are currently running under the debugger and
you want to examine or modify the state of some task besides the one
currently at a breakpoint.
When a new task is made current by this command, a new set of
registers is displayed. Highlighting of changed registers in the Register
window may be misleading since the debugger only keeps track of
changes while stepping through a single task. The module displayed in
the Source window may change, or more likely, if the task was in a
resident or linked library, assembler lines will be displayed. It may be
possible to get information as to the calling sequence of the task by
using the where command, but since assembler routines, including
the Amiga system's resident libraries, do not follow C language calling
conventions, the information displayed by where is only an intelligent
guess.
You can modify any registers, condition control register (CCR) flags,
or stack variables, just as in the breakpointed task. You can even single
step through the code. However, a word of caution is advised. A
breakpoint is implemented by placing an illegal instruction at the
desired location. All tasks under the debugger's control have a trap
handler attached to catch the illegal instruction and report back to the
debugger. A breakpoint in any shared code will insert an illegal
instruction in any task that executes that code. If you must place a
breakpoint in shared code, such as a resident library under test, be
sure that any task that might open it is under debugger control. Never
place breakpoints in libraries that you do not control. Improper use of
breakpoints in these circumstances can crash your machine.
The opt task command, like all commands that manipulate tasks,
takes task-ID as an argument:
op[t] t[ask] task-ID
A task-ID can be either the name of the task or the address of the
task control
block. If the name is used, it should be unique (otherwise
111 Debugging Multitasking Programs
the first task with that name in the debugger's task list will always be
selected). If the name contains a blank, the entire name must be
surrounded by double quotes.
Task addresses are generally entered in hexadecimal with a 0x
prefix. Task names and addresses can be determined with the tasks
command. Some sample commands are
>opt task Child
>opt task 0xC85428
>opt task "Child of multi"
Note: task command names are case sensitive.
activate and deactivate
While debugging a multiple task application, you may want to stop one
or more tasks temporarily. The deactivate command allows you to
prevent a task from running, even when the go command is
performed from another current task. Later, the task can be
reactivated by using the activate command. Both commands take
task-ID as an argument.
a[ctivate] task-ID
dea[ctivate] task-ID
detach
At times, you may want to allow one or more tasks spawned by a task
under the debugger to run freely and not under the control of
CodeProbe. For example, a task designed to respond to Intuition events
may cause the system to lock up if it does not respond to menu events
quickly. It may not be desirable to allow such a task to be stopped
when other tasks hit a breakpoint. Such a task can easily be freed from
debugger control by using the detach command.
To use the detach command, first set a breakpoint at the entry point
to the task. When the breakpoint is reached, use the tasks command
to identify the address or name of the task (you may know this based
on your code). Then enter the detach command. The syntax is the
same as the other task manipulation commands previously discussed.
det[ach] task-ID
A few cautionary words are in order regarding the use of the
detach command. Once the task is free from the debugger, it can no
longer handle breakpoints. Therefore, be sure that all breakpoints in
code reachable from a detached task have been removed. Second, the
task will not be removed automatically if you quit the
debugger. The
112 Chapter 8
detached task can continue running even after you exit CodeProbe.
Since CodeProbe frees all of the memory containing the code used by
the detached task, subsequent code segments can use part of this free
memory and a crash can occur.
If you later want to re-attach a task to the debugger, this can be
achieved using the catch command, the subject of the following
discussion.
catch
At times, you may find that a process or task not started under the
debugger is behaving in an unpredictable or undesired manner. For
instance, the task may be caught in an infinite loop. Another possibility
is that the task is waiting on some message port for a message that will
never come. The catch command is used to capture tasks that are
causing these types of problems. Its syntax is similar to those for other
task commands:
ca[tch] task-ID
To debug a task that is stuck in an infinite loop, invoke CodeProbe
with no filename. Then, when the debugger is up, use the command
tasks all to find the name and address of the process in question.
The catch command can then be used to capture the desired task
and place it under debugger control. If the task is a process, this
command will locate the code segments associated with the debug
executable as available from the process structure. If the task is not a
process, you will have to determine the address of the seglist and
use the opt env command to tell the debugger how to map the
debug information with the actual executable file. The opt env
command takes as an argument the address of a seglist pointer, as
in this example:
opt env 0xC08418
For more information on segment lists, see The AmigaDOS Manual,
3rd Edition.
symload
The symload command enables you to change the executable file
used for collecting debug information while the debugger is active. This
is useful when debugging several interacting applications that are
invoked from separate executable files. Note that this command does
not load any code
into memory or spawn any new processes or tasks.
113 Debugging Multitasking Programs
The symload command can take several forms. The following
command will find the executable file and the loaded memory segments
associated with the specified process, if it has CLI structure:
symload proc "process-name" executable
The process is specified by the process-name parameter, and the
executable file is specified by the executable parameter. Note that
symload and proc are required keywords in this example. If the
command has an executable filename as an additional argument, as in
this example, any debug information associated with that file will be
loaded instead of looking for the file associated with the process. The
address of a process task block can be specified in place of the process
name.
This command also can be given a pointer to a segment list as an
argument:
symload seg 0x123456 executable
The keyword seg is followed by the hexadecimal address pointing
to the process seglist. The name of an executable file is also
required.
Design Considerations for Debugger Compatibility
CodeProbe makes every effort to allow an application to run as it
would while running outside of debugger control. However, in order to
establish breakpoints and catch new tasks generated in a multitasking
application, CodeProbe must manipulate certain resources in the
application's task structure. In particular, CodeProbe redefines a task's
exception handler, exception data, trap handler, and trap data fields. If
it is necessary for an application to redefine any of these fields for its
own purposes, it must do so in the way described in the Amiga ROM
Kernel Reference Manual: Libraries and Devices.
Exception handlers must save the address of the original exception
handler and exception data fields and pass any unallocated exceptions
back to those routines. Before invoking the original exception handler,
be sure to restore the original exception data pointer in the task
structure.
The same practice applies to trap handlers. In particular, all
exceptions besides allocated traps should be passed to
the original trap
114 Chapter 8
handler. In order to control multitasking, CodeProbe performs a
SetFunction on the AddTask, OpenLibrary, OpenDevice, and
RemTask functions. These functions should not be redefined by an
application.
115
9 Commands and Built-in
Functions
115 Introduction
115 CodeProbe Commands
118 Special Parameters
118 address
119 array-slice
120 expression
120 location
121 number
121 range
122 register
123 string
123 subrange
124 type
125 variable
126 Command Reference
202 Built-in Functions
203 Built-in Function Reference
Introduction
This chapter provides complete reference information for each of the
CodeProbe commands and the built-in functions. This information is
provided in the following order:
[] list of CodeProbe commands that shows acceptable abbreviations and
provides a brief description of each command
[] list of built-in functions with brief descriptions
[] descriptions of special parameters, each of which is used with
several CodeProbe commands
[] reference information for each of the commands and built-in
functions.
CodeProbe Commands
As explained in Chapter 1, "Introduction to CodeProbe," debugger
commands can be entered four ways: from the Dialog window, from a
pull-down menu,
by function keys, or by menu-accelerator keys. This
116 Chapter 9
chapter describes each of the following debugger commands as they
are entered from the Dialog window:
a[ctivate] activates a task under debugger control
al[ias] defines an alias for a debugger command
ar[gs] displays the arguments to a function
bc[lear] clears one or more breakpoints
bd[isable] disables one or more breakpoints
be[nable] enables one or more breakpoints
bl[ist] lists all breakpoints
b[reak] sets a breakpoint
c[all] evaluates an expression and discards the result
ca[tch] catches a task not currently under debugger
control
dea[ctivate] deactivates a task under debugger control
def[ine] defines a macro
det[ach] detaches a task from debugger control
d[isplay] displays the value of an expression
du[mp] dumps memory contents
dz[ero] displays memory as a null-terminated ASCII string
ec[ho] displays a string
env sets the environment
ex[ecute] executes a debugger command file
expand expands and displays a command line
fin[ish] terminates CPRK and CPRX
fr[egister] displays or modifies floating-point registers
g[o] continues execution until a breakpoint is
encountered or the program exits
h[elp] displays help information
hu[nks] lists the addresses and sizes of all hunks
j[ump] changes the current execution point
117 Commands and Built-in Functions
l[ist] lists the lines in a source file
lo[g] logs debugger commands to a file
op[t] shows option values or changes the value of a
debugger option
p[roceed] single-steps over function calls
ps single-steps over function calls by source line
q[uit] terminates the debugger
r[egister] displays or modifies registers
res[tart] restarts the program being debugged
ret[urn] returns immediately from the current function
rf[lag] displays or modifies flags
sea[rch] searches for a string in the current source file
se[t] modifies the values of variables or memory
locations
sle[ep] pauses for the time specified
so[urce] displays the source file
sta[rt] restarts the program being debugged
symb[ol] finds the symbol nearest to the specified address
sym[load] reads symbol information from an executable file
ta[sks] displays system tasks
t[race] single-steps into function calls
ts single-steps by source line into function calls
unal[ias] deletes an alias
u[nassemble] displays memory as assembler instructions
und[efine] deletes a macro definition
w[atch] sets a watch on a variable or memory
wb[reak] sets a watch break
wc[lear] clears one or more watches
wd[isable] disables one or more watches
we[nable] enables one or
more watches
118 Chapter 9
wha[tis] determines the type of an object
whe[re] shows the calling sequence
wi[ndow] opens or closes a window
wl[ist] lists all watches
wmsg writes a message to the Message window.
Special Parameters
The following special parameters are described in this section:
[] address
[] array-slice
[] expression
[] location
[] number
[] range
[] register
[] string
[] subrange
[] type
[] variable.
Each of these parameters is used in several CodeProbe commands.
address
An address parameter is any expression that denotes an address. This
may be a hexadecimal constant, a C pointer variable, a register, the
result of prefixing & to a C identifier of the proper type, or the result
of arithmetic calculations on other addresses. Note that the address
operator & may not be applied to the identifier of a bitfield or a
register.
The following are examples of values of expressions that denote an
address where p is a pointer, and i and x are integers:
&i
(&i + 8)
&arrayl 3 1
&mystruct - x
0x00C85400
a0
(a0 + 0x22)
119 Commands and Built in Functions
There are some cases where a register name may be ambiguous. For
example, you may have defined a variable sp in your program. In the
following command it is not clear whether you mean to dump data
beginning at the variable sp, or at the address contained in the
register SP:
db sp
In such cases the debugger will assume that you mean to refer to the
variable sp. However, you can prefix the register name with a dollar
sign ($) or use the register command to examine the value of the
SP register even if you have declared a variable named sp.
In certain commands, it is necessary to specify the type of an object
to be modified or displayed. If the object is referred to by means of an
address constant or register, the value is assumed to be a character
pointer (char *).
array-slice
An array-slice parameter is a contiguous section of a unidimensional
array of scalar variables, an ordered selection of elements from a
multidimensional array, or an ordered selection of members from an
array of complex types. An array-slice is specified using the following
form:
variable [[n . . m ] | [*]]
Note: The inner brackets in this syntax diagram are not optional
and do not denote optional parameters.
The advantage of using an array-slice parameter over a range
parameter is that the array-slice can be used to select isolated
subcomponents, such as a particular structure member from an array
of structures. The array-slice parameter also can be nested for
multidimensional arrays or structure members that are arrays
themselves.
The subrange parameter is described later in this chapter. If a
subrange is chosen as the index of an array-slice, those elements within
the subrange are selected. The asterisk (*) index specifies that all
elements of the array are to be contained in the array-slice.
The following are examples of the array-slice parameter:
a[3..7]
matrix[i..j][1.ù3]
b[*]
a[3..6]->b
120 Chapter 9
expression Any C expression is accepted as an expression parameter, except those
that use one or more of the following operators:
++ or --
,
?:
=
&=
|=
>>=
<<=
+=
-=
*=
/=
%=
^=
location
A location parameter specifies a place in the code at which a
breakpoint is to be set, code is to be unassembled, or a similar action
is to be performed. When debugging in source mode, you can think of
a location parameter as a line number in a source file or a function
entry point. When debugging in assembly mode, you may want to
place breakpoints at specific addresses. To do this, specify a
hexadecimal address as the location parameter.
The location parameter can be specified in one of two ways:
[] hex address
[] [[image:][\module\]function] line
In the first form, the hex-address variable can be any valid absolute
address specified as a hexadecimal integer.
In the second form the values for the variables image, module, and
function can be specified explicitly as follows:
image
is the name of the executable image (the program, library, or
device) containing the location. It is usually specified in lowercase.
If omitted, the current image is the default. In a program with only
one image, it is never necessary to specify a value for image: Note
the required colon (:).
module
is the name of the C source file compiled to yield the specified
function. Note
the backslash (\) postfix.
121 Commands and Built in Functions
function
is the name of a function in the application.
You can put spaces between the value specified for image and its colon
postfix and the value specified for module and its backslash postfix. but
they are not necessary. You must put a space before the line parameter.
The line parameter can specify any of the following points in the
source code:
integer
a line number, relative to the start of the C source file containing
the function
$
the current location
e[ntry]
the entry to the function (prolog)
r[eturn]
the return from the function (epilog).
If the function name is not specified with the line parameter, the
debugger defaults to the current function. If a function is specified
without a line, the debugger defaults to the first execution line.
number
A number parameter is a number in decimal, octal, or hexadecimal
notation. An initial 0 digit causes the number to be interpreted as
octal, an initial 0x (or 0x) causes the number to be interpreted as
hexadecimal, and an initial 0n (or 0N) causes the number to be
interpreted as decimal. The default is decimal.
Examples of acceptable values for the number parameter include the
following:
12345
0455
0x380
0X1849
0n12345
range
A range parameter is a contiguous area of memory that can be
specified in one of two ways:
[] address..address
[] address l number
address L
number
122 Chapter 9
In both forms, the first address variable is the start address, and the
range begins at this address.
In the first form, the second value for address is the end address,
and the range includes the area of memory from the start address to
the end address.
In the second form, the l or L indicates that the value for the
variable number is to be interpreted as a length. In this case, number
indicates the number of elements and the range is from the start
address through address+number-1. When the debugger sees a
solitary l or L in a command, it is considered part of a range
expression.
The following examples fit the definition of the range parameter:
0x123456 .. 0x123461
0x123456 L 11
a1..a2
a7 l 20
&P[O] .. &P[5]
P[0] .. P[5]
&P[0] l 6
P[0] l 6
The first pair of examples are equivalent. The next pair are variants
of the basic range expression. The remaining pairs are equivalent
ranges, given the addressing policy described earlier in this section.
register
A register parameter refers to the name of any of the following 680xO
registers:
A0 - A7 are address registers. Register A7 functions as the
stack pointer and can be specified as either A7 or
SP.
D0 - D7 are general-purpose registers.
PC is the program counter.
SP is the stack pointer.
SR is the status register. It contains the CCR register
as well as the current processor status.
CCR is the condition code register. It resides in the
lower byte of the status register, SR.
123 Commands and Built-in Functions
If a math coprocessor is present, the following registers also can be
specified as the register parameter:
FP0 - FP7 are the floating-point registers.
FCR is the floating-point control register.
FSR is the floating-point status register. It contains the
current floating-point condition codes.
Optionally, registers can be prefixed with a dollar sign ($) to
distinguish them from variables with the same name. For example,
register D1 can be specified as $D1 to distinguish it from a variable
named d1.
string
A string parameter can be any standard C string in double quotes (").
Standard C escape sequences starting with the backslash character are
supported as follows:
\n newline (0x0a)
\t horizontal tab (0x09)
\b backspace (0x08)
\r carriage return (0x0d)
\f form feed (0x0c)
\v vertical tab (0x0b)
\NNN octal constant, where NNN is a three-digit octal
number
\xNN hex constant, where NN is a two-digit hexadecimal
number.
A backslash followed by any character other than those shown
previously in the escape sequences is interpreted as a plain character.
For example, \ \ is a string consisting of a single backslash, and a \ " b
is three characters long: an a, a double quote, and a b.
The Dialog window does not recognize any of these escape sequences
when they are displayed. You cannot use the \t escape sequence to
tab in the Dialog window. The escape sequences are useful in line
mode and when setting a character string.
Like all debugger input, a string can be continued to the next line by
ending the line with a backslash. The debugger does not support ANSI
string concatenation.
subrange
A subrange parameter is a series of contiguous integers, inclusive of its
bounds. The integers may be either integer constants or
variables from
124 Chapter 9
the application being debugged. The form of the subrange parameter is
as follows:
[integer | variable]. . [integer | variable]
The following are examples of the subrange parameter:
3..7
i..j
type
A type parameter can be any of the data types provided by the C
language including any of the following:
char
unsigned char
short
unsigned short
int
unsigned int
long
Unsigned long
unsigned
float
double
struct <name>
union <name>
enum <name>
A type also can be any of the C types previously listed followed by
some number of asterisks indicating that the type is a pointer to the
base object.
In addition, the type parameter can take any identifier defined by
means of a typedef statement if the debugging information for the
module supplies
typedef information.
125 Commands and Built-in Functions
variable
A variable parameter is an expression in your program that designates
an object. It can be either a simple identifier or an expression
referring to an array element, structure member, or object pointed to
by a pointer. In addition, it can begin with a specification of the
following form:
[[image:][\module\]function]
See the location parameter earlier in this chapter for a description of
the image, module, and function variables.
The following are objects that fit the definition of the variable
parameter:
i
max
array[3]
array
io:readfile\length
mystruct->name[2]
mystruct
*cptr
main.c\opnf\count
opnf\i
mylib.library:LIBmyfunc\myvar
126 Chapter 9
Command Reference
This section provides complete reference information for each of the
CodeProbe commands. The commands are listed in alphabetical order.
Most of the command descriptions include the following sections:
Synopsis shows the format of the debugger command or
built-in function
Description describes the function of the debugger command or
built-in function and contains all the information
you need to use the command or function
Example contains examples that illustrate how to use the
command or function
See Also refers you to the descriptions of other related
commands or
functions.
127 Commands and Built-in Functions
activate Activates a task under debugger control
Synopsis a[ctivate] [task-name | task-address | exe-name]
Description: The activate command activates a task that has been deactivated by
the deactivate command. The task is activated when the next go or
proceed command is executed.
The task-name, task-address, and exe-name parameters are the name
of the task, the address of the task, and the executable name of the
task as specified by the tasks command. Only one of these
parameters can be specified.
Examples activate Child
activates the task named Child under debugger control.
activate 0xC08540
activates the task with a task block starting
at address 0xC08540.
activate myprog
activates the task executing the program myprog.
See Also catch, deactivate,
detach, tasks
128 Chapter 9
alias Defines an alias for a debugger command
Synopsis al[ias] [name[definition]]
Description: When entered with no arguments, the alias command displays the
list of all currently defined aliases. If a value for name is provided as
the only argument, the definition for that alias will be displayed. Any
text following the name parameter is treated as a definition and is used
to define the alias.
Alias names are expanded only when they occur at the beginning of
a Dialog window command line. An alias definition can be a simple
textual substitution or it can contain positional parameters to be
expanded at execution time. Positional parameters are specified as $1,
$2, $3, and so on. $0 represents the alias name itself. $* represents
command line parameters $1 through $n. If no positional parameter is
specified in a definition, all parameters are placed after the expanded
definition text.
The alias command will parse a definition until it encounters a
command delimiter character (;) or the end of the line. To define an
alias that expands into more than one command, enclose the definition
in either double quotes or curly braces. If the command string must
contain double quotes, curly braces can be used or the quotes can be
escaped. As in C and all other debugger commands, a backslash may
be used to continue the line.
Examples alias
displays a list of all alias definitions.
alias foo
displays a definition of f oo.
alias next proceed
defines next to be an alias for proceed.
alias pr display foo, bar, $*
defines pr to be an alias that executes the display command
printing the value of foo, bar, and any variables entered after
the pr.
alias doit {go $1; d foo}
defines doit to execute the go command using the first
parameter, and displays the variable named foo.
alias doit {go $1;\
d foo}
uses the backslash command to split a command across two lines.
129 Commands and Built-in Functions
alias Defines an alias for a debugger command
(continued)
alias doit "go $1; d $2"
uses positional parameters with multiple commands. The first
parameter, $ 1, is passed to the go command, and the second
parameter, $2, is passed to the display command.
See Also
define,unalias,undefine
130 Chapter 9
args Displays the arguments to a function
Synopsis ar[gs] [function-name]
Description: The args command displays all of the argument names and values to
the current function or the function specified by the function-name
parameter. If a function-name parameter is specified it must be in the
calling sequence, as displayed by the where command.
Examples args
displays the arguments to the current function.
args sort
displays the arguments to the sort function.
See Also display,
env, where
131 Commands and Built-in Functions
bclear Clears one or more breakpoints
Synopsis bc[lear] integer[integer...]
bc[lear]* | l[ast]
bc[lear] integer .. integer
Description: The bclear command clears one or more breakpoints. When a
breakpoint is cleared, it ceases to exist and can be reinstated only by
issuing the break command again. You should use the bdisable
command to disable breakpoints temporarily.
The integer parameter specifies the breakpoint number as displayed
by the blist command. Any number of values can be specified as
integer parameters. An asterisk specifies that all breakpoints should
be cleared and last causes the most recently set breakpoint to be
cleared. A range of breakpoints can be specified by
integer. . integer.
Examples bclear 2 5 6
clears the breakpoints numbered 2, 5, and 6.
bclear last
clears the last breakpoint set.
bclear *
clears all breakpoints.
bclear 4 .. 7
clears breakpoints 4, 5, 6, and 7
See Also bdisable,
benable, blist, break, wclear
132 Chapter 9
bdisable Disables one or more breakpoints
Synopsis bd[isable]integer[integer...]
bd[isable] * | l[ast]
bd[isable]integer .. integer
Description: The bdisable command disables the recognition of one or more
breakpoints. When a breakpoint is disabled, it is not recognized by
CodeProbe, but it does remain on the list of current breakpoints. A
disabled breakpoint can be re-enabled by the benable command.
The integer parameter specifies the breakpoint number as displayed
by the blist command. Any number of values can be specified as
integer parameters. An asterisk specifies that all breakpoints should be
disabled and last causes the most recently set breakpoint to be
disabled. A range of breakpoints can be specified by integer . . integer.
Examples bdisable 2 5 6
disables the breakpoints numbered 2, 5, and 6.
bdisable last
disables the last breakpoint set.
bdisable *
disables all breakpoints.
bdisable 4 .. 7
disables breakpoints 4, 5, 6, and 7.
See Also bclear, benable, blist, break, wdisable
133 Commands and Built-in Functions
benable Enables one or more breakpoints
Synopsis be[enable] integer [integer ...]
be[enable] * | l[ast]
be[enable] integer .. integer
Description: The benable command enables the recognition of one or more
breakpoints that have been disabled by the bdisable command.
The integer parameter specifies the breakpoint number as displayed
by the blist command. Any number of values can be specified as
integer parameters. An asterisk specifies that all breakpoints should be
enabled and last causes the most recently set breakpoint to be
enabled. A range of breakpoints can be specified by integer . . integer.
Examples benable 2 5 6
enables the breakpoints numbered 2, S, and 6.
benable last
enables the last breakpoint set.
benable *
enables all breakpoints.
benable 4 .. 7
enables breakpoints 4, 5, 6, and 7.
See Also
bclear, bdisable, blist, break, wenable
134 Chapter 9
blist Lists all breakpoints
Synopsis bl[ist]
Description: The blist command displays a list of all breakpoints. Each entry has
a form similar to the following example:
5 0x40054 loop:\loop.c\main 8 (2 hits)
after(4) when(i == 3) quiet {echo Hi}
The number 5 in this example is the number used to refer to this
breakpoint in bclear, bdisable, and benable commands. If an
asterisk appears next to the number, that breakpoint has been disabled
and will not be triggered. Following the breakpoint number is the
hexadecimal address at which the breakpoint resides. If sufficient
debug information is available, the address is followed by the location
that it represents. The hit count, which represents a running count of
the number of times the breakpoint has been triggered, is displayed
after the location of the breakpoint. A breakpoint is triggered when all
of the following conditions are true:
[] execution has reached the address shown
[] the when and after conditions are true, if specified
[] the breakpoint is enabled.
Breakpoints are triggered when the user steps to the address provided
the last two conditions are met. The second line of output displayed by
the blist command shows the options given when the break
command was issued.
See Also bclear,
bdisable, benable, break, wlist
135 Commands and Built-in Functions
break Sets a breakpoint
Synopsis b[reak] location[after(integer)][when(expression)]
[tr[ace]] [q[uiet]] [te[mp]] [{cmd-list}]
Description: The break command is used to set a breakpoint at a location
specified by the location parameter. You can use a dollar sign to specify the
current location.
The after option specifies the minimum number of times the
specified line must be executed before the breakpoint is triggered. This
is also known as specifying a pass count. For break commands that
do not contain an after clause, the pass count is set to 1.
Each time the breakpoint is hit, the pass count is tested. If the pass
count equals 1, the breakpoint is triggered and execution stops. If the
pass count is greater than 1, the pass count is decremented by 1, and
execution continues. The blist command shows the current pass
count for each breakpoint.
If the when option is present, the breakpoint is triggered only if the
specified expression evaluates to true (nonzero). The after and when
options can be specified in any order. If both options are specified, the
pass count is tested and decremented only when the when condition is
true.
The trace option continues execution automatically after the
breakpoint is triggered, unless you reach the breakpoint by single-
stepping, then the the trace option has no effect.
The quiet option suppresses the default message showing the
location when the breakpoint is triggered.
The temp option causes the breakpoint to be deleted after it has
been triggered.
If the cmd-list parameter is present, the commands listed are
performed each time the breakpoint is triggered. As in C commands
and all other debugger commands, a backslash may be used to
continue the line.
Note: To avoid confusion, the break command does not use the
default radix setting. You must specify ox for an address; otherwise,
you will be specifying a line number. For example, even if the radix is
set to hex, the following command specifies a break command for
line 20 and not address 0x20:
b 20
136 Chapter 9
break Sets a breakpoint
(continued)
Examples break $
sets a breakpoint at the current line.
b 14
sets a breakpoint at line 14 of the current module.
b sort
sets a breakpoint at the first line of the sort function.
break sort return
sets a breakpoint at the return from the sort function.
break \myfile.c\sort 14
sets a breakpoint at line 14 of sort in the module named
myfile.c.
break mylib.library:myfunc
sets a breakpoint at the first line of the myf unc function in
the shared library mylib. library.
b $ after(5)
breaks the fifth time the current line is executed.
break 0x804A
sets a breakpoint at the absolute address 0x804A.
break 14 when (i > 5) (di p L 16; b sort 26
when (i == 8); bl; go)
sets a breakpoint on line 14 that performs the commands given
inside the curly braces if i > 5 evaluates true.
b 8 trace quiet (d "i = ", i)
prints a message of the form ~ i = value "every time line 8 is
executed.
break 100 temp (d foo)
stops at line 100, prints f oo, and deletes this breakpoint.
See Also bclear,bdisable,benable,blist,go
137 Commands and Built-in Functions
call Evaluates an expression and discards the result
Synopsis c[all] expression
Description: The call command is used to evaluate an expression when you do not
care about the value returned. It is equivalent to the following
statement in C language:
expression;
The most common use of the call command is to call a function in
the application program, though function calls also may appear in
arbitrary expressions in other commands. If you want to see the value
returned by the expression, use the display command.
The debugger looks at the types of the parameters specified and not
at the definition of the function or any prototype. Thus, the debugger
does not flag an error if the wrong number of parameters are
specified, nor does it perform automatic casting of types or allow
passing of char, short, or f loat types. For example, the following
command passes two parameters, an int and a double, regardless of
how the function is declared:
call f(2, 1.5)
CodeProbe supports standard C syntax for function calls. Either a
function name or an expression evaluating to a function type may be
specified before the opening parenthesis. Thus, the call command can
be used only to call functions or evaluate expressions that point to a
function. For example, if pf is a function pointer, and f unc is a
function, the following commands are allowed:
call func()
call (*pf)()
However, the following commands are not allowed:
call pf()
call 0xl34()
call register( )
You cannot use the call command to execute a function after a
program has
ended.
138 Chapter 9
call Evaluates an expression and discards the result
(continued)
If a breakpoint is hit, a signal is caught, or the program terminates
in the middle of a function call, the debugger aborts the expression
and leaves you at that location. A warning is printed if any parameters
are not cleaned off the stack. This may cause a return to an invalid
location later if execution is allowed to continue.
Examples call status()
calls the status function.
call print("Test", 300)
calls the print function passing in a string and an integer
parameter.
call (*fp)(&arr[5], j+10, 3.0)
evaluates arbitrary expressions.
See Also display,env,where
139 Commands and Built-in Functions
catch Catches a task not currently under debugger control
Synopsis ca[tch] [task-name I address I exe-name]
Description: The catch command enables the debugger to gain control of tasks
that were not started under the control of CPR. The task-name and
address parameters can be found by issuing a t a s k s a 11 command.
The exe-name parameter can be used to specify the name of the
executable associated with the task you want to catch.
Examples catch Child
catches the task named Child.
ca 0xC08540
catches the task with a task block starting address 0xC08540.
catch myprog
catches the task running the program myprog.
See Also
activate, deactivate, detach, symload, tasks
140 Chapter 9
deactivate Deactivates a task under debugger control
Synopsis dea[ctivate] [task-name | address | exe-name ]
Description: Normally all tasks under CPR's control are started when a go or
proceed command is issued. The deactivate command can be
used to deactivate a task. A task that is deactivated by this command is
not started when the debugger allows the application to run unless it is
the current task. The task can be reactivated with the activate
command.
The task-name and address parameters can be found by issuing a
tasks command. The exe-name parameter can be used to specify the
name of the executable associated with the task you want to catch.
Examples dea Child
deactivates the task named Child under CPR.
deactivate 0xC08540
deactivates the task with a task block starting at address
0xC08540.
deactivate myprog
deactivates the task running the program named myprog.
See Also activate,
catch, detach, tasks
141 Commands and Built-in Functions
define Defines a macro
Synopsis [#]def[ine] name [definition]
[#]def[ine] name(parm [,parm ... ]) [definition]
Description: The define command provides a general macro substitution facility
that is nearly identical to the mechanism provided in C syntax. Macros
defined in the debugger are expanded anywhere within a line of text
except inside quotes or filenames. The debugger also will not expand
macro definitions that are prefixed with a backtick character ( ` ). The
ANSI # and ## operators are not supported.
Examples define
displays all the macro definitions.
define foo
defines foo as a null definition.
def foo bar
defines foo to be bar.
define func(a,b) (a+b)
defines func with parameters.
See Also alias,
unalias, undefine
142 Chapter 9
detach Detaches a task from debugger control
Synopsis det[ach] [task-name | address | exe-name ]
Description: The detach command detaches a task from debugger control. The
task can be brought under CodeProbe's control with the catch
command.
The task-name and address parameters can be found by issuing a
tasks command. The exe-name parameter can be used to specify the
name of the executable associated with the task you want to catch.
When using the detach command make sure that no breakpoints
are placed inside code that is executable from a detached task. Also, do
not specify the detach command to the original program if any of its
child processes continue to run in the same code segment.
Examples detach Child
detaches the task named Child from debugger control.
det 0xC08540
detaches the task with a task block starting at
address 0xC08540.
det myprog
detaches the task executing the program myprog.
See Also activate,
catch, deactivate, tasks
143 Commands and Built-in Functions
display Displays the value of an expression
Synopsis d[isplay] (expression["format"] | string) [, ...]
Description: The display command evaluates the value of the expression
parameter and displays the result. The expression parameter can be
any C expression containing constants, variables, and function calls
from the program being debugged. Any number of expressions and
strings can be specified, separated by commas. All expressions are
displayed on the same line.
The display command chooses the default format based on the
type of the expression. Values of type char are displayed as
characters as well as in decimal and hexadecimal format. If the
character is unprintable it is displayed as an escape sequence, for
example, \n or \xAC. Values of type int and long are displayed in
decimal and hexadecimal format, and f loats and doubles are
displayed in floating-point best format.
To override the default format, a printf style format can be
specified optionally after each expression. No error checking is done on
the format parameter, so strange results are possible. It may contain
up to two conversion operators for short and long types but only
one for all other types.
All members of structures, unions, and arrays are displayed using
the default formats. Partial arrays may be displayed using two integers
to indicate the first and last elements to display. For example, the
following command displays array elements 3, 4, and 5:
display a[3..5]
An asterisk may be used instead to indicate that all elements should be
displayed.
The string parameter can be any standard C string in double quotes
as described earlier in this chapter in the "Special Parameters" section.
To display a null-terminated string, use the dzero command. Use
the dump command to dump an area of memory.
Examples display
displays the variable i.
d a "a=%10.5e"
displays a using a printf style format specifier.
d p->d[5] + f(3)
displays the value of an expression containing a function
call.
144 Chapter 9
display Displays the value of an expression
(continued)
display "X is", x, "J is", j
displays the value of several argu ments including strings.
d x "X is %d", j "J is %d"
displays the value of several arguments using printf style
format specifiers.
d a[3]
displays the value of an element of an array.
display a[3..5]
displays the value of elements 3 through 5 in an array named
a.
d a[*]
displays the value of every element of an array.
See Also call,dump,dzero
145 Commands and Built-in Functions 145
dump Dumps memory contents
Synopsis du[mp] [variable | address | range] [S]
[format [itemsize] | text]
Description: The dump command is used to examine an area of memory. You select
the format of the dump, the length of each item being dumped, and
whether or not you want text to appear on the right side of the dump.
A dump command with no parameters continues where the previous
dump command ended using the same dump specifications.
The variable, address, or range parameter specifies the location to be
dumped. The $ parameter can be used to specify the last dump address
when the format or text parameters are used. The $ is ignored if a
variable, address, or range parameter has already been specified
making it useful for aliases where the dump address may be omitted.
The format parameter controls the format of the dump and its value
can be any of the following:
a[scii] FFP[float] IEEE[float]
b[inary] f[loat] o[ctal]
d[ecimal] h[ex] u[nsigned]
The default format is hex.
If you specify a format parameter, you also can specify an itemsize
parameter to control the length of each item dumped. The itemsize
parameter can have a value of 1, 2, 4, or 8. The itemsize parameter is
concatenated onto the end of the format parameter (for example, b4
for a binary format of length 4). If you do not specify itemsize,
CodeProbe uses a default. As shown in the following table, the
allowable size and default values depend on the format specified.
The text parameter is used to specify that an ASCII representation
of the memory
dump should be displayed.
146 Chapter 9
dump Dumps memory contents
(continued)
The itemsize parameter has the following default values and
allowable sizes:
Format Default Allowed Sizes
ascii 1 1
binary 1 1, 2, 4
decimal 4 1, 2, 4
FFPfloat 4 4
float 8 4, 8
hex 4 1, 2, 4
IEEEfloat 8 4, 8
octal 4 1, 2, 4
unsigned 4 1, 2, 4
Compatibility Aliases
To provide backward compatibility with previous releases of
CodeProbe, the following aliases for the dump command are
supported:
da
dumps a range of memory as ASCII characters
db
dumps a range of memory in both hexadecimal and ASCII format
dc
dumps a range of memory in decimal format
dd
dumps a range of memory as 8-byte floating-point numbers in IEEE
format
df
dumps a range of memory as 4-byte floating-point numbers in IEEE
format
dffp
dumps a range of memory as 4-byte floating-point numbers in FFP
format
147 Commands and Built-in Functions
dump Dumps memory contents
(continued)
di or dl
dumps a range of memory in integer format using decimal
representations of the integers
dw
dumps a range of memory in short integer (16-bit) format using
hexadecimal representations of the integers
dp
dumps a range of memory in 4-byte hexadecimal format
ds
dumps a range of memory in short integer (16-bit) format, using
decimal representations of the integers.
Examples dump var
dumps memory contents of variable var.
dump var L 13 hex1
dumps memory contents for 13 bytes using 1-byte hexadecimal
format.
dump var1 .. var2 ascii
dumps memory contents between var 1 . . var 2 in ASCII format.
dump 0xAF8100 L 8
dumps memory contents for 8 longs (32 bytes) starting at
absolute address 0xAF8100.
See Also
display,dzero
148 Chapter 9
dzero Displays memory as a null-terminated ASCII string
Synopsis dz[ero] variable | address | array-slice
Description: The dzero command displays the contents of memory as a null-
terminated (\0) string. If the location is the name of a nonpointer
variable in the program being debugged, dzero displays the memory
contents starting at the address of the variable and continuing until the
null character is found. If the location is the name of a pointer
variable, dzero uses the contents of the pointer and displays bytes
starting at that address until a null character is encountered. If the
address parameter is used to specify an absolute address, dzero
displays the contents of that address until a null character is
encountered. If the location is an array-slice, the address of each
element in the array slice will be displayed until the null character is
found.
Examples dzero string
displays characters until the null character is reached.
dzero ptr
displays data pointed to by ptr as a string.
dzero ptr[3..7]
displays each element in the array slice ptr [3..7] until the
null character is reached.
See Also display,
dump
149 Commands and Built-in Functions
echo Displays a string
Synopsis ec[ho] [text]
Description: The echo command writes the value specified for the text parameter
in the Dialog window. This is useful for documenting the actions being
taken in a debugger command file, the cprinit file, or AREXX
macros. If the text parameter contains semicolons, they must be
escaped with a backslash (\;). Defines or aliases are not expanded.
Example echo Starting program\; loading defines .
displays the message following the echo command in the Display
window.
See Also display,
execute
150 Chapter 9
env Sets the environment
Synopsis env[function | integer]
env[-c[aller] | -s[ubroutine] | -u[p] | -d[own] | -integer |
+integer]
Description: The env command changes the environment for subsequent debugger
commands. Environment is the state of the machine at a particular
point in the calling sequence (that is, the contents of the stack and the
contents of variables). Setting the environment to a previous point in
the calling sequence, such as the point where the current function was
called, returns the machine to the state it was in at that time.
However, only the information that can be retrieved from the stack
will have been restored. Scratch registers and other components, such
as the values of externs, that are not dependent on the stack remain
relative to the current execution point in the application and will not
be changed. Nonscratch registers are restored to the correct values for
the new environment.
The environment can be set to an absolute or relative position in the
call chain. To set it to an absolute position, specify the function name
using the function parameter, or a level number using the integer
parameter. The where command or Calls window can be used to
display the level number. The other forms to the env command set the
environment relative to the current function.
To move the environment up one level to the caller of the current
function, use the -caller, -up, or -1 flags. To move in the opposite
direction, use the -subroutine, -down, or +1 flags. Use the
+integer or -integer forms to move more than one level at a
time.
Level 1 is defined to be the function in which you are currently
stopped. The caller's level is 2, its caller is level 3, and so on. These
level number designations change as the program steps into and
returns from functions.
If you attempt to move the environment up or down more levels
than there are in the call frame, a warning is displayed and the
environment is moved as far as possible.
After using the env command, commands that refer to line numbers
and variables act as if the function specified by the function parameter
is the current function. Any command that causes the program being
debugged to resume execution, such as the go or trace commands,
automatically resets the user environment to the last point of
execution. Issuing the env command is the same as double-clicking on
a function call
entry in the Calls window.
151 Commands and Built-in Functions
env Sets the environment
(continued)
Examples env
sets the user environment to the last point of execution.
env main; d i
sets the user environment to main and display i.
env -subroutine
sets the environment to the called function (down 1 level).
env -caller
sets the environment to the caller function (up 1 level).
env +5
moves the environment down 5 levels.
env 7
moves the environment to the level 7.
See Also where
152 Chapter 9
execute Executes a debugger command file
Synopsis ex[ecute] filename
Description: The execute command reads and executes CodeProbe commands
from the file specified by the filename parameter. If the file cannot be
found, CodeProbe appends a . cpr extension to it and tries again.
Thus, you can place a set of debugger commands in a file with a .cpr
extension and simply use the root filename, minus the extension, in the
execute command. CodeProbe searches for the specified file in your
normal Shell path as defined with the AmigaDOS PATH command.
If the file cmds.cpr consists of the commands
break sort
blist
trace
trace
then the execute command applied to this file would yield the
following display:
> execute cmds.cpr
executing commands from cmds.cpr
1 0xC32D3E sort:\sort.c\sort 22
sort:\sort.c\init 5
sort:\sort.c\init 9
The debugger commands themselves are not echoed as part of the
display unless echo mode is turned on.
If you are debugging a program frequently and want to set a number
of breakpoints at the same places, you can place all of your breakpoint
commands in a file and then use the execute command on this file.
This way you can avoid re-entering the same commands each time you
want to use the debugger.
If the execute command is used in a command list, it must be the
last command in the list.
Examples execute setvars
executes the file named setvars or setvars .cpr.
execute test/cmds.cpr
executes the file named cmds.cpr located in the test directory.
153 Commands and Built-in Functions
expand Expands and displays a command line
Synopsis expand [alias] command-line
Description: The expand command displays its arguments with all aliases or
defines expanded. The command-line parameter specifies any valid
command-line entry that includes aliases or defines. This command can
be useful in trying to create more complex aliases and defines.
If the alias keyword is not specified, aliases are not expanded, but
defines will be expanded.
Examples expand alias dp
expands the alias for named dp to display the following:
dump $ hex4
expand ISEQUAL(1,5)
expands the macro ISEQUAL using the arguments 1 and 5. For
example, if ISEQUAL has been defined as ( a == b ), then it
would be expanded to ( 1 = = 5 ) .
See Also alias,
define
154 Chapter 9
ffnish Terminates CPRK and CPRX
Synopsis fin[ish]
Description: The finish command is used in cross-development mode to terminate
the session. The cross debugger (CPRX) on the host machine instructs
the kernel (CPRK) on the target machine to terminate after cleaning up
and closing the communications link. The f i n i s h command must be
entered on the host machine. The host machine is the one that is being
used to display the CodeProbe user interface. The f i n i s h command
does not work from the native version of CodeProbe.
Example finish
causes CPRK to terminate after disconnecting from CPRX.
See Also quit
155 Commands and Built-in Functions
fregister Displays or modifies floating-point registers
Synopsis fr[egister] [register[[=] expression]]
Description: On machines that have a math coprocessor chip installed, the
fregister command displays or modifies the contents of the
floating-point registers. If no parameters are specified, the fregister
command displays the current contents of all the machine's floating-
point registers in hexadecimal and as floating-point numbers. If only a
register name is supplied, the contents of the register are displayed;
otherwise, the value of the expression parameter is stored in the
register specified.
The display and set commands also can be used to display and
modify the registers.
Examples fr
displays all floating-point registers and flags.
fregister fp0 30.14
sets floating-point register fp0 to 30. 14.
fr fp2 = sales
sets floating-point register p2 equal to the value of sales.
fregister fp1
displays the value of floating-point register fp1.
See Also
display,register,rflag,set
156 Chapter 9
go Continues execution until a breakpoint is encountered or the program
exits
Synopsis g[o][location[after(integer)] [when(expression)]]
Description: The go command begins execution of the program at the current
location, which is identified by the address stored in the program
counter (pc) register. Execution continues until a breakpoint is reached
or until the program terminates, either normally or with an error.
The location parameter specifies an optional location for a temporary
breakpoint. The breakpoint specified in the go command exists only
for the duration of the go command. The next time program execution
stops, the breakpoint is cleared, even if the temporary breakpoint was
not reached.
The after option specifies the minimum number of times the
specified location must be reached before the temporary breakpoint is
triggered. This is also known as specifying a pass count. For go
commands that do not contain an after clause, the pass count is set
to 1.
Each time the temporary breakpoint is hit, the pass count is tested.
If the pass count equals 1, the temporary breakpoint is triggered and
execution stops. If the pass count is greater than 1, the pass count is
decremented by 1 and execution continues.
If the when option is present, the breakpoint is triggered only if the
specified expression evaluates to true (nonzero). The after and when
options can be specified in any order. If both are used, the pass count
is only tested and decremented when the condition is true.
Note: To avoid confusion, the go command does not use the
default radix setting. You must specify ox for an address; otherwise,
you will be specifying a line number. For example, even if the radix is
set to hex, the following command specifies a go command for line 20
and not address 0x20:
g 20
Examples go
continues program execution to the next breakpoint or the end
of the program.
go 14
continues program execution to line 14 of the current module.
Note that line numbers are relative to a module and not a
function. This example assumes that code was generated at line
14. You cannot use the go command to go to a line with no code
generated.
157 Commands and Built-in Functions
go Continues execution until a breakpoint is encountered or the program
(continued) exits
go sort
continues program execution to the first line of the sort function.
go \myfile.c\sort 14
continues program execution to line 14 of the sort function in
module my file.c . This example also assumes that code was
generated at line 14.
go mylib.library: myfunc
continues program execution to the myfunc function in the shared
library mylib. library.
go $ after(5)
continues program execution until the fifth time the current line is
executed.
go 0x804A
continues program execution until absolute address 0x804A is
reached.
See Also break,
proceed, ps, trace, ts
158 Chapter 9
help Displays help information
Synopsis h[elp] [command]
? [command]
Description: The help command displays information about commands and
operands. If the command parameter is omitted, the Help window
opens and a list of commands and topics is displayed. Entering one of
the items on this list as the value for the command parameter displays
information about that item.
An alternate method of selecting an item is to double-click on the
command or topic in the Help window. This method of selection can
also be used from the help screens themselves. For example, at the
bottom of the screen for the dump command there is a section that
directs you to the display and dzero commands for additional
information. You can access the help screen for either of these
commands by double-clicking on the name of the command.
Examples help
displays a list of commands and topics.
h break
displays information about the break command.
? break
displays information about the break command.
159 Commands and Built-in Functions
hunks Lists the addresses and sizes of all hunks
Synopsis hu[nks]
Description: The hunks command displays the list of loaded hunks, their
addresses, and their sizes for the current executable file.
The following example shows the output from the hunks command:
>hunks
Hunk Address Size
0 00C32AE8 0xB54 (2900)
1 00C28570 0x27C (636)
The size is displayed first in hexadecimal format followed by decimal
format in parentheses.
Example hunk s
lists all hunks for the current executable file.
160 Chapter 9
jump Changes the current execution point
Synopsis j[ump] location
Description: The jump command updates the program counter to point to a new
location. The effect of using this command is that the code between the
previous execution point and the new location is not executed. Any
value for the location parameter that is valid for the break or go
commands can be used. It is important to note that the stack is not
modified in any way.
You should be very careful when using the j ump command because
certain registers may not be set up the way the code that is jumped to
expects. Using the j ump command is more likely to be safe if you
always jump from one C source file line to another in the same
function (not from assembly lines), and you have compiled with the
debug=symbolflush or debug=fullflush options to make sure
that registers are flushed to memory at C source line boundaries. If the
jump command is used on optimized code, the registers are not likely
to be set correctly.
Note: To avoid confusion, the jump command does not use the
default radix setting. You must specify 0x for an address; otherwise,
you will be specifying a line number. For example, even if the radix is
set to hex, the following command specifies a jump command for line
20 and not address 0x20:
j 20
Examples jump 1 2
jumps to line 12 in the current function.
jump 0x804E
jumps to the address 0x804E.
See Also env, go,
return
161 Commands and Built in Functions
list Lists the lines in a source file
Synopsis l[ist]
l[ist] $
l[ist] + | - integer [L length]
l[ist] line-range
l[ist] [image:]\module [line-range]
l[ist] [[image:]\module\lfunction [line-range]
Description: The list command is used when debugging in line mode to list the
lines in a source file. The current list line is set to the source line at
which the program being debugged is stopped each time the user
regains control.
The list command with no arguments displays lines starting with
the current list line. The number of lines displayed is controlled by the
opt list command.
The $ parameter is used to list a number of lines above and below
the current line at which the program is stopped. The number of lines
above and below is controlled by the opt context command.
The module parameter specifies the name of a module in the
program. A range of lines is specified with the line-range parameter,
which can have either of the following forms:
line-1 [[..] Iine-2]
line-1 L length
In the first form the line-range parameter specifies a range of lines
starting at line-1 and ending at line-2. In the second form a range of
lines is specified as starting at line-1 and extending for length number
of lines.
If the list command is given an environment (module or function),
then the source file for that environment is opened, if possible, and the
desired line range is displayed. If no line range is given, and no
function is given, the listing begins at line 1. If a function name is
given and no line range is given, lines are listed beginning with the
function declaration.
Each time the list command is used, the current list line is set to
the line immediately following the last listed line. Remember that the
current list line is also updated each time the client program is allowed
to execute.
Examples list
lists the next group of lines. The number of lines listed is
set by the opt list command.
162 Chapter 9
list Lists the lines in a source file
(continued)
list $
lists lines around the line pointed to by the current program
counter.
list module
lists first lines of the specified module.
list \module 20 40
lists lines 20 through 40 of the specified module.
list \module 20 L 10
lists 10 lines of the specified module starting at line 20.
list +20
starts listing lines 20 lines down from the current line.
list -20
starts listing lines 20 lines up from the current line.
list -20 L 10
lists 10 lines, starting 20 lines up from the current line.
list foo
starts listing at the declaration of the function named foo.
list foo 10 20
lists lines 10 through 20 of the function named foo.
See Also opt,
source, unassemble
163 Commands and Built-in Functions
log Logs debugger commands to a file
Synopsis lo[g] [log-command]
Description
The log command is used to save to a file a record of all activity in
the Dialog window including commands and results. Menu selections
are not saved by the log command. This information is stored in a log
file. The name of the file is set with the log f ile command. The
default filename is cpr. log.
When issued without the log-command parameter, the log command
can be used to display the current log state, either on or o f f, and the
filename of the log file. The log-command parameter can be any of the
following:
append
appends log information to the end of the log file
file filename
specifies the filename of the log file
off
closes the log file
on
opens a new log file
snap
snapshots contents of the Dialog window to the log file.
If a command that enables the logging of your session, such as log
on, log append, or log snap, is issued when logging is already
enabled, the results of the command are added to the current log file.
If the log filename is changed while logging is enabled, the current log
file is closed, and a new one is opened. The log file is automatically
closed when you exit CodeProbe.
Examples
log snap
saves the dialog for the current session into the log file named
cpr . log.
log file foo.log
sets the log file to the filename foo.log.
log on
enables the
log file.
164 Chapter 9
log Logs debugger commands to a file
(continued)
log off
disables the log file.
log append
enables the log file and appends new log information to the end of
the log file.
165 Commands and Built-in Functions
opt Shows option values or changes the value of a debugger option
Synopsis op[t]
op[t] aU[toswap] [on | off]
op[t] ar[rdim] integer
op[t] b[adchar] integer
op[t] ca[se] [on | off]
op[t] cat[ch][on | off]
op[t] co[ntext] integer
op[t] dev[ices][on | off]
op[t] e[cho] [on | off]
op[t] ib[ytes][on | off]
op[t] ig[norepath] [on | off]
op[t] l[ist] integer
op[t] rad[ix][d[ecimal] | h[ex]]
op[t] ran[gelen] integer
op[t] re[slib][on | off]
op[t] se[arch] [+ | -] director,v[, director,v [ . . . ]]
op[t] so[urce] c | a[sm] | m[ixed] | n[ext]
op[t] st[rlen] integer
op[t] t[ask] [task-ID]
op[t] u[nassemble] integer
Description
The opt command is used to show the value of debugger options or to
change them. The opt command by itself shows the current settings of
all options. The following are the options and their possible values:
autoswap
if set to on, pushes the screen containing the applications output to
the front each time control is given to the application. If set to o f f,
the application screen is not pushed to the front. The default is
off.
arrdim
controls the maximum number of array elements that are displayed
at one time with the display command. The default is 20.
badchar
controls the number of non-ASCII characters that a dzero or
display command will accept when displaying a string referenced
by a character pointer. The default is 3.
case
if set to on, causes the search command to perform case-sensitive
string
searches. The default is off.
166 Chapter 9
opt Shows option values or changes the value of a debugger option
(continued)
catch
if set to on, catches any new task generated by a task under
debugger control. The default is off.
context
controls the number of lines displayed in the Source window
preceding the current line. The default is 2.
devices
if set to on, attaches to, or catches, any new device process or task
generated by a task under debugger control. The default is off.
echo
if set to on, causes the debugger to echo all commands to the
Dialog window. This is particularly useful when using the
execute command to execute a file of debugger commands. The
default is off.
ibytes
if set to on, causes the debugger to display the instruction bytes
being disassembled. This affects the output of the unassemble
command. In windowing mode, it also affects the Source window in
mixed and asm source modes. The default is off.
ignorepath
if set to on, causes the debugger to ignore the pathname for the
source file provided by the compiler. The default is off.
list
controls the default number of lines displayed by the list
command in line mode. The default is 6.
search
defines a set of directories to search for the source code. If no + or
-- is specified, the list of directories replaces the current list.
Specifying a + at the beginning of the list appends the new list to
the end of the current list. Specifying a -- at the beginning of the
list removes the specified directories from the current list.
source
controls the display in the Source window in windowing mode.
Repeatedly choosing the next values cycles through the possible
display types in the order C, asm, and mixed. The source option
controls the output when you execute a step or go. The default is
C.
167 Commands and Built-in Functions
opt Shows option values or changes the value of a debugger option
(continued)
strlen
controls the maximum number of bytes that are displayed when a
character string is displayed with the dzero command. The default
is 128.
task
changes the current task to the task identified by the task-ID
parameter. The task-ID parameter can be either the name of a task
or the address of a task control block, as displayed by the tasks
command.
radix
sets the default input type for constants. It is used to avoid having
to type the initial 0x on hexadecimal constants. The default is
decimal.
rangelen
controls the default size of ranges when no range size information
is available. The default is 64.
reslib
if set to on, steps into resident libraries while tracing or running an
application with watch breaks. The default is off .
unassemble
controls the default number of instructions that are disassembled by
the unassemble command in line mode. It has no effect in C
mode or windowing mode. The default is 4.
Examples
opt
displays the settings of all options.
opt unassemble 10
sets unassemble count to 10.
opt search /src,/test
sets search directories.
opt search +test2
appends a new search directory.
See Also
display,dzero,list,unassemble
168 Chapter 9
proceed Single-steps over function calls
Synopsis p[roceed] [integer]
Description
In C mode, the proceed command causes the debugger to step
through the number of source statements specified by the integer
parameter. In Mixed or Asm modes, it steps through integer number
of machine instructions. If a function call is encountered, the function
is executed as if it were a single statement. If the integer parameter is
omitted, it defaults to 1.
A proceed command is performed when you press the Return key
without entering any commands in the Dialog window. The F6 key can
also be used to enter the proceed command.
Examples
proceed
steps 1 source statement in C mode or 1 machine instruction if in
Mixed or Asm modes.
proceed 5
steps 5 source statements in C mode or 5 machine instructions if in
Mixed or Asm modes.
See Also go, ps,
trace, ts
169 Commands and Built-in Functions
ps Single-steps over function calls by source line
Synopsis ps [integer]
Description
The ps command causes the debugger to single-step through the
number of C source statements specified by the integer parameter even
if mode is set to Mixed or Asm. If a function call is encountered
during stepping, the function is executed as if it were a single
statement. If the integer parameter is omitted, it defaults to 1.
Example
ps2
steps through two source lines regardless of the debugger mode.
See Also go,
proceed, trace, ts
170 Chapter 9
quit Terminates the debugger
Synopsis q[uit]
Description
The quit command terminates the debugging session and returns to
the operating system prompt.
When running in cross-development mode, the quit command only
terminates the cross debugger (CPRX) on the host machine, leaving the
kernel (CPRK) waiting for a new debug session.
Normally, CodeProbe forces the application being debugged to call
the exit function before terminating the application. The debugger
then exits. If CodeProbe was started with the -startup option, the
debugger exits without forcing the application to call exit.
Example quit
terminates the
debugging session.
171 Commands and Built-in functions
register Displays or modifies registers
Synopsis r[egister] [register [[=] expression]]
Description
If no arguments are given, the register command displays the
current contents of all the machine integer registers. If a register name
is specified by the register parameter, the contents of that register are
displayed. If an expression parameter is specified in addition to the
register parameter, the value of the expression is stored in the register.
The display and set commands can also be used to display and
modify the contents of the registers.
Examples
register
displays all registers and flags.
register dS = 30
sets register D5 to 30.
r d3 = index
sets register D3 to the value of index.
register a0 &x
sets register A0 to the value pointed to by x.
r a1
displays the value stored in register A1.
See Also display,
fregister, rflag, set
172 Chapter 9
restart Restarts the program being debugged
Synopsis res[tart] [argument-list]
Description
The restart command causes the program you are debugging to be
reloaded and executed up to the entry point of main, just as when the
debugger was first invoked. (If the -startup option was specified
when you invoked the debugger, execution will stop before the startup
code is executed and not at the first line of the main function.)
Because the program is reloaded, all static data is reinitialized. All
breakpoints will be retained and watch breaks on static and external
variables will be retained and disabled.
The argument-list parameter provides the arguments for the program
being debugged. These arguments are delimited by white space, just as
would appear on the command line when invoking the program. The
program will use these arguments as if it were invoked from the
command line with them.
The restart command cannot be used with the -command
command-line option or as one of a sequence of commands separated
by semicolons. When used, the restart command must occur at the
end of a command line.
The restart command potentially can cause your machine to crash
if used improperly. When you enter the re s tart command, your
application is immediately reloaded and re-executed with no cleanup of
your currently running program other than calling the exit function
to close files. This can leave the machine in an unacceptable state that
can cause problems later. To avoid this problem, be sure to allow your
application to run to completion if possible and do any necessary
cleanup before issuing the restart command.
The start and restart commands are the same if the same
arguments are provided by the argument-list parameter. The significant
difference between the two commands is their behavior when they are
specified with no arguments. The start command restarts the
program without any arguments; however, the restart command
with no arguments restarts the program with the original arguments
used when the
debugger was invoked.
173 Commands and Built-in Functions
restart Restarts the program being debugged
(continued)
Examples
restart
restarts the program using the same arguments with which it was
initially invoked.
restart myfile.txt 5
restarts the program passing it two arguments: myfile.txt and
5
restart "sample string"
restarts the program passing in a string as an argument.
See Also start
174 Chapter 9
return Returns immediately from the current function
Synopsis ret[urn] [expression]
Description
The return command causes the current function to return to its
caller without executing the rest of the function.
The value of the expression parameter is used as the return value
from the function. The value is converted to the appropriate type if
necessary; however, it must be a scalar quantity (not a structure or
union).
An attempt to return a value from a function declared void is
treated as an error, and a suitable message is displayed. Similarly, an
error message is displayed if you use a simple return command
(without a parameter) from within a function declared as having a
return value. In all other cases, the return value is cast (if necessary)
to the correct type and returned to the calling function.
When a return command is given, the current function is returned
immediately to the calling function. The return value, if any, is
returned to the calling function, and execution is suspended as though
a breakpoint were triggered in the calling function after the call was
made. For instance, note the following code fragment:
i = 5;
j = func(i);
if (j < 2)
j++ ;
Assume that the return command is issued during the execution of
func in the form ret 7. Execution stops inside the line that did the
call, just before the assignment to j. You can then single-step to the
next statement.
Examples
return stringptr
returns the value of stringptr.
ret 5
returns an integer value of 5.
return
returns from a
void function.
175 Commands and Built-in Functions
rflag Displays or modifies flags
Synopsis rf[lag] [flag ...]
Description
The rflag command can be used to display or modify the settings of
the machine flags. If no parameters are specified, the current settings
of the flags are displayed. With one or more arguments, the indicated
flags are set or cleared according to the values given. The flag names
are specific to the target machine.
A flag setting can be one of the terms in the following table. The Set
column comprises the terms used to set flags, while the Clear column
comprises the terms used to clear flags.
Flag Name Set Clear
Overflow (yes/no) OV NV
Sign (negative/positive) NG PL
Zero (yes/no) ZR NZ
Auxiliary Carry (yes/no) AC NA
Carry (yes/no) CY NC
Examples
rflag
displays all registers and flags.
rflag cy
sets the carry flag to 1.
See Also
fregister, register
176 Chapter 9
search Searches for a string in the current source file
Synopsis sea[rch] [string]
Description
The search command searches the current source file for the
specified string. In windowing mode, the search begins from the top
line of the current Source window. In line mode, the search begins at
the first line that would be displayed if a list command were entered
with no arguments.
In windowing mode, the cursor is positioned at the beginning of the
matching string. The Source window is also repositioned so that the
line containing the match is the number of lines specified by the
context option from the top of the window. The context is set by
the opt command.
In line mode, the line containing the match is displayed.
The search command with no arguments causes the debugger to
search for the string specified in the last search argument, starting
from the new current line. If no matches are found, a message is
printed. If the user then enters search again, the search is resumed
beginning at the top of the file. The case-sensitivity option, opt case,
determines whether the search is case sensitive or not.
Examples
search foo
finds the string "foo".
search foo;
finds the string "foo". The semicolon used in this command is a
command delimiter and is not considered part of the search string.
search foo\;
finds the string "foo;" . The escape character (\) causes the
semicolon to be part of the search string.
search
repeats the last search.
See Also opt, list
177 Commands and Built in Functions
set Modifies the values of variables or memory locations
Synopsis se[t] (variable | register) = expression
se[t] address [=] string
Description
The set command is used to modify the values of variables, registers,
or memory locations in the program being debugged.
You are most likely to use the first form of the set command in
debugging C programs. It allows you to change the value of a variable
in your program by referring to that variable by name. In this context,
variable has a rather broad sense that includes references to array
elements, structure members, and indirect references.
The variable parameter cannot refer to an aggregate such as a
structure, union, or array.
The register parameter can be any valid register name, D0 through
D7 and A0 through A7, and if a co-processor is present, FP0 through
FP7. A $ prefix optionally may be used to distinguish the register from
a variable of the same name.
The expression parameter is the same as used in the C assignment
statement.
If necessary, the value for variable will be converted to the proper
type in accordance with the normal C conversion rules; it is then
entered into memory at the address of the first variable operand. This
is similar to a C assignment statement for a scalar variable.
The second form shown in the synopsis is used to store a string into
memory. The null terminator is not copied unless it is explicitly
present in the string. The equal sign is optional. Support for this form
of set command may be removed in future releases. The built-in
strcpy and memcpy functions are preferred.
Examples
set i = 5
sets the variable i equal to the integer value 5.
set a = 3.1415
sets the variable a equal to the floating-point value 3.1415.
set $d0 = 300
sets register D0 equal to 300. The $ is optional.
set time->date = newtime
sets the date member of the time structure equal to the value of
the variable newtime.
set stringptr "this string has no null byte"
stores a string that is not null-terminated to the memory location
pointed to by
stringptr.
178 Chapter 9
set Modifies the values of variables or memory locations
(continued)
set stringptr "this string has a null byte\0"
stores a null-terminated string to the memory location pointed to by
stringptr.
set stringptr "string one\0string two\0"
stores two null-terminated strings to the memory location pointed to
by stringptr.
See Also fregister,memcpy,strcpy,register
179 Commands and Built-in Functions
sleep Pauses for the time specified
Synopsis sle[ep] number
Description
The sleep command pauses for the number of seconds specified by
the number parameter.
Example sleep 10
pauses for 10
seconds.
180 Chapter 9
source Displays the source file
Synopsis so[urce] [filename]
Description
The source command overrides the C source file associated with the
current module. The specified value for filename replaces the filename
associated with the module for the rest of the current debugging
session. The new file is displayed in the Source window immediately,
and its name is echoed in the Dialog window.
If no filename parameter is specified, the name of the current source
file is echoed in the Dialog window but the current source file is not
changed.
If the filename you want to change to is the same as the default
filename but the path is different, you can use the opt search
command instead of the source command to change the locations that
CodeProbe looks for source files.
Examples
source
displays the current filename.
source test/test1.c
changes the filename for the current module to test1.c in the
test directory.
See Also opt
181 Commands and Built-in Functions
start Restarts the program being debugged
Synopsis sta[rt] [argument-list]
Description
The start command causes the program you are debugging to be
reloaded and executed up to the entry point of main, just as when the
debugger was first invoked. (If the -startup option was specified
when you invoked the debugger, execution will stop before the startup
code is executed and not at the first line of the main function.)
Because the program is reloaded, all static data are reinitialized. All
breakpoints are retained and watch breaks on static and external
variables are retained and disabled.
The argument-list parameter provides the arguments for the program
being debugged. These arguments are delimited by white space, just as
would appear on the command line when invoking the program. The
program will use these arguments as if it were invoked from the
command line with them.
The start command cannot be used with the -command
command-line option or as one of a sequence of commands separated
by semicolons. When used, the start command must occur at the
end of a command line.
The start command potentially can cause your machine to crash if
used improperly. When you enter the start command, your
application is immediately reloaded and re-executed, with no cleanup
of your currently running program other than calling the exit
function to close files. This can leave the machine in an unacceptable
state that can cause problems later. To avoid this problem, be sure to
allow your application to run to completion and do any necessary
cleanup before issuing the start command.
The start and restart commands are the same if the same
arguments are provided by the argument-list parameter. The significant
difference between the two commands is their behavior when they are
specified with no arguments. The start command restarts the
program without any arguments; however, the restart command
with no arguments restarts the program with the original arguments
used when the
debugger was invoked.
182 Chapter 9
start Restarts the program being debugged
(continued)
Examples
start
restartsthe program being debugged without passing it any
arguments.
start myfile.txt 5
restarts the program being debugged passing in the arguments
myfile.text and 5.
See Also restart
183 Commands and Built-in Functions
symbol Finds the symbol nearest to the specified address
Synopsis symb[ol] address
Description
The symbol command causes the debugger to search the symbol
information and display the name of the symbol whose location is
closest to the address specified by the address parameter.
Example symbol 0x8040
displays the symbol whose address is nearest to 0x8040.
See Also symload
184 Chapter 9
symload Reads symbol information from an executable file
Synopsis sym[load] executable file
sym[load] proc process-id
sym[load] seg address executable-file
Description
The symload command associates an executable file and any
debugging information found in that file with a loaded image.
If given the filename of an executable-file, the symload command
associates that file with the current hunk list.
If the proc keyword is used, followed by the name of a process that
is identified by the process-id parameter, the symload command
attempts to map the segment list for the process with its executable
file.
If the seg keyword is specified along with an address and the
filename of an executable file, the symload command treats the
address as a pointer to a BCPL segment list and it maps the list to the
executable file.
Examples
symload myapp
reads the current segment list and symbols from the file named
myapp.
sym proc myapp
reads the segment list and executable file for process myapp.
symload proc 0xC85428 myapp
reads the segment list and executable file for the process located at
0xc85428.
symload seg 0xC84200 myapp
uses the segment list at address 0xC84200.
See Also hunks
185 Commands and Bui1t-in Functions
tasks Displays system tasks
Synopsis ta[sks] [a[ll]]
Description
The tasks command displays information about tasks. By default, it
displays the tasks currently under debugger control. If the all option
is specified, all system tasks are displayed.
The opt task command can be used to change to a new task.
Examples
tasks
displays a listing of all tasks under debugger control.
ta all
displays a listing of all tasks in the system.
See Also
activate, catch, deactivate, detach, opt
186 Chapter 9
trace Single-steps into function calls
Synopsis t[race] [integer]
Description
In c mode, the trace command steps the number of source
statements specified by the integer parameter. In Mixed or Asm
modes, it steps the number of machine instructions specified by the
integer parameter. If a function call is encountered, stepping continues
into that function. If the integer parameter is omitted, trace will step
one line.
Examples
trace
steps one source statement if in C mode, or one machine instruction
if in Mixed or Asm mode.
t 5
steps five source statements or machine instructions.
See Also go,
proceed, ps, ts
187 Commands and Built-in Functions
ts Single-steps by source line into function calls
Synopsis ts [integer]
Description
The ts command is similar to the trace command in that it will step
into functions encountered during execution. It is different in that ts
will only step by C source line, even if the source mode is set to Asm
or Mixed. The integer parameter specifies the number of C source
lines to step. If no parameter is specified, ts will step one line at a
time.
Examples
ts
steps one source line regardless of the mode the debugger is in.
ts 2
steps two source lines.
See Also
proceed,ps,trace
188 Chapter 9
unalias Deletes an alias
Synopsis una[lias] name
una[lias] *
Description
The unalias command removes entries from the debugger's list of
aliases. The name parameter refers to any alias name. You can use the
* parameter as a wildcard character to remove all aliases.
Examples
unalias foo
deletes the alias for foo.
una *
deletes all aliases.
See Also alias,
define, undefine
189 Commands and Built-in Functions
unassemble Displays memory as assembler instructions
Synopsis u[nassemble] [location-1 [location-2]]
Description
The unassemble command displays the range of memory from
location-1 to location-2 in assembler format.
By default, the command begins disassembling at the current
program counter. If subsequent unassemble commands are
performed before the application is given control by a trace,
proceed, or go command, it will continue disassembling from the
point at which it finished the last invocation.
If source line number information is available for the range of
memory being disassembled, unassemble will display the C source
line before displaying the corresponding instructions. It will display the
number of assembler instructions generated for one C source line.
If no source information is available for the range of memory being
displayed, unassemble will display the default number of
instructions as specified by the unassemble default item in the
Options menu. By default this number is 4 instructions.
The output of the unassemble command is equivalent in format to
assembler mode output displayed in the Source Window. It will consist
of three or four columns depending on the setting of the instruction
bytes option, which is controlled by the opt ibytes command. (See
Chapter 4, "Setting Up the Debugging Environment," for more
information about setting instruction bytes.) The following is an
example of unassemble output with instruction bytes on and source
unavailable:
> unassemble
0x25F950 48E70130 MOVEM.L D7/A2-A3,-(A7)
0x25F954 BFEC0004 CMPA.L 0004(A4),A7
0x25F958 65001BD6 BCS 00261530
The first field contains the hexadecimal address of the instruction
being disassembled. The second field is a hexadecimal dump of the
actual bytes composing the instruction. The third field consists of the
M680X0 mnemonic for the given opcode. The fourth field consists of
the operands to the instruction. If the instruction bytes option is
turned off, the second field is not displayed.
Examples
unassemble \modl\func1 10
unassembles line 10 of func1 in mod1.
unassemble 13 14
unassembles
lines 13 to 14.
190 Chapter 9
unassemble Displays memory as assembler instructions
(continued)
unassemble func1
unassembles the first line of func1.
unassemble func1 func2
unassembles from &func1 to &func2.
unassemble
continues unassembling at the last location.
SeeAlso opt, list
191 Commands and Built in Functions
undefine Deletes a macro definition
Synopsis [#]und[efine] name
[#]und[efine] *
Description
The undef ine command removes entries from the debugger's list of
macro definitions. The name parameter specifies the name of the macro
to removed. You can use the * as a wildcard character to remove all
macro definitions. The # sign can be inserted before the undef ine
command so that C header files (.hfiles) can be read by CodeProbe.
Examples
#undef foo
deletes the macro named foo.
undefine *
deletes all macros.
See Also alias,
define, execute, unalias
192 Chapter 9
watch Sets a watch on a variable or memory
Synopsis w[atch] expression | range [s[tatic] | d[ynamic]]
Description
The watch command is used to set a watch for the expression or
memory range specified. Whenever control is returned to the user, for
example by stepping or stopping at a breakpoint, the new value of the
watched object is displayed in the Watch window. The Watch window
can be opened with the View menu, the window command, or by
pressing F1.
In line mode, the object is not automatically displayed. You must use
the w list command to display it.
The watch command does not cause the debugger to stop execution
when the value being watched changes; it just displays the changed
value. Use the wbreak command to cause the debugger to stop when
a value is changed.
By default, watches are dynamic; that is, the expression being
watched is re-evaluated whenever control returns to the debugger. The
static option causes the watch expression to be evaluated once,
when the watch is set. The result is treated as an address whose
contents are displayed.
Examples
watch text->len
sets a watch for the symbolic scalar text->len.
w \mod\f1\a[0] L 20
sets a watch for a length of 20 bytes starting at the symbolic range
specified by \mod\f1\a[0].
w &a[0] .. &a[5]
sets a watch for the range from &a[0] to &a[5].
watch tmp[i] static
if i = 3, watches tmp [3] regardless of changes to i.
See Also
wbreak,wclear,wdisable,wenable,wlist
193 Commands and Built-in Functions
wbreak Sets a watch break
Synopsis wb[reak] expression | range [s[tatic] | d[ynamic]]
Description
The wbreak command sets a watch break for the expression or
memory range specified. Whenever any byte in a specified range is
modified, control is returned to you.
By default, watch breaks are static; that is, the expression is
evaluated once when the watch break is set. The address result of the
expression is then monitored by the watch break.
The dynamic option indicates that the watch break expression or
range should be re-evaluated whenever control returns to the
debugger.
Examples
wbreak text->len
sets a watch break for the symbolic scalar text->len.
wb \mod\f1\a[0] L 20
sets a watch break for a length of 20 bytes starting at the symbolic
range specified by \mod\f1\a[0].
wbreak &a[0].. &a[5]
sets a watch break for the range from &a[0] to &a[5].
wb p->q dynamic
sets a watch break for different locations depending on the value of
p.
See Also watch,
wclear, wdisable, wenable, wlist
194 Chapter 9
wclear Clears one or more watches
Synopsis wc[lear] integer [integer . . . ]
wc[lear] * | l[ast]
wc[lear] integer .. integer
Description
The wclear command is used to clear one or more watches or watch
breaks. When a watch is cleared it ceases to exist and can be
reinstated only by issuing the watch or wbreak command again. You
can use the wdisable command to temporarily disable a watch.
The integer parameter specifies the number of a watch as displayed
by the wlist command. Any number of integer values can be
specified as parameters to the wclear command.
The * parameter specifies that all watches and watch breaks should
be cleared.
You can specify that all watches and watch breaks between two
watch numbers be cleared by using the form integer . . integer.
The last parameter can be specified to clear the last watch or
watch break that was set.
Examples
wclear 2 5 6
clears watches or watch breaks numbered 2, 5, and 6.
wclear last
clears the last watch or watch break set.
wc *
clears all watches or watch breaks.
wc4..7
clears watches 4, 5, 6, and 7.
See Also watch, wbreak, wclear, wdisable, wlist
195 Commands and Built-in Functions
wdisable Disables one or more watches
Synopsis wd[isable] integer [integer ...]
wd[isable] * | l[ast]
wd[isable] integer .. integer
Description
The wdisable command is used to disable the recognition of one or
more watches or watch breaks. When a watch or watch break is
disabled, it is no longer recognized, but it remains on the current list
of watches. A wenable command can be used to re-enable a watch or
watch break that has been disabled with the wdisable command.
The integer parameter specifies the number of a watch, as displayed
by the wlist command. Any number of integer values can be
specified as parameters to the wdisable command.
The * parameter specifies that all watches and watch breaks should
be disabled.
You can specify that all watches and watch breaks between two
watch numbers be disabled by using the form integer . . integer.
The last parameter can be specified to disable the last watch or
watch break that was set.
Examples
wdisable 2 5 6
disables watches or watch breaks numbered 2, 5, and 6.
wdisable last
disables the last watch or watch break set.
wdisable *
disables all watches or watch breaks.
wdisable 4..7
disables watches 4, 5, 6, and 7.
See Also watch, wbreak, wclear, wenable, wlist
196 Chapter 9
wenable Enables one or more watches
Synopsis we[nable] integer ...
we[nable][*] | l[ast]
we[nable]integer .. integer
Description
The wenable command is used to enable the recognition of one or
more watches or watch breaks that have been disabled by the
wdisable command.
The integer parameter specifies the number of a watch, as displayed
by the wlist command. Any number of integer values can be
specified as parameters to the wenable command.
The * parameter specifies that all watches and watch breaks should
be enabled.
You can specify that all watches and watch breaks between two
watch numbers be enabled by using the form integer . . integer.
The last parameter can be specified to enable the last watch or
watch break that was set.
Examples
we 2 5 6
enables watches or watch breaks numbered 2, 5, and 6.
we last
enables the last watch or watch break set.
wenable *
enables all watches or watch breaks.
we 4..7
enables watches 4, 5, 6, and 7.
See Also watch,
wbreak, wclear, wdisable, wlist
197 Commands and Built-in Functions
whatis Determines the type of an object
Synopsis wha[tis] expression
wha[tis] (type)
Description
The whatis command displays the type, location, and storage class of
an object, or gives additional information about a data type.
If an expression is given, whatis displays the C data type of the
expression. If the result of the expression is a simple variable or a
member of an array, whatis displays the address of the object and
identifies it as either static, extern, or automatic. If the result
of the expression is a function, whatis displays the address of the
function, its return type, and its location.
If a parenthesized type is given, including types that are defined by a
typedef statement, whatis displays the full definition for the type.
For struct, union, and enum types this means all members of the
aggregate are displayed; for a type that has been defined by a
typedef statement, this means the base type of the typedef is
displayed. Using the whatis command on basic C data types such as
int or long is allowed, but it is not very useful.
Examples
whatis i
determines the type of a variable named i.
wha main
determines the type, address, and defining module for the main
function.
wha 3.5
determines the type of a constant.
whatis Red
determines the type of an enumeration constant.
wha *p->c[3]
determines the type of the expression *p- >c [3].
whatis (int) (1*3.4)
determines the type of an expression with a type cast.
whatis (node)
determines the type of a typedef.
whatis (struct X)
displays the
members of s truct X.
198 Chapter 9
where Shows the calling sequence
Synopsis whe[re] [a[rgs]] [integer]
Description
The where command displays a backtrace of the function calls in the
call sequence. Calls are listed in reverse order beginning with the most
deeply nested function.
The args option causes the where command to display the
arguments to each function in a manner similar to the args
command.
The integer parameter specifies the number of calls to be displayed.
By default, only the 20 most recent calls are printed.
Here is an example of the output from the where command:
> 1 In routine fpreg.o:\fpreg.c\five 48
> 2* Called from fpreg.o:\fpreg.c\six 68 (+0xE)
> 3 Called from fpreg.o:\fpreg.c\seven 82
> 4 Called from fpreg.o:\fpreg.c\main 92
> ...
The numbers on the left indicate a level number that can be passed to
the env command. Level 1 is defined to be the function in which you
are currently stopped or the run environment. The caller's level is 2,
its caller is 3, and so on. These level number designations change over
time as the program steps into and returns from functions. The
asterisk indicates the current user environment as set by the env
command.
The Calls window also displays this information.
Examples
whe
displays a list of the last 20 function calls.
where S
displays a list of the last 5 function calls.
where a
displays the arguments to each function.
See Also args, env
199 Commands and Built-in Functions
window Opens or closes a window
Synopsis wi[ndow] window-name [on | off]
Description
The window command is used to open and close a specified window.
Any of the following values can be specified as the window-name
parameter:
c[alls] mo[dules] w[atch]
he[lp] ms[g] s[ource]
me[mory] r[egister]
If the window command is invoked with only a window-name
parameter, the command acts as a toggle for the specified window;
thus, if the window is currently opened, the window command will
close it, and if it is currently closed it will be opened.
If on or off is specified, the window is forced into that state,
regardless of its current state. If a window that is already open is set
to on, it will pop to the top of the window hierarchy.
The window command is ignored in line mode.
Examples
wi register
toggles the Register window.
window help on
opens the Help
window or pops it to the top.
200 Chapter 9
wlist Lists all watches
Synopsis wl[ist]
Description
The wlist command lists all watches and watch breaks. Disabled
watches are marked with an asterisk. Watch breaks are distinguished
from regular watches by an exclamation mark. The value associated
with the watch is displayed if available.
Example w list
lists all watches.
See Also watch,
wbreak, wclear, wdisable, wenable
201 Commands and Built-in Functions
wmsg Writes a message to the Message window
Synopsis wmsg integer message-text
Description
The wmsg command is used to write the text specified by the
message-text parameter in the Message window. The integer parameter
specifies the location in the window for the text. Line 0 is the top line.
This command is used primarily with debugger or AREXX scripts.
Examples wmsg 0 --- This is the Message window. ---
displays the string --- This is the Message window. ---
on the top line of the Message window.
wmsg 12 This goes on line 12.
displays the string This goes on line 12. on line 12 of the
Message window.
202 Chapter 9
Built-in Functions
As described in Chapter 3, "Debugging Your Program", built-in
functions are standard, commonly used functions recognized by the
compiler and expanded inline for efflciency. The SAS/C Compiler
defines several built-in functions that are described in Chapter 4,
"Using the System Header Files to Access Libraries," of the SAS/C
Development System Library Reference.
CodeProbe also defines several built-in functions. These functions are
related to the library built-in functions in that several of them share
the same names and the same functionality. The CodeProbe built-in
functions are provided for the following reasons:
[] for use with the call and display commands. Since the built-in
functions provided with the compiler generate in-line code, these
commands would not be able to access them.
[] to add convenience and functionality. CodeProbe's built-in functions
provide functionality not available through other debugger
commands.
The compiler's built-in functions perform in accordance with the
ANSI C standards. This may be slightly different from what
CodeProbe's built-in functions do. For example, passing NULL to a
built-in function is an error in CodeProbe. Overlapping memory blocks
may be handled differently. Also, the parameters to CodeProbe's
built-in functions are a little more flexible than the parameters to the C
versions:
formal type actual parameter types allowed
void * constant, register, any pointer scalar,
array, function, address, string
constant
char * constant, register, character pointer,
unsigned character pointer, character
array, string constant
int constant, register, any integral scalar,
bitfield, enumerated constant
Floating-point constants and registers are not allowed, and string
constants can
only be specified as the source operand.
203 Commands and Built-in Functions
Built-in Function Reference
This section describes the following built-in functions:
memcmp compares two memory blocks
memcpy copies a memory block (non-overlapping)
memmove copies a memory block (possibly overlapping)
memset sets memory to a specified value
strcat concatenates two strings
strcmp compares two strings
strcpy copies a string
strlen returns the length of a string.
204 Chapter 9
memcmp Compares two memory blocks
Synopsis i = memcmp ( a, b, n );
int i; /* comparison results */
void *a, *b; /* blocks being compared */
int n; /* block size in bytes */
Description
The memcmp function compares two memory blocks and returns a
value whose sign indicates the collating sequence of the blocks, as
follows:
Return Meaning
Negative First block below the second
Zero Blocks are equal
Positive First block above the second
CodeProbe has a built-in #define that causes all references to
memcmp to be referenced to __builtin_memcmp, which is the
actual name of the CodeProbe function. If you want to step into or call
an actual function called memcmp in your code, you should use the
undef ine command to clear the define or use the backtick character
to escape the function's name.
Example
display memcmp(ptr1, ptr2, n)
displays the result of comparing ptr 1 and ptr2 for n bytes.
b 27 when(memcmp(ptr1, ptr2, 10) < 0)
breaks at line 27 when the 10 bytes pointed to by ptr 1 evaluate to
a value less than the value of the 10 bytes pointed to by ptr2.
See Also memcpy,
memmove, memset
205 Commands and Built-in Functions
memcpy Copies a memory block (non-overlapping)
Synopsis to = memcpy(to, from, n);
void *to; /* destination pointer */
void *from; /* source pointer*/
int n; /* block size in bytes */
Description
The memcpy function copies data from one memory block to another.
The destination pointer is returned.
The memcpy function cannot be used to copy overlapping memory
blocks. You should use the memmove function when copying
overlapping blocks. Also note that you can crash your machine if there
is not enough memory to hold the data at the destination memory
location.
CodeProbe has a built-in #define that causes all references to
memcpy to be referenced to __builtin_memcpy, which is the
actual name of the CodeProbe function. If you want to step into or call
an actual function called memcpy in your code, you should use the
undef ine command to clear the define or use the backtick character
to escape the function's name.
Example
call memcpy(ptr1, &j, 10)
copies 10 bytes from ptr2 to ptr1.
call memcpy(0x804a, myptr, 50)
copies 50 bytes from myptr to location 0x804a.
b 27 (memcpy(a0, a1, 15)]
sets a breakpoint at line 27 with an action to copy 15 bytes from
the memory pointed to by register A1 to the memory pointed to by
register A0.
See Also memcmp,
memmove, memset
206 Chapter 9
memmove Copies a memory block (possibly overlapping)
Synopsis to = memmove(to, from, n);
void *to; /* destination pointer */
void *from; /* source pointer*/
int n; /* block size in bytes */
Description
The memmove function copies data from one memory block to another.
Overlapping blocks are handled correctly. The destination pointer is
returned.
Note that you can crash your machine if there is not enough
memory to hold the data at the destination memory location.
CodeProbe has a built-in #define that causes all references to
memmove to be referenced to __builtin_memmove, which is the
actual name of the CodeProbe function. If you want to step into or call
an actual function called memmove in your code, you should use the
undef ine command to clear the define or use the backtick character
to escape the function's name.
Example
call memmove(ptr1, &j, 10 )
copies 10 bytes from ptr2 to ptr 1.
call memmove(0x804a, myptr, 50)
copies 50 bytes from myptr to location 0x804a.
b 27 {memmove(a0, a1, 15)}
sets a breakpoint at line 27 with an action to copy 15 bytes from
the memory pointed to by register A1 to the memory pointed to by
register A0.
See Also memcpy,
memcmp, memset
207 Commands and Built-in Functions
memset Sets memory to a specified value
Synopsis to = memset(to , c , n );
void *to /* base of memory to be initialized */
int c; /* initialization value */
int n; /* number of bytes to be initialized */
Description
The memset function sets the specified number of bytes of memory to
the specified value.
Note that you can crash your machine if there is not enough
memory to hold the data at the destination memory location.
CodeProbe has a built-in #define that causes all references to
memset to be referenced to __builtin_memset, which is the
actual name of the CodeProbe function. If you want to step into or call
an actual function called memset in your code, you should use the
undef ine command to clear the define or use the backtick character
to escape the function's name.
Example
call memset(ptr, 0, 100)
sets 100 bytes to 0 starting at the address pointed to by ptr.
call memset(a0, 'X', 50)
sets 50 bytes to the ASCII character X starting at the address
pointed to by register A0.
See Also memcpy,
memcmp, memmove
208 Chapter 9
strcat Concatenates two strings
Synopsis to = strcat(to, from);
char *to; /* destination pointer */
char *from; /* source pointer*/
Description
The strcat function copies data from one string to the end of
another string until a null character is found. Overlapping strings are
not handled by the strcat function.
Note that you can crash your machine if there is not enough
memory to hold the string at the destination memory location.
CodeProbe has a built-in #define that causes all references to
strcat to be referenced to __builtin_strcat, which is the
actual name of the CodeProbe function. If you want to step into or call
an actual function called strcat in your code, you should use the
undefine command to clear the define or use the backtick character
to escape the function's name.
Example call strcat(myptr, "foo")
concatenates the string "foo" after the string pointed to by the
variable myptr.
See Also strlen,
strcmp, strcpy
209 Commands and Built-in Functions
strcmp Compares two strings
Synopsis i = strcmp(a, b);
nt i; /* comparison result */
char *a, *b; /* strings being compared */
Description
The strcmp function compares two strings and returns a value whose
signs indicate the collating sequence of the blocks as follows:
Return Meaning
Negative First string below the second
Zero Strings are equal
Positive First string above the second
CodeProbe has a built-in #define that causes all references to
strcmp to be referenced to __builtin_strcmp, which is the
actual name of the CodeProbe functioll. If you want to step into or call
an actual function called strcmp in your code, you should use the
undefine commalld to clear the define or use the backtick character
to escape the functioll's name.
Example
display strcmp("abc", ~def")
tests the strings "abc" and "def" and displays the return value.
The value indicates whether the strings are equal or which string is
higher.
break myfunc when(strcmp(arg, "foobar") == 0)
breaks at the furlction myfunc when the variable arg points to the
string "foobar".
See Also
strlen,strcpy,strcat
210 Chapter 9
strcpy Copies a string
Synopsis to = strcpy(to, from);
char *to; /* destination pointer */
char *from; /* source pointer */
Description
The strcpy function copies data from one string to another until a
null character is found. Overlapping strings are not handled by the
strcpy function.
Note that you can crash your machine if there is not enough
memory to hold the string at the destination memory location.
CodeProbe has a built-in #define that causes all references to
strcpy to be referenced to __builtin_strcpy, which is the
actual name of the CodeProbe function. If you want to step into or call
an actual function called strcpyin your code, you should use the
undefine command to clear the define or use the backtick character
to escape the function's name.
Example call strcpy(a, b)
copies the string pointed to by b to the memory location pointed to
by a.
See Also strlen,
strcmp, strcat
211 Commands and Built-in Functions
strlen Returns the length of a string
Synopsis len = strlen( s );
int len; /* length of string s */
char *s; /* string to scan for length */
Description
The strlen function returns the length of a string, as determined by
the index of the first null character found.
CodeProbe has a built-in #define that causes all references to
strlen to be referenced to __builtin_strlen, which is the
actual name of the CodeProbe function. If you want to step into or call
an actual function called strlen in your code, you should use the
undefine command to clear the define or use the backtick character
to escape the function's name.
Example
display strlen( "hello" )
displays the length of the string "hello", which is 5.
display strlen(0x804a)
displays the length of the string starting at address 0x804a.
See Also strcmp,
strcpy, strcat
212
213
Part 2
Using the SAS/C
Utilities
Chapter 10 Utility Reference
214
215
10 Utility Reference
This chapter describes the utilities included with the SAS/C
Development System. The utilities are described in alphabetical order.
The description of each utility includes each of the following sections,
if applicable:
Synopsis shows the format of the command that invokes the
utility
Description describes what the utility does and contains all the
information you need to use the utility
Example contains examples that illustrate how to use the
utility
Error Messages describes the error messages, if any, produced by
the utility and the action required to fix the error.
216 Chapter 10
cover Analyzes coverage data
Synopsis cover [options] [datafile]. . .
Description
The cover utility analyzes the coverage data produced when you
compile your program with the coverage option, link with the object
file covutil.o, and run your program. Using this data, you can
determine which lines of code in your program were executed and
which were not. This information can help you design test cases that
exercise all paths through your program.
When you run your program, it writes coverage data to the file
cover . dat in the current directory. If this file does not exist, your
program creates it. If this file already exists, your program reads in
the existing cover.dat, merges in the new coverage data, and writes
the merged data back to cover.dat.
This utility analyzes the coverage data file, locates your C source
files, and produces new output files containing a copy of your C source
with arrows pointing to lines that generated code that was not
executed. Ihe output file has the same basename as the C source file,
but with the extension .cov instead of .c.
By default, cover looks for the coverage data file cover . dat in
the current directory. If you choose to rename cover.dat, you must
specify datafile when you run cover.
Your program must adhere to the following rules:
[] The main routine must be called main rather than _main because
covutil.o replaces _main with an enhanced version.
[] Your program must end by calling exit or by falling through the
end of main. (Do not call XCEXIT or abort, for example.)
[] Your prograrn must not be a resident library or device.
To use cover, follow these steps:
1. Compile your program with the coverage and debug=line
options. (You can use a higher debug level if you like.) I)o not
specify the nostdio option. Specifying coverage slows down
your program considerably, so do not specify coverage for
production software. You can choose to compile only certair
modules with coverage to reduce overhead.
2. Link your compiled program with covutil.o. This file is
located in sc:examples/cover. The covutil.o file replaces
the main and _exit functions in your program with enhallced
versions that can constrllct and write out the coverage data.
3. Run your program normally to create cover.dat.
4. Run the cover
utility.
217 Utility Reference
cover Analyzes coverage data
(continued)
The cover utility supports the following options:
dir =directory-pathname
specifies the directory path or paths to search to locate the C source
files. The coverage data contains the name of the C source file, but
not its directory. If the C source file is not in the current directory,
specify the dir= option with the proper directory as its argument.
To specify multiple pathnames, separate each pathname with a plus
(+) sign or a comma (,). Also, you can specify dir= as many times
as necessary.
merge filename
tells cover to read the specified data files, merge the information
contained in them, and write the merged data to filename. If you
specify merge, cover does not look for C source files and does not
produce a report. This option allows you to combine the results of a
suite of tests to determine what code is exercised by the test suite as
a whole.
nosource
tells cover not to read in the C source files. Instead, it prints a
report to the Shell window listing the names of all source files and
the lines in each file that were not executed.
Example
To analyze the coverage of the lines.c program, open a Shell and
use the cd command to change to the sc:examples/lines drawer.
Enter the following command:
sc lines.c sc:examples/cover/covutil.o coverage debug=line link
The compiler produces a program called lines. Run this program
with no command-line options:
lines
Watch the lines for a few seconds, then click on the close gadget to
terminate the program. The program produces a file called cover.
dat. Run the cover utility on this file:
cover
218 Chapter 10
cover Analyzes coverage data
(continued)
The cover utility reads cover .dat and lines.c and writes the
file lines.cov. Use your editor to examine lines.cov. Lines that
were not executed are highlighted with an arrow (==>) in the left
margin.
219 Utility Reference
diff Determines the differences between two files
Synopsis diff[>destination] loptions] file1 file2
Description
The diff utility determines the differences in contents between two
files and describes the lines that you should delete from, add to, or
change in file2 to make it look like file1. To help you find those lines,
diff identifies the line numbers and gives the text of the lines.
If you enter the diff command without specifying filenames, diff
displays the version that you are using and describes the options
available.
Output from this utility is sent to the standard output device, unless
you redirect it by specifying the -o option or by entering a greater
than (>) sign followed by a destination.
diff supports the following options:
-bnn sets the size of the I/O buffer to the value specified by nn. The
default I/O buffer size is 4K, and the maximum size is limited
by the amount of available system memory. Increasing the size
of the I/O buffer makes diff run faster.
-c displays only those lines common to both files.
-Fnn sets the column number where you want diff to begin
comparing lines. For example, if you set nn to 25, diff
ignores the first 25 characters on each line.
-Lnn sets the column number where you want diff to stop
comparing lines. For example, if you set nn to 75, diff
ignores the characters beyond column 75 on each line.
-lnn defines the number of lines, nn, per file that can be handled
by diff. diff uses two tables (one for each file) to keep
track of the lines read in from each file. The default size of
each of these tables is 2000; the maximum number is limited
by memory availability. If diff is running out of memory
and your files are less than 2000 lines in length, you can use
this option to increase the amount of memory available, or
you can check to see if any other tasks are running
concurrently and shut down any unwanted tasks.
-ofile sends the output to the specified file (or device). You can use
this option instead of the AmigaDOS redirection command.
You can send the output to a different device by specifying the
device name. For example, to send output to the printer,
specify -oprt: . To send output to a file on drive df0:,
specify
-odf0:filename.
220 Chapter 10
diff Determines the differences between two files
(continued)
-p filters out unprintable characters from the input stream. You
can use this option to clean out an AmigaDOS binary file.
-q suppresses any messages if there are no differences between
the specified files.
-w ignores differences related solely to space or tab characters
and reduces sequences of these characters to a single space.
This option also removes trailing blanks. When you specify the
-w option, diff uses additional memory to create a third
table for each line in its compressed form.
Note: The appendix, "diff File-Matching Algorithm," discusses
the theory of file matching and how it affects diff .
To compare the two files, newfile and oldfile, you enter the
following command:
diff newfile oldfile
diff compares the two files and gives you a set of instructions to
follow to change oldf ile into newf ile. The instructions begin with
the following message:
TO TRANSFORM oldfile INTO newfile ...
The instructions are displayed in three types of blocks: a delete block,
an append block, and a change block.
A delete block describes the lines that you should delete from
oldfile, and it has the following form:
*** DELETE [i,j] FROM oldfile ***
<Text of line 1 in oldfile.
<Text of line 2 in oldfile.
<Text of line 3 in oldfile.
The numbers i and j are the first and last line numbers in oldfile of
the lines to be deleted. A less than (<) sign preceding a line of text
indicates that
you should delete the line.
221 Utility Reference
diff Determines the differences between two files
(continued)
An append block describes the lines that you should add to
oldfile, and it has the following form:
*** APPEND AFTER i IN oldfile ***
>Text of first line that you should add.
>Text of second line that you should add.
>Text of third line that you should add.
The number i is the line number in oldfile after which the lines
should be added. A greater than (>) sign preceding a line of text
indicates that you should add the line.
Note: The line number i will not be correct if you make other
changes to the lines in oldfile before line number i.
A change block lists the lines in oldfile that you should change
and shows how to change them. diff presents this information as a
series of lines to delete and a series of lines to add in place of the
deleted lines. A change block has the following form:
*** CHANGE [i,j] IN oldfile TO [m,nl IN newfile ***
<Line 1 in oldfile that you should change.
<Line 2 in oldfile that you should change.
<Line 3 in oldfile that you should change.
---------------
>New text (from newfile) for line 1 in oldfile.
>New text (from newfile) for line 2 in oldfile.
>New text (from newfile) for line 3 in oldfile.
The numbers i and j are the first and last line numbers in oldfile of
the lines to be deleted. The numbers m and n are the first and last line
numbers in newfile of the lines you need to add to oldfile.
Examples Suppose you wanted to compare the contents of the files cow and
lamb. The file lamb contains the following lines:
Mary had a little lamb.
Its fleece was white as snow.
Everywhere that Mary went,
The lamb was
sure to go.
222 Chapter 10
diff Determines the differences between two files
(continued)
The file cow contains the following lines:
Mary had a very large cow.
Its fleece was white as snow,
Mary had a what?
Everywhere that Mary went,
If you entered the command
diff lamb cow
this utility would produce the following:
TO TRANSFORM cow INTO lamb ...
*** CHANGE 1 IN cow TO 1 IN lamb ***
< Mary had a very large cow.
Mary had a little lamb.
*** DELETE 3 FROM cow ***
< Mary had a what?
*** APPEND AFTER 4 IN cow ***
> The lamb was sure to go.
Error Messages
The diff utility may generate the following error messages:
Can't open file
indicates that diff cannot open the named file. The file may not
exist or it may be protected.
Diff I/O Error
indicates an I/O problem.
Improper -1 specification: nn
indicates that diff cannot interpret the nn value specified with the
-1 option as a
number.
223 Utility Reference
diff Determines the differences between two files
(continued)
Internal Error: ...
indicates an internal error. Please contact the Technical Support
Division at SAS Institute if you see this error message. The
Technical Support representative will need the following
information:
[] the version of diff you are using
[] the exact wording of the command line you used
[] the exact wording of the message you received
[] the size of the files you were trying to compare.
Line table overflow
indicates that one of the two line tables, in which diff stores the
lines from each file while they are being compared, is too small to
hold the lines in one of the files. Try increasing the line table size
with the -l option.
Not enough memory for nn lines per file
indicates that you have used the -l option to increase the line table
size, but you do not have enough memory to increase it by the
amount you specified.
Out of memory
indicates that diff is out of memory. Try decreasing the line table
size with the -l option if possible. Do not use the -w option. You
can also try decreasing the size of the I/O buffer by using the -b
option; however, this action makes diff run slower because more
disk accesses may be required. If you are using a hard disk, this
factor may be negligible.
Too many file names: ...
indicates that you have made an error on the command line in such
a way that diff assumes you are attempting to operate on more
than two files.
Unrecognized option
indicates that
you specified an option that diff does not recognize.
224 Chapter 10
grep Searches for and prints regular expressions
Synopsis grep [>destination] [options] pattern file . . .
Description
The grep utility searches the files you specify for all the lines that
contain the specified pattern. For each file in which it finds the
pattern, grep displays, on the screen, the filename, line number, and
contents of the line that contains the matching string. The patterns that
you can specify can be specific or general, and they are sometimes
referred to as regular expressions. In this book, they are referred to as
patterns.
For example, suppose you are working on a long document in a file
named document . txt. You originally were going to call the
document a user manual, but you have decided to call it a user's guide.
You need to see where you have used the word manual to describe the
document. You could enter the following command:
grep manual document.txt
grep displays all of the lines in the file that contain the word manual.
These lines could include such phrases as the manual, insert the paper
manually, or refer to your AmigaDOS manual.
By using special characters as described under "Specifying the
Pattern" later in this discussion, you can tell grep exactly what to
look for so that it does not display lines in which you are not
interested.
To specify the files that you want grep to search, you can use the
AmigaDOS wildcards (#?). For example, to search all files in the
current directory that have an extension of .c, enter # ?.c as the
filename. To search all files in the root level directory of drive df 0:
that begin with the letter g and have the extension .c, enter
df0:g#?.c. AmigaDOS ignores the case of filenames. It will find the
files you specify whether you enter the name in uppercase, lowercase,
or mixed case.
You can redirect the output from grep by specifying a greater than
(>) sign followed by the destination where you want the output sent.
You may want to
redirect the output to a file and print that file.
225 Utility Reference
grep Searches for and prints regular expressions
(continued)
grep supports the following options:
-c prints the total number of matched lines.
-f prints only the names of all files in which grep finds a string
that matches the pattern.
-n tells grep not to display line numbers.
-p displays only printable ASCII characters. Non-printable
characters are filtered out. This option is useful if you are
searching a binary file that may contain control characters.
-q does not display filenames or line numbers.
-s displays the names of all files that grep searches. Normally,
grep displays only those filenames in which it found a match
for the pattern.
-v prints only the lines in which a match of the pattern is not
found.
-v prints the version number of grep.
-S tells grep not to distinguish between upper- and lowercase. For
example, if you use this option, the pattern int would match
int, INT, Int, and INt.
Specifying the Pattern
By using characters that grep interprets in special ways, you can
specify some very complex patterns. Because grep is so flexible, you
must also be specific about the pattern for which you are searching.
The following list describes the special characters that you can use to
specify the pattern for which you are looking:
. is the grep wildcard character. A period will match any single
character, including a space, tab, newline, or control character.
A period followed by an asterisk(*) tells grep that any
number of any characters can be present. The .* sequence is
equivalent to the #? sequence for AmigaDOS commands.
" " are used to enclose patterns
that include space characters.
226 Chapter 10
grep Searches for and prints regular expressions
(continued)
[] are used to search for any one character from a set of
characters by enclosing that set of characters inside square
brackets. A set of characters enclosed in square brackets is
called a character class. A character class will match one single
character. For example, to search for lines that contain vowels,
you can enter [aeiou].
- is used to specify a range. Inside a character class, you can
specify a range of characters by entering the first character
in the range and the last character in the range separated
by a hyphen. The first character must occur alphabetically
before the second. For example, to find any one of the
lowercase alphabetic characters, you enter [ a- z ] .
! is used as the negation character when included as the first
character in a character class. An exclamation point tells
grep to find any character that is not in the character
class. For example, to find any one character that is not a
lowercase alphabetic character, enter [!a-z] . To find any
one character that is not a lowercase alphabetic character
and is not the end-of-line character, enter [!a-z\N].
* tells grep that the preceding character does not have to be
present in the pattern but can be present an unlimited number
of times. In other words, an asterisk means "zero or more of."
A period followed by an asterisk tells grep that any number
of any characters can be present. The .* sequence is equivalent
to the #? sequence for AmigaDOS commands.
+ tells grep that the preceding character must be present in the
pattern at least one time but can be present an unlimited
number of times. In other words, a plus sign means "one or
more of." For example, to find all lines in your file that contain
one or more of the lowercase letter t, enter t+.
^ tells grep that the pattern must begin in column 0. Enter the
caret (^) at the beginning of the pattern. grep will look only for
those lines in which the pattern occurs beginning in column 0.
For example, to find all lines that begin with a left parenthesis,
enter ^(.
227 Utility Reference
grep Searches for and prints regular expressions
(continued)
$ tells grep that the pattern must occur at the end of a line.
Enter the dollar sign at the end of the pattern. For example, to
find all lines that end with a right parenthesis, enter ) $.
\ is the escape character. If you want to search for any of the
special characters included in this list, you must enter a
backslash before that character. For example, to find all lines
that contain a caret, enter \~. Similarly, if you want to search
for a backslash, enter two backslashes, \ \ .
You also need to use the backslash to identify certain
additional characters. These characters are as follows:
\b backspace
\n newline
\r carriage return
\s space
\t tab
\xij control character identified by hexadecimal digits ij
For example, to locate all lines containing the Control-g
character, enter \x07.
You can combine these characters to specify any pattern you need.
The way in which you specify the pattern to grep determines the
response you will receive. grep does not convert tabs to spaces or
change any combinations of spaces and tabs. If grep does not respond
as you expect it to, try escaping any special characters with the
backslash (\) character. Alternatively, try reducing the number of the
special characters in your search pattern.
Examples
To search for one word, you need only specify the word and the file in
which you want to search. For example, the following command
searches the file document.txt for the word manual:
grep manual document.txt
To search for a string of words that are separated by spaces you
must enclose the entire string within double quotes, as follows:
grep
"this is the string to search for" document.txt
228 Chapter 10
grep Searches for and prints regular expressions
(continued)
Specifying Any Single Character
You can tell grep that a character can be any character by using a
period (.) to designate that character. For example, you can specify a
four-character pattern, beginning with th and ending with n, in which
the third character can be anything, by specifying the following
command:
grep th.n document.txt
This command will display all lines with patterns such as
than then thanks Ethan
The period will match any single character, including an alphabetic
character, numberic character, space, tab, newline, or control
character. For example, you can enter the following command:
grep 123.45 document.txt
This command will display all lines containing any of the following
strings:
123a45 123 45 123!45 123(45 123.45
Specifying Character Classes
A character class is useful when you need to look for characters that
do not follow a pattern or when you do not care about the case of a
character. For example, the following command displays all lines
containing the symbols %, &, or ~:
grep [%&~] document.txt
If you want to display all lines containing either the or The, you can
enter the following command:
grep [Tt]he
document.txt
229 Utility Reference
grep Searches for and prints regular expressions
(continued)
Similarly, you can enter the following command:
grep [Tt][Hh][Ee] document.txt
This command displays all lines containing any of the following strings:
THE THe The the thE tHE tHe ThE
Using the -$ option produces the same results:
grep -$ the document.txt
Inside a character class, you can use a minus (--) sign to specify a
range of characters. The first character must occur alphabetically
before the second. For example, the following command displays all
lines that contain a lowercase letter:
grep [a-z] document.txt
Similarly, the following command displays all lines that contain any
lowercase letter, any uppercase letter, or any decimal number:
grep [a-zA-ZO-9] document.txt
A practical use of character classes arises when you need to display all
the lines in your file in which you refer to a specific year. Since each
character class matches one character, enter the following command:
grep [0-9][0-9][O-9][O-9l document.txt
If you are concerned only with years in the nineteenth and twentieth
centuries, then enter this command:
grep
1[89][0-9][0-9] document.txt
230 Chapter 10
grep Searches for and prints regular expressions
(continued)
Also, the exclamation point (!) means not if it occurs as the first
character in a character class. For example, the following command
displays all lines that contain any character that is not a lowercase
letter:
grep [!a-z] document.txt
The following command displays all lines that contain any character
that is not the number sign (#):
grep [!#] document.txt
Specifying the Number of Times a Character Can Appear
An asterisk (*) tells grep that the preceding character can be present
zero or more times. For example, you may have a file in which you
have referred to Gail and mentioned a year in which some event has
occurred. To display those lines in which both Gail and a year occur,
enter the following command:
grep "Gail.*[0-9][0-9][0-9][0-9]" document.txt
The period (.) followed by an asterisk (*) tells grep that any character
can be between Gail and the year and that you do not care how many
of the characters appear. This command would display lines such as
the following:
Call Gail Barbara Industries at 1-999-629-9310.
Gaillard de Marentonneau was a 1900s century botanist.
My eldest daughter Gail was born in 1969.
You can also use the asterisk (*) after a character class if you want
to tell grep that you do not care how many of the characters in the
character class occur in the pattern. For example, the following
command displays any combination of zero or more lower- or
uppercase letters t and the letters he:
grep [tT]*he
document.txt
231 Utility Reference
grep Searches for and prints regular expressions
(continued)
This command displays lines containing strings such as the following:
he tthe These hero penuche inherit mother
Using the plus (+) sign instead of the asterisk (*) tells grep that you
want the string to include at least one t. Using a plus sign displays the
following strings:
tthe These mother
If you want to display only lines that contain the word the, you can
use the following command:
grep "[tT]+he" document.txt
Of the previously listed words, this command displays only tthe. If
you enter an asterisk (*) instead of a plus (+) sign, this command
displays he and tthe. If you include an exclamation point (!) as the
first character in the character class, this command displays only the
following strings:
he hero penuche inherit
Specifying a Pattern at the Beginning or End of a Line
As the first character in the pattern, a caret (^) tells grep to display
only those lines that begin with the pattern. For example, to display
only lines that begin with numerals, you can enter the following
command:
grep ^[10-9] document.txt
Similarly, you can tell grep to display only those lines that end with a
pattern by entering a dollar sign ($) as the last character in the
pattern. For example, the following command tells grep to display all
lines that end with the word the:
grep
"[tT]+he$" document.txt
232 Chapter 10
grep Searches for and prints regular expressions
(continued)
Specifying Patterns that Contain Special Characters
Using a backslash (\), you can search for any of the special characters
that grep recognizes. For example, if you want to search for a dollar
sign ($), enter a backslash (\) in front of the dollar sign. grep
assumes you are looking for a dollar sign and not for a pattern that
occurs at the end of a line. Similarly, the following command displays
all lines that contain left brackets ([):
grep \[ document.txt
You also can use the backslash (\) to tell grep that you want to
display all lines that contain backslashes, as follows:
grep \\ document.txt
To locate all lines containing tab characters, enter the following
command:
grep \t document.txt
You also can use the backslash (\) inside of a character class. For
example, to find all lines that begin with a space or a tab character,
you can enter the following command:
grep "^[ \t]" document.txt
Because the period (.) is the grep wildcard character, to search for
the phrase and so on ..., use the following command:
grep "and so on \.\.\." document.txt
You can use \xij to search for control characters. Control characters
are generally used as printer format instructions in files produced by
word processors. Identify the character by its hexadecimal number (ij).
For example, to display all lines that contain Control-g, enter the
following command:
grep \x07
document.txt
233 Utility Reference
grep Searches for and prints regular expressions
(continued)
To find lines that contain Control-z, enter the following command:
grep \xla document.txt
The dollar sign ($) special character works much like the carat (^)
except that it forces the match to occur only at the end of a line. For
example, to search for all occurrences of the C language comment
terminator, */, at the end of a line, enter the following command:
grep \*/$ document.txt
The backslash (\) tells grep not to interpret the asterisk (*) in its
special sense as a closure operator.
Suppose you have a number of C language source files, each with
filenames that end with .c, and you need to search these files to find
all calls of either of the read or fread functions. Enter the following
command:
grep "f*read *(" #?.c
This command prints every line in these files that contains either
read or fread, followed by O or more spaces and a left parenthesis.
You also can search your files for all function definitions. Assume
that each function definition begins with the function name and
parameter list on a separate line. You can use the following command:
grep "^[a-zA-Z_ ]+[a-zA-Z0-9_ ]*(" #?.c
The pattern matches only expressions that begin a line. The
expression must consist of one or more lowercase letters, uppercase
letters, or the underscore (_), followed by 0 or more spaces, and then
a left parenthesis. This command will print lines such as the following:
get1(s) /* get a line */
_read ()
my_read(fp) {fread(fp,x);}
However, this command will not select a line such as
char
*get1(p) /* get a line */
234 Chapter 10
grep Searches for and prints regular expressions
(continued)
You can use grep to help locate mismatching left and right braces
({}). To print each line that contains a left or right brace, you can
enter the following:
grep [{}] #?.c
Error Messages
grep may generate the following error messages:
Bad character class
indicates that grep is unable to interpret a character class in the
pattern you have asked it to find. Check to see if you have used any
special symbols that you did not intend to use. This message also
can be generated if, in specifying a character class and using the
minus (--) character to indicate a range of characters, the first
character in the range does not alphabetically precede the second
(for example, [d-a]).
Bad pattern
indicates that grep is unable to interpret the pattern you are
asking it to find. You may have used a special character in the
pattern that does not make sense in this context. Check to see if you
have forgotten to escape a special character.
Can't find file(s) ...
indicates that grep is unable to find one or more of the files you
have asked it to search. The files may not exist, or you may have
misspelled the filenames.
Can't open ...
indicates that grep is unable to open the named file. The file may
not exist or may be protected.
Closing ] not found
indicates that grep believes that you have asked it to search for a
pattern that contains a character class, but you have omitted the
right bracket (]) that terminates the character class. If not, you may
have included a left bracket ([) in the pattern but forgot to use a
backslash (\) before it.
Empty character class
indicates that a character class you have used in your pattern has
no members, for
example [].
235 Utility Reference
grep Searches for and prints regular expressions
(continued)
Improper hex specification
indicates that you have used the x escape sequence but have not
followed it with two recognizable hexadecimal digits.
Incompatible combination of options
indicates that the options with which you have invoked grep are
contradictory.
Internal Error: . . .
indicates an internal error. Please contact the Technical Support
Division at SAS Institute if you see this message. The Technical
Support representative will need the following information:
[] the version number of grep you are using
[] the exact wording of the command line you used
[] the exact wording of the resulting error message.
Invalid option
indicates that you have used a command line option that grep does
not recognize. This message also can be generated if your pattern
begins with a minus sign (--) but you have not escaped it or
enclosed the pattern in double quote marks (").
No beginning double quote in pattern
indicates that grep has detected double quote marks (") in a
pattern that did not start with a double quote. You may need a
backslash (\) before the double quote.
No file arguments provided
indicates that grep believes you have specified a pattern but no
filenames. This message also may be generated if you invoke grep
with a filename but no pattern.
No pattern or file arguments given
indicates that grep cannot find either a pattern or filename on its
command line.
Out of space
indicates that grep has run out of space in constructing its pattern
representation. Please contact the Technical Support Division at
SAS Institute if you see this message.
Pattern ill-formed: no terminating double quote
indicates that you started the pattern with a double quote (") but
failed to
terminate it with one.
236 Chapter 10
grep Searches for and prints regular expressions
(continued)
Too few arguments to GREP
indicates that grep demands at least two arguments on its
command line: a
pattern and at least one filename.
237 Utility Reference
gst Manages global symbol tables
Synopsis gst [gst-filename] [options] [symbol-name . . . ]
Description
A Global Symbol Table (GST) is a collection of all the information
defined in a set of header files and stored in a format that the compiler
can use easily and quickly. You can use GSTs to reduce significantly
the processing time required for header files. However, GSTs require
additional disk space and impose some restrictions on your header
files. For information on creating and using GSTs, refer to Chapter 4,
"Using the System Header Files to Access Libraries," in SAS/C
Development System Library Reference.
The gst utility helps you manage GSTs and extract information
from a GST. With the gst utility, you can
[] load a GST into memory
[] unload a GST
[] list all GSTs currently in memory
[] extract symbol information from a GST.
GSTs must be loaded into memory before they can be used.
Normally, a GST is loaded automatically the first time you issue a
command that needs the GST. After a GST is loaded, it will remaill in
memory until either the system needs the memory, until you mallually
unload it using the gst utility, or until you tell sc to recreate the
GST. To load a GST into memory, specify the GST command as
follows:
gst gst-filename
The gst utility loads the GST into memory and then exits.
Note: You should do this only if you plan to remove the disk
containing the GST from the drive.
To display information about a symbol contained in a GS 1', specify
the gst command as follows:
gst gst-filename symbol-name
Some symbols may occur more than once in the GST. For example,
a symbol may occur once as a structure tag and again as an identifier.
The gst utility prints all definitions of the same symbol.
gst supports the following options:
list
lists all GSTs currently in memory. You can use this option to
determine which
GSTs to unload if you need more memory.
238 Chapter 10
gst Manages global symbol tables
(continued)
[name=]filename
specifies a GST file created using the makegst option in the sc
command. You do not need to specify name= unless you want to
load a GST that has the same name as a keyword (for example,
name = symbol ).
[symbol=]symbol-name
displays the type of symbol name and the filename and line number
where symbol-name is defined. The type may be one of the
following:
tag struct, union, or enum name
identifier variable or function name
typedef typedef
include #include filename
preprocessor preprocessor macro or #define
You do not need to specify symbol= unless you want information
about a symbol that has the same name as a keyword (name,
unload, and so on).
unload
forces a GST to be unloaded from memory. If you also specify
symbol names on the command line, gst prints all definitions for
those symbols before it unloads the GST.
verbose
prints the full definition of symbol-name.
Examples
To load the GST named pro ject.gst, enter the following command:
gst project.gst
The gst utility loads the GST into memory and then exits.
If the header file intuition/intuition.h is included in
pro ject.gst, you can display the definition of the Window
structure as follows:
gst
project.gst Window
239 Utility Reference
gst Manages global symbol tables
(continued)
If project.gst is not already loaded into memory, gst loads
project.gst. After project.gst is loaded into memory, gst
queries the GST and displays the following information:
intuition/intuition.h 904 defines "Window" (struct)
To display additional information, enter the following command:
gst verbose project.gst Window
gst also displays the contents of the Window structure with offsets
for each member.
Error Messages
gst may generate the following error messages:
No GST file specified
indicates that you did not specify a GST filename.
Can't find GST file "filename"
indicates that gst cannot find the file specified.
Symbol "symbol-name" not found
indicates that gst could not find the specified symbol.
Not enough memory to load GST
indicates that the GST file could not be loaded due to insufficient
memory.
240 Chapter 10
hypergst Displays the contents of GSTs
Synopsis hypergst [gst-filename]
Description
The hypergst utility enables you to browse the definitions of symbols
and data structures in GSTs (Global Symbol Tables) that are loaded
into memory. The hypergst utility works with the AmigaGuide
hypertext system. For information on using AmigaGuide, see Chapter
3, "Getting Help," in SAS/C Development System User's Guide,
Volume I: Introduction, Editor, Compiler.
To browse the definitions in a GST, the GST must be loaded in
memory. You can invoke the hypergst utility and load a GST in one
of the following two ways:
[] You can enter the hypergst command followed by the name of the
GST file that you want to browse.
[] From the Workbench you can click on the HyperGST icon, then
hold down the Shift key and double-click on the icon for the GST file
that you want to browse.
If the GST that you want to browse is already loaded into memory,
you can invoke hypergst in one of the following two ways:
[] You can enter the hypergst command without specifying a GST
filename. The hypergst utility displays a screen listing the names
of all GSTs in memory. To select a specific GST, click on the name
of that GST file.
[] You can double-click on the HyperGST icon. The hypergst utility
displays a screen listing the names of all GSTs in memory. To select
a specific GST, click on the name of that GST file.
After the GST is loaded, hypergst displays a screen containing
buttons for the various kinds of symbols defined in the GST. These
buttons are as follows:
Data Items
displays external data items declared in header files in the GST
such as DOSBase.
Prototypes
displays prototypes for functions including system functions and
functions declared in your OWII header files.
Typedefs
displays custom data types defined with a typedef statement
either in
system header files or in your own header files.
241 Utility Reference
hypergst Displays the contents of GSTs
(continued)
Structs/Unions/Enums
displays structure, union, and enumerated type definitions.
Preprocessor Symbols
displays preprocessor macros defined in any header file including
macros with arguments and simple substitution macros.
If you click on one of these buttons, hypergst displays an
alphabetical list of all symbols of that type in the GST. If you click on
the name of a symbol, hypergst displays a symbol information
screen for that symbol. This screen may contain other buttons that
reference header files, structure tags, type definitions, and so on. You
can click on any of these buttons to display more information about the
highlighted item.
Error Message
hypergst may generate the following error message:
No GST files in memory
indicates that you have not loaded any GST files into memory. For
example, you see this message if you invoke hypergst
immediately following a reboot and do not specify any arguments.
242 Chapter 10
lprof Generates run-time statistics
Synopsis lprof [-t=n] [>prog-output-dest] program [program-options]
Description
The lprof utility generates run-time statistics for a program. lprof
records the amount of time spent in each routine that is called as your
program runs. The lstat utility produces a report using the
information compiled by lprof. This report will help you identify
modules that run slowly or inefficiently.
To use lprof with your program, you must compile your program
with the debug option.
lprof gathers statistics by determining, at regular intervals, what
instruction your program is executing. The default interval is 33
milliseconds. You can change this interval by specifying a new interval
(n) in milliseconds with the -t option as follows:
lprof -t=n program
You can redirect your program's output by specifying a greater than
(>) sign followed by a destination. program is the name of the
executable that you want to run. If program is not in the current
directory, you must specify the full pathname. You can specify options
for your program.
After lprof loads your program, it runs the program and gathers
statistics by examining the current program counter at given intervals.
lprof writes your program's statistics to the file named prof . out
in the current directory. You can use the lstat utility to produce a
report from those statistics.
Examples
To gather statistics on a simple program named myprog that does not
take any arguments, enter the following command:
lprof myprog
For a program that normally takes command-line arguments, you
can add them after the program name, as follows:
lprof myprog -opt 1 -flag
If you want to redirect the program's output to a file named
outfile, enter the following command:
lprof
>oUtfile myprog -opt 1 -flag
243 Utility Reference
lprof Generates run-time statistics
(continued)
If the program is not in the current directory, you must give the full
pathname, as follows:
lprof
>outfile C:myprog -opt 1 -flag
244 Chapter 10
lstat Analyzes and prints run-time statistics
Synopsis lstat [>destination] [options] program [profile]
Description
The lstat utility analyzes the profile statistics file created by lprof.
lprof runs the program, gathers statistics by examining the current
program counter at given intervals, and writes this information to the
file named prof . out in your current directory. lstat analyzes the
information in this file and displays a report on the screen.
You can redirect the output from lstat by specifying a greater
than (>) sign followed by the destination where you want the output
sent. You may want to redirect the output to a file and print that file.
The profile is the name of the output file created by lprof. lstat
first looks in your current directory for the default file produced by
lprof, prof.out. If this file is not in your current directory, or if
you have changed its name, you must specify its full pathname as the
value for profile.
You must specify the program name. lstat uses this name to get
debugging and symbol information for its report.
Note: This utility assumes that you have compiled the program
with the debug compiler option. The debug option allows lstat to
associate code with a specific line. If you do not compile with the
debug option, lstat reports statistics based on subroutines only.
lstat supports the following options:
-z tells lstat to display statistics for all subroutines even if
they were not encountered in profiling. By default, lstat
does not report subroutines that it does not encounter.
-f tells lstat to display full statistics for each subroutine,
indicating the line numbers within a module that it
encountered. By default, lstat displays only summary
information about the subroutine.
-t=n tells lstat to display only those routines that have at least n
hits. By default, lstat prints all subroutines that it
encountered even once.
If the report produced by lstat shows that a large percentage of
time is spent in one program module, you may want to
[] redesign the module
[] incorporate the module into the calling routines, thus eliminating
calling overhead
[] rewrite the routine in assembly language
[] restructure your program.
245 Utility Reference
lstat Analyzes and prints run-time statistics
(continued)
You also may find that most of the work being done involves the
routine in question, and the percentage of time taken is reasonable.
Examples These examples assume that you have the file named pro f . out in
your current directory and that prof . out was produced with the
following command:
lprof testprog
To display the basic statistics about your program, enter the
command lstat testprog as follows:
1> lstat testprog
header size 0x1c, ProfileHeader 0x1c
719 run + 158 ready + 77 wait = 954
75.367% run, 16.562% ready, 8.071% wait
8.067% samples (58) oUt of profile range
counted = 660, RUN - NonTable 661
Routine % Total % Offset Hits Label
59.5455% 59.5455% lc44c 393 getrsc
8.9394% 68.4848% lc6fa 59 frersc
3.6364% 72.1212% 10d38 24 alcmem [lines 64-102 in mem.c]
Most hits-1.2121% (8) on line 80
2.2727% 74.3939% 18252 15 instal [lines 117-146 in sym.cj
Most hits-1.2121% (8) on line 132
0.l5l5% l00.0000% 1ca18 1 CXM22
You can display information about subroutines that lprof did not
encounter by using the -z option. In this example, using this option
produces information about the strcat and strncpy routines.
These routines have O hits and account for 0% of the runtime, but IIOW
appear in the output, as in the following:
1> lstat -z testprog
246 Chapter 10
lstat Analyzes and prints run-time statistics
(continued)
header size 0xlc, ProfileHeader 0xlc
719 run + 158 ready + 77 wait = 954
75.367% run, 16.562% ready, 8.071% wait
8.067% samples (58) out of profile range
counted = 660, RUN - NonTable 661
Routine % Total % Offset Hits Label
59.5455% 59.5455% lc44c 393 getrsc
8.9394% 68.4848% lc6fa 59 frersc
3.6364% 72.1212% 10d38 24 alcmem llines 64-102 in mem.cl
Most hits-1.2121% (8) on line 80
2.2727% 74.3939% 18252 15 instal llines 117-146 in sym.cl
Most hits-1.2121% (8) on line 132
...
0.0000% 100.0000% lca60 0 strcat
0.0000% 100.0000% lca78 0 strncpy
For each routine that has line number information, you can display
more detailed line number information by specifying the - f option.
The -f option tells lstat to display the percentage of total runtime
and number of hits for each line that was executed in that routine, as
in the following:
1> lstat -f testprog
header size 0xlc, ProfileHeader 0xlc
719 run + 158 ready + 77 wait = 954
75.367% rUn, 16.562% ready, 8.071% wait
8.067% samples (58) oUt of profile range
counted = 660,
RUN - NonTable 661
247 Utility Reference
Istat Analyzes and prints run-time statistics
(continued)
Routine % Total % Offset Hits Label
59.5455% 59.5455% lc44c 393 getrsc
8.9394% 68.4848% lc6fa 59 frersc
3.6364% 72.1212% lOd38 24 alcmem llines 64-102 in mem.~]
0.3030% (2) on line 64
1.0606% (7) on line 68
0.7576% (5) on line 69
1.2121% (8) on line 80
0.3030% (2) on line 90
2.2727% 74.3939% 18252 15 instal [lines 117-146 in sym.c]
0.1515% (1) on line 117
0.1515% (1) on line 129
0.4545% (3) on line 131
1.2121% (8) on line 132
0.1515% (1) on line 133
0.1515% (1) on line 138
...
0.1515% 100.0000% lcal8 1 CXM22
For a large program, you may want to limit the amount of
information produced by lstat by using the -t option. You can use
the -t option to set a minimum number of hits that must be recorded
for a subroutine before that subroutine will be included in the display.
With this option, the final total percentage may not be 100%. Here is
an example:
1> lstat -f -t=2 testprog
header size 0xlc, ProfileHeader 0xlc
719 run + 158 ready + 77 wait = 954
75.367% run, 16.562% ready, 8.071% wait
8.067% samples (58) out of profile range
counted = 660,
RUN - NonTable 661
248 Chapter 10
lstat Analyzes and prints run-time statistics
(continued)
Routine % Total % Offset Hits Label
59.5455% 59.545s% lc44c 393 getrsc
8.9394% 68.4848% lc6fa 59 frersc
3.6364% 72.1212% 10d38 24 alcmem [lines 64-102 in mem.c]
0.3030% (2) on line 64
1.0606% (7) on line 68
0.7576% (5) on line 69
1.2121% (8) on line 80
0.3030% (2) on line 90
2.2727% 74.3939% 18252 15 instal [lines 117-146 in sym.c]
0.1515% (1) on line 117
0.1515% (1) on line 129
0.4545% (3) on line 131
1.2121% (8) on line 132
0.1515% (1) on line 133
0.1515% (l) on line 138
...
0.3030% 98.3333%
lca00 2 xcovf
249 Utility Reference
omd Disassembles object modules
Synopsis omd [r>destination] [-x] object [source]
Description
The omd (Object Module Disassembler) utility program disassembles an
object file produced by the SAS/C Compiler and produces a listing
consisting of assembly language statements (interspersed with the
original C source code if you specified a source filename).
omd sends the output to the screen unless you redirect it by entering
a greater than (>) sign followed by a destination. You rnay want to
send the output to a file and then print the file.
The -x option sets the size of the buffer used to hold the external
symbol section of the object module. For example, -x250 establishes a
buffer that can hold 250 external symbols. The default size is 200. You
should increase the buffer size only if omd reports that there are too
many external symbols.
object is the object filename. You must specify the complete filename,
including the .o extension.
source is the source filename. If you specify source, you must specify
the complete source filename, and the source file should have been
compiled with the debug compiler option. The debug option allows
omd to associate source lines with the object code they generated. If
you did not use the debug option, C source lines will not appear in
the output produced by omd.
Examples
The following example compiles myprog.c to produce myprog.o,
which is then disassembled with omd. The disassembled listing is
redirected to the file named myprog. 1st.
sc debUg=line myprog
omd
>myprog.lst myprog.o myprog.c
250 Chapter 10
oml Manages libraries
Synopsis oml [<cmdfile] [>listfile] [options] libfile [command [module...]]...
Description
You can use the oml (Object Module Librarian) to manage your
libraries. oml allows you to:
[] create library files
[] list the modules in a library file
[] delete modules from a library file
[] replace old modules with new modules.
A link library is a group of object modules, each of which was
originally in a separate file and consisted of one or more subroutines.
Some advantages of using a link library are as follows:
[] The subroutines in a library can be used by several programs.
[] When you are linking your program, you specify only the library file
instead of several individual object modules.
[] The linker includes only those modules in the library that are
required by your program.
Each module within the library is identified by a module name,
which is placed in the object module by the program (the SAS/C
Assembler or Compiler) that generates the module. The assembler and
compiler use the name of the object file.
If a module does not contain a module name, oml assigns a module
name of the form $nnn, where nnn is a decimal number.
A module may define one or more public symbols. A public symbol
is something in the module that is available to other modules, such as
global variables or functions. When the linker resolves external
references for a program, it examines each module in each library you
specify. It decides which of the modules are required by the program it
is linking by looking at the module's list of public symbols. If any of
the program's unresolved external references match any of the
module's public symbols, that module will be included in the
executable module.
When writing the modules for your library, be careful to avoid
duplicate names for public symbols. If you create a library that defines
a symbol more than once, oml issues a warning message. If you then
link with that library without correcting the problem, the linker may
include the wrong module or give a duplicate symbol error.
To invoke oml, enter the oml command followed by a library name,
as follows:
oml mylib.lib
251 Utility Reference
oml Manages libraries
(continued)
oml waits for you to enter commands (and module names, if
necessary) from the keyboard.oml executes the commands as you
enter them and displays a list of any duplicate symbol names that it
finds. After you have entered all your commands, enter a Control
backslash (Control-\) to terminate the oml.
You also can include the commands and module names on the oml
command line. If you enter commands on the command line, oml
executes those commands and terminates. For example, the following
command replaces the module ftoc.o in my lib.lib with the
version of the same module in your current directory:
oml mylib.lib r ftoc.o
oml replaces the module, lists any duplicate symbol names it finds,
and terminates.
You also can enter some commands on the command line followed
by some from the keyboard. If you include an at (@) sign at the end of
the command line, oml executes the commands you enter on the
command line and then waits for you to enter additional commands
from the keyboard. You must enter a Control-\ to terminate oml. For
example, the following command replaces the module ftoc.o in
mylib.lib with the version of the same module in your current
directory and then waits for you to enter additional commands from
the keyboard:
oml mylib.lib r ftoc.o @
You also can enter the commands into a file and tell oml to use that
file as input. You can tell oml to use that file by either of the following
methods:
[] entering a less than (<) sign followed by the filename (<cmdf ile)
as the second item on the oml command line
[] entering an at (@) sign followed by the filename (@cmdf ile) as the
last item on the oml command line.
oml sends its output to the screen unless you redirect it by
specifying a
greater than (>) sign followed by a filename.
252 Chapter 10
oml Manages libraries
(continued)
Specifying Com mands
Commands specify the actions to be performed by oml with respect to
the specified library file. Each command is specified as a single
character, usually followed by a list of module names or object
filenames. Separate commands and file and module names with one or
more spaces. If you specify the r, d, or x command, oml assumes that
the next item on the command line is a file or module name, so that
item is not checked to determine if it is another command. If you need
to enter a file or module name that may appear to oml to be a
command, specify that file or module name as the first name following
the command. oml supports the following commands:
r file file . . .
replaces the named object files in the library or adds them to the
library, if they are not already present. Each module should be in a
separate object file. To replace modules within a library, make sure
that the module contains a module name and that the filename is
the same as the module name.
d module module . . .
deletes the named modules from the library. oml assigns module
names to those modules without names; therefore, you may need to
get a listing of names in the library (using the 1 command) to
determine the name of the module that you want to delete.
x module module . . .
extracts the named modules from the library and creates separate
files using the same names. You may need to get a listing of names
in the library (using the l command) to determine the correct name
of the module that you want to extract. If the module name
contains a pathname, oml attempts to create a file with that name.
If the module name does not contain a pathname, oml creates the
file in the current directory unless you specify a different pathname
with the -o option. You can use an asterisk (*) to specify that you
want all modules extracted. oml terminates if it cannot extract a
module. You cannot extract and replace the same module with the
same oml command line.
l
generates a listing of the modules in the library after all other
commands have been executed. If you also specify the -s option,
the listing
includes the public symbols defined in each module.
253 Utility Reference
oml Manages libraries
(continued)
@[filename]
tells oml to execute the commands that you enter from stdin
(usually defined as the keyboard) or from the filename, if specified.
If you include this option it should be the last option on the
command line.
If you specify the r or d command, oml creates a temporary file in
which it builds the new version of the library. After oml builds the
new version, if it does not detect any errors, it deletes the original
library file (if it existed) and renames the temporary file. Therefore, the
original library file is not affected if an error occurs.
Specifying Options
oml supports the following options:
-b tells oml not to issue prompts, including prompts for
missing information.
-n strips debugging information from modules before
adding them to the library.
-oprefix specifies a prefix for the filenames to be created by the x
command. If the prefix includes a directory name, you
must include the forward slash (/) at the end of the
name.
-s includes, in the listing produced by the l command, a
list of the public symbols defined in the module.
-tpathname specifies a path for the temporary library.
-v tells oml to display messages as it adds or deletes
modules to and from the library.
-x generates a cross reference for variables and functions
used in a library.
oml produces warning messages if either of the following are true:
[] A module that you want to delete or extract is not in the library.
[] Any module in the library includes a second definition for a public
symbol.
254 Chapter 10
oml Manages libraries
(continued)
Examples
Since a single object file is essentially a library of one module, you can
use oml to find out what module name is included in the object file, as
follows:
oml name.o l
To build a new library, you can create a list of the filenames of the
object modules that you want to include in the library and then create
the library using the following command:
oml new.lib r @name.lst
The following command extracts all of the modules in the library
cfuncs.lib and creates a file for each module in the directory
:object/:
oml -o:object/cfuncs.lib x *
Note: This command will succeed only if the module names in the
library do not contain pathnames.
The following command deletes the module tribe.o from the
library cfuncs.lib:
oml cfuncs.lib d tribe.o
The following command lists the modules and symbols in the library
test.lib:
oml -s test.lib l
You can save this listing in a file named test.lst by adding the
greater than (>) sign followed by the filename:
oml
>test.lst -s test.lib l
255 Utility Reference
scmsg Searches for and corrects errors and warnings
Synopsis scmsg [options]
Description
The semsg utility helps you find and fix errors and warnings in your
code. It acts as a filter between you and the compiler, allowing you to
invoke the editor of your choice and go to the line causing the error or
warning quickly and easily.
You can use semsg with the editor of your choice, using AREXX as
a communication medium. AREXX is a standard part of AmigaDOS 2.0
and can be purchased as a third-party product for use under
AmigaDOS 1.3. If you do not have AREXX, you still can use semsg to
control the se editor provided as part of the SAS/C Development
System, but you will not be able to program the editor keys to control
scmsg.
If you invoke the compiler from the Shell or by using the Build
icon on the Workbench, semsg is automatically invoked for you.
You can specify the following options in the semsg command:
autoedit
specifies that you want semsg to invoke your editor automatically,
open the source file, and display the line producing the message.
The default value is noautoedit.
config=filename
specifies the name of a configuration file. Typically, the
configuration file contains the command necessary to invoke your
editor, open a source file, and display the appropriate line. For
more information about configuration files, see "Using AREXX to
Invoke Your Editor," later in this section.
hidden
specifies that you do not want semsg to display the message
browser window until the compiler returns a message. The default
value is noh i dden.
To redisplay the message browser window, you can enter semsg
nohidden at the Shell prompt or send the AREXX show
command to the sC_ SCMSG AREXX port. For example, you can
use the following AREXX script to send the show command:
/* AREXX script to send the SHOW command */
ADDRESS 'SC_SCMSG'
'SHOW'
quit
terminates
scmsg.
256 Chapter 10
scmsg Searches for and corrects errors and warnings
(continued)
rexxonly
specifies that scmsg should not open a window. Use this option if
you intend to query scmsg for the messages from your editor or
some other AREXX-supporting program, and you do not want to
see the scmsg window.
Unless you specify hidden or rexxonly, scmsg opens a window
on the Workbench screen. This window contains the first error or
warning message from the compilation. As additional messages are
produced, they are appended to the end of the list. These additional
messages may be produced in the same or a different source file.
The current message is always highlighted. You can move from
message to message by clicking on the message or by using the arrow
keys. The scroll bar on the right side of the window allows you to
move around in the list. Double-clicking on a message invokes the
editor at the file and line number specified in the message.
The scmsg window lists all messages in the following format:
primary: class msgno in secondary line lineno: text
where:
primary
is the C source file being compiled.
class
is either Error or Warning.
msgno
is the message number.
secondary
is the name of the file in which the error or warning occurred. This
file may be the same file as the primary file, or it may be a header
file included by the primary file using the #include statement.
lineno
is the line number in the secondary file.
text
is the message text. The message text may specify an alternate file
for a message. If a message describes a conflict between two
different places in your code, the alternate file gives the location of
one of them. The
secondary file gives the location of the other. If an
257 Utility Reference
scmsg Searches for and corrects errors and warnings
(continued)
alternate file is available for the message, the text contains the
words
See line num file filename.
Every time a C source file is compiled, all old messages listing that
file as the primary file are deleted from the scmsg window.
The following sections describe the options available from the
Project and Edit menus on the scmsg screen. Many of these menu
items have menu acce1erator keys that allow you to perform the
specified action without selecting the menu item. To use a menu
accelerator key, hold down the right Amiga key (just to the right of the
spacebar) and press the specified key.
The Project Menu
The Project menu allows you to control your message session. The
following list describes each option on the Project menu and, where
applicable, gives the menu accelerator key equivalent.
Set Options
sets scmsg options that specify which editor you want to use and
any options for that editor. These options are typically saved in the
file ENV: sc/scmsg. The options available are as follows:
editcommand
is the Shell command necessary to start your editor. Use the % f
sequence to indicate where the filename should be in the
command. If this option is left blank, scmsg does not attempt to
invoke your editor, and all the other options are ignored. If this
option is left blank but a portname is specified, scmsg sends
AREXX commands to the port, if it exists.
gotofile
specifies the AREXX commaIld template needed to open a file.
Use the %f sequence to indicate where the filename should be in
the command. Once the filenaIlle has been substituted, this
command is sent to your editor's AREXX port when a new file
needs to be opened. If this option is left blank, scmsg always
uses the editcommand to invoke your editor each time there is
an error.
258 Chapter 10
scmsg Searches for and corrects errors and warnings
(continued)
gotoline
specifies the AREXX command template needed to go to a
specific line. Use the %1 sequence to indicate where the line
number should be in the command. Once the line number has
been substituted, this command is sent to your editor's AREXX
port when scmsg needs to go to a new line. If this option is left
blank, scmsg does not attempt to move to the proper line
number in the file.
hidden
specifies that scmsg should not open a window. Use this option
if you intend to query scmsg for the messages from your editor
or some other AREXX-supporting program and you do not want
to see the scmsg window. This option does not take any
arguments.
portname
specifies the name of your editor's AREXX port. If this option is
left blank, but editcommand is specified, scmsg assumes that
your editor does not support AREXX. The scmsg utility issues
the editcommand option but does not attempt to send any
AREXX commands to your editor.
wait
specifies that scmsg should not open a window until one or
more new compiler messages are available. This option does not
take any arguments.
Use
saves the current options to ENV:sc/scmsg.
Save
saves the current options in ENV:sc/scmsg and
ENVARC:sc/scmsg. The left, top, width, and height
options are set to the current window's values.
Save As . . .
allows you to save your current options to a specified filename. You
will be prompted for the filename.
Restore
reads the option settings from ENV:sc/scmsg into memory.
Restore from . . .
reads the options settings from a specified filename. The scmsg
utility
prompts you to enter the filename.
259 Utility Reference
scmsg Searches for and corrects errors and warnings
(continued)
Reset to SAS/C defaults
resets all options to the default values provided by the SAS/C
Development System. Refer to Chapter 8, ''Compiling and Linking
Your Program," in SAS/C Development System User's Guide,
Volume I: Introduction, Compiler, Editor. These defaults are suitable
for use with se.
Hide Window
closes the scmsg window until the compiler produces another
message.
To redisplay the message browser window, you can enter scmsg
nohidden at the Shell prompt or send the AREXX show
command to the SC_SCMSG AREXX port. For example, you can
use the following AREXX script to send the show commalld:
/* AREXX script to send the SHOW command */
ADDRESS 'SC_SCMSG'
'SHOW'
Quit
terminates scmsg.
The Build Menu
You can use the Build menu to terminate any current builds or start
new builds. The following list describes each option on the Build menu
and, where applicable, gives the menu accelerator key equivalent.
Abort Build
terminates any current builds that are active. You may want to
select this option if, for example, an error in a common header file
is producing too many warnings or errors. The menu accelerator
key for this command is Right-Amiga-A.
Build Project
starts a new build. The smake utility is invoked from the directory
specified in the ENV: sc/pro jdir environrnent variable. This
variable is automatically set for you each time you submit a smake
command or click on the Build icon from Workbench. If unset,
the current directory is used. The menu accelerator key for this
command is Right-Amiga-B. Any build that is currently running is
aborted before
the new build is submitted.
260 Chapter 10
scmsg Searches for and corrects errors and warnings
(continued)
The Edit Menu
You can use the Edit menu to perform certain actions on the current
(highlighted) message. The following list describes each option on the
Edit menu and, where applicable, gives the menu accelerator key
equivalent.
Go to Error
invokes the editor on the file and line number that produced the
message. You can perform the same action by double-clicking on the
message or by pressing the Return key.
Go to Alternate
invokes the editor on the alternate file and line. This option is valid
for messages that have an alternate file and line number specified in
the form
See line num file filename.
You also can edit the alternate file by holding down either Alt key
and double-clicking on the message or by holding down either Alt
key and pressing the Return key.
Delete Message
removes the highlighted message from the list. The menu
accelerator key is Right-Amiga-D.
Clear
removes all messages from the list. The menu accelerator key is
Right-Amiga-C.
Delete by . . .
displays a submenu that allows you to delete all messages that meet
specific criteria. The options on the submenu are as follows:
Message Number
deletes all messages with the same message number as the
current message. The menu accelerator key is Right-Amiga-N.
File
deletes all messages produced by the same secondary file,
regardless of the primary file. The menu accelerator key is Right-
Amiga-F.
Compilation
deletes all messages produced by the same primary file. The
menu
accelerator key is Right-Amiga-P.
261 Utility Reference
scmsg Searches for and corrects errors and warnings
(continued)
Using AREXX to Invoke Your Editor
When scmsg wants to communicate with your editor, it issues an
AREXX command based on the templates you provide with the Set
Options submenu and the information from the highlighted message. It
uses the template in the appropriate option as a base and performs
substitutions on it. All templates start with a percent (%) sign. The
following substitutions are performed:
Template Substitution
%% percent (%) sign
%n newline character
%f filename
%l line number
%c column number
%xhh hexadecimal character specified by hh
%r carriage return
scmsg ignores any other sequence of a percent (%) sign followed by
a character.
If scmsg finds the AREXX port described in your options file, it
sends the openf ile AREXX sequence provided to the port to tell
your editor to open the necessary file.
If scmsg cannot locate the AREXX port described in your options
file, it attempts to invoke your editor on the appropriate file using the
specified editcommand Shell command. If successful, it goes to the
appropriate line using the AREXX command template.
The following values are typical of what might be found in a
configuration file created for se by the Set Options submenu under the
Project menu:
editcommand SC:C/SE Shell command to invoke SE
portname SC_SE Name of the editor's REXX port
262 Chapter 10
scmsg Searches for and corrects errors and warnings
(continued)
gotofile OW "%f"%r Open specified file
gotoline LL "%1"%r Go to line number %1.
Configuration files and example AREXX scripts for several popular
editors have been included with the SAS/C Development System in the
sc:extras/scmsg drawer. Check that drawer to see if support for
your editor has been provided.
Using ehe SC_SCMSG AREXX Port
You can also use the built-in AREXX port iII scmsg to get information
on the messages remotely from your editor or from any other program
that supports AREXX. The port's name (for use with the AREXX
address command) is SC_SCMSG. The following commands are
supported:
abort
aborts any builds currently running.
altfile
returns the alternate filename (if any). An empty string indicates
that there are no messages on the list or that the current message
has no alternate file.
altline
returns the alternate line number (if any). An empty string indicates
that there are no messages on the list or that the current message
has no alternate file.
bottom
goes to the last message in the list.
build
submits a new build of the last project built. Any build that is
currently running is aborted before the new build is submitted.
class
returns either error or warning, depending on the current
message.
clear
deletes all messages.
delcomp [filename]
deletes all messages with the specified filename as their primary
filename. If no
filename is specified, the primary filename of the
263 Utility Reference
scmsg Searches for and corrects errors and warnings
(continued)
current message is used. If the current message is deleted, the next
non-deleted message becomes current.
delete
deletes the current message and goes to the next message in the list.
delfile [filename]
deletes all messages with the specified filename as their secondary
filename. If no filename is specified, the secondary filename of the
current message is used. If the current message is deleted, the next
non-deleted message becomes current.
delnum[msgno]
deletes all messages with the specified message number. If no
message number is specified, the number of the current message is
used. If the current message is deleted, the next non-deleted
message becomes current.
errnum
returns the error number. An empty string indicates that there are
no messages on the list.
file
returns the filename for the current message. An empty string
indicates there are no messages on the list.
hide
closes the scmsg window, but keeps scmsg running. If you specify
wait, the scmsg window reappears when a new message is issued
from the compiler. Otherwise, you must send a show command
with REXX or reinvoke scmsg from the command line to redisplay
the window.
line
returns the line number for the current message. An empty string
indicates there are no messages on the list.
next
goes to the next message in the list. If the current message is the
last in the list, scmsg goes to the first message in the list.
prev
goes to the previous message in the list. If the current message is
the first in the list, scmsg goes to the last message in the list.
quit
terminates scmsg.
264 Chapter 10
scmsg Searches for and corrects errors and warnings
(continued)
rexxonly
specifies that scmsg should close the message browser window and
not reopen it unless you specify scmsg nohidden at the Shell
prompt or send the ARGXX show command to the sc_ SCMSG
ARGXX port. Use this command if you intend to query scmsg for
the messages from your editor or some other AR~XX supporting
program, and you do not want to see the scmsg window.
select
selects the current message for editing. Your editor is invoked and
moved to the proper file and line number. This command is
equivalent to pressing the Return key on the current message.
show[activate]
pops the scmsg window to the front or redisplays the window if it
is hidden. If you specify activate, the scmsg window becomes
the active window, and you can enter keyboard commands to
scmsg.
text
returns the message text. An empty string indicates that there are
no messages on the list.
top
goes to the first message in the list.
Examples
The following AREXX script, when invoked from se, opens the file
containing the current message, moves to the appropriate line number,
and displays the message on the editor message line:
/* AREXX script to move to next error */
address 'SC_SCMSG' /* Set Up to talk to scmsg */
Idelete' /* Delete the current error, move to next */
options results /* Tell AREXX we want the return values */
/* of issued AREXX commands */
'file' /* Get the new filename */
file = result
'line' /* Get the new line nUmber */
line = result
265 Utility Reference
scmsg Searches for and corrects errors and warnings
(continued)
'text' /* Get the new message text */
text = result
options /* Don't care about results any more */
address 'SC_SE' /* Now talk to the editor */
if file = "" then
'DMNo more errors' /* Display Message "No more errors" */
else do
'OW UC' || file || "0d"x /* Open Window "file" */
'LL UC' || line || "0d"x /* Go to line "line" */
'DM' || text /* Display Message "text" */
end
266 Chapter 10
scopts Sets compiler options
Synopsis scopts [options]
Description
The scopts utility allows you to set compiler options for a project by
clicking on the gadget that corresponds to the option. The options you
specify are used by the sc command whenever you compile and link
your files.
To run scopts, you can double-click on the SCoptions icon, or
you can enter scopts on the Shell command line. scopts displays
the SAS/C Compiler Options Index window. This window contains
buttons that open additional windows. Each of these windows allows
you to set different compiler options. In all, scopts can display nine
windows:
Compiler Options Index
allows you to do the following:
[] set certain options such as list, xref, link, and map
[] specify the name of the final executable module
[] display additional windows such as the Optimizer Options
window and the Link Options windows
[] save your option settings to a file named scoptions in the
current directory
[] save your option settings in ENV:sc/scoptions.
Compiler Options
contains gadgets for miscellaneous options such as debug,
shortintegers, and stringmerge.
Diagnostic Message Options
contains gadgets for options, such as ansi, strict, and
errorrexx, that affect which messages are generated by the
compiler and linker and how those messages are handled.
Code Generation Options
contains gadgets for options, such as data, code, and cpu, that
affect the code generated by the compiler.
Listing/Cross-Reference Options
contains gadgets for options, such as listnarrow,
errorlisting, and xrefsystem, that affect the content and
formatting of any listing or cross-reference files generated.
Optimizer Options
contains gadgets for options, such as optpeep, optsize, and
optalias, that
affect the performance of the optimizer.
267 Utility Reference
scopts Sets compiler options
(continued)
Prototype Generation Options
contains gadgets for options, such as genprotoexterns,
genprotoparms, and genprototypedef s, that affect how
prototypes are generated.
Linker Options
contains gadgets for options, such as smallcode, stripdebug,
and batch, that are passed to the linker when the linker is invoked
by sc. These options are not used by the compiler.
Map Options
contains gadgets for options, such as maphunk, mapxref, and
mapoverlay, that affect the content of the map file.
For a brief description of an option, move the cursor to the option
gadget and press the Help key. For a complete description of any
compiler option, refer to Chapter 8, "Compiling and Linking Your
Program," in User's Guide, Volume I.
These windows may contain one or more of the following basic types
of gadgets:
cycles appear as raised buttons with a cycle symbol on
the left side. By clicking on the gadget with the left
mouse button, you can cycle through the setting
available for that option. To reverse the direction
of the cycle, press the Shift key as you click the
mouse button.
actions appear as raised buttons. Selecting the button
causes an immediate action to occur. For example,
selecting the Compiler Options. . . gadget
displays the Compiler Options window.
strings appear as a raised ridge around a text area. You
can enter data in the area by clicking within the
text area and typing. When you have finished
typing, press the Return key.
lists appear as a set of control gadgets (a scroll bar,
arrow gadgets, a string area, and ADD and DEL
buttons) combined with a raised scrolling area. Use
the scroll bar and arrow gadgets to position the
scrolling area on specific items. To add new items
to the list, select the ADD button, type the new
item
name, and press the Return key. To remove
268 Chapter 10
scopts Sets compiler options
(continued)
an item from the list, click on the item (to copy it
to the string area), and select the DEL button. To
modify an item, click on the item (to copy it), and
enter any corrections.
To specify an option for which the scopts utility does not have a
gadget, enter the option and any parameters required by the option
into the SPECIAL gadget. You can enter as many additional options as
you like. If you use the SPECIAL gadget to specify an option for which
scopts already has a gadget, the next time you invoke scopts, the
gadget for that option is selected, and the option is no longer included
in the SPECIAL gadget. The only options remaining in the SPECIAL
gadget are those for which scopts does not have a gadget. For
example, if you enter link into the SPECIAL gadget, the next time
you invoke scopts, the link gadget is selected, and the SPECIAL
gadget does not contain the link option.
Any values you enter into the SPECIAL gadget are processed after
all other gadgets are processed. Therefore, options you enter into the
SPECIAL gadget may override other options.
To specify the name of your final executable module, specify a
filename in the ProgramName gadget.
To save your option settings, select one of the following options from
the Project menu:
Save to SCOPTIONS
saves the settings to the file scoptions in the current directory.
You also can click on the Save button in the SAS/C Compiler
Options Index window to save the settings in scoptions.
Save as global defaults (ENV:)
saves the settings to the file ENV:/sc/scoptions. You also can
click on the Save Default button in the SAS/C Compiler Options
Index window to save the settings in ENV:. The option settings are
also saved to ENVARC:, if it exists.
Save as . . .
asks you for the name of the file in which you want to save the
settings. To use the options saved in a file other than scoptions
or ENV: sc/scoptions, you can specify the filename using the
with compiler option in the sc command. The options in the
with file are read as if they were specified in the sc command at
the position
occupied by the with option.
269 Utility Reference
scopts Sets compiler options
(continued)
To exit scopts without saving any of your changes, click on the
Cancel button.
When you run the sc command, it first looks for an scoptions
file in your current directory. If this file does not exist, the sc
command looks for the ENV:sc/scoptions file.
The scoptions file is an ASCII file that contains the list of sc
options that you specify. You can edit this file with a text editor and
add any options you want.
To load a previously saved options file or to reset all options to their
default values, select one of the following options from the Project
menu:
Restore from SCOPTIONS
reads the contents of the scoptions in the current directory into
memory.
Restore from global defaults (ENV:)
reads the contents of ENV: sc/scoptions into memory.
Restore from . . .
asks you for the name of the file from which you want to read
option settings into memory.
Reset to SAS/C defaults
resets all options to the default values provided by the SAS/C
Development System. Refer to Chapter 8, "Compiling and Linking
Your Program," in SAS/C Development System User's Guide,
Volume I: Introduction, Compiler, Editor.
You also can change option settings by specifying the option Oll the
scopts command line. For example, to set the math=standard and
link options, you can enter the scopts command as follows:
scopts math=standard link
If you enter the scopts command followed by option settings,
scopts does not display any windows, and you cannot choose the file
into which the options are saved. Specifically, scopts performs the
following tasks:
1. reads the scoptions file in your current directory, if it exists.
If this file does not exist, scopts reads ENV: sc/scoptions.
2. adds or
changes the options you specified.
270 Chapter 10
scopts Sets compiler options
(continued)
3. saves the new option settings in the file scoptions in the
current directory.
271 Utility Reference
scsetup Sets up a new project
Synopsis sc:scsetup [directory]. .
Description
The scsetup utility sets up a directory that you can use for C
development. You can run scsetup on existing directories or use it
to create new directories. scsetup creates an icon for the directory
and copies into the directory icons for the most commonly used SAS/C
Development System tools, such as smake and CodeProbe. You can
add icons for any file extensions or tools that you want scsetup to
copy in addition to the standard icons.
Specifically, scsetup performs the following actions:
1. Creates the directory, if necessary.
2. Creates an icon file for the directory being set up, if it does not
already have one. scsetup uses the file
sc: starter_project . info as a template for directory icons.
3. Creates icons for the files in the directory, if necessary. Default
icons are supplied for . c, . h, . a, and . smk files. These icons
are in the sc: icons drawer under the name def_c.info,
def_h.info, def_a.info, and def_smk.info. You can add
any default icons needed for other extensions by copying an icon
into sc:icons with the appropriate name (def_extension.
info).
4. Creates an icon file for any subdirectories of the directory being
set up, if they do not already have one.
5. Creates icons for the files in each subdirectory, if necessary.
6. Copies the contents of the directory sc: starter_project, if
present, to the directory being set up. This starter directory
contains a Build icon, a Debug icon, an Edit icon, and an
SCoptions icon. You can place any other icons or programs in
this starter directory that you want copied to directories set up
with scsetup.
scsetup will not overwrite any existing files or icons.
You can run scsetup from the CLI or from the Workbench. To
run scsetup from the CLI, enter the following command:
sc:scsetup [directory] . . .
If you do not specify a directory name, scsetup sets up the current
directory. If you specify a directory that does not exist, scsetup
creates the directory.
To run scsetup from the Workbench and create a new project,
double-click on the SCsetup icon, and type the name of the drawer
when prompted.
272 Chapter 10
scsetup Sets up a new project
(continued)
To run scsetup from the Workbench and set up an existing
drawer, click on the drawer icon. (Click on the actual drawer icon, not
the file icons in the drawer.) To select additional drawers, hold down
the Shift key and click on their icons. After you have selected all the
drawers, hold down the Shift key and double-click on the SCsetup
icon.
After you have set up a directory, you can run the editor by double-
clicking on the Edit icon, and you can run CodeProbe by double-
clicking on the Debug icon. You can run smake by double-clicking on
the Build icon. smake looks for a smakefile or a makefile. If none
are present, it compiles and links all.c files in the directory using the
options specified through the scopts utility, described earlier in this
chapter.
273 Utility Reference
smake Maintains and updates records of file dependencies
Synopsis smake [options] [macro-definitions] [targets]
Description
The smake utility is a tool that you can use to maintain projects that
are composed of many files. A file can be C source code, a data file for
a graphics or audio, or perhaps a spreadsheet file. For example, you
may have a project that consists of 50 files, and several programmers
may be responsible for different files. To manage this project, you need
to keep track of which files have been changed and which files must be
compiled before other files (that is, which files are dependent on other
files). You can use smake to keep track of file dependencies, recompile
and relink any files that have been updated, and produce new product
files.
In other words, smake determines if any of the source files have
changed since the last version of the product file was generated and, if
so, generates a new product file.
To use smake, you create a smakefile that identifies dependent files
and target fi1es and describes the actions required to produce a new
product. A basic description of these terms follows:
target file is any file that is created or updated by smake.
Producing this file may require creating or updating
several intermediate files.
dependent file is a file that must be created or updated before a
target file can be updated. A dependent file can be a
source code file, header file, or object code file. In
other words, if a dependent file is changed (for
example, by editing), then the target file must be
rebuilt.
actions are the commands necessary to update each dependent
and target file. Actions can be calls to the compiler or
linker or basic housekeeping commands.
smakefile is a file that identifies every dependent file required to
create the target file and describes every action
required to update or create the dependent and target
files.
When you run smake, it re-creates only the first target file specified in
the smakefile (unless you specify an alternate target as described in
"Using
Alternate Targets," later in this section) and, if necessary, any
274 Chapter 10
smake Maintains and updates records of file dependencies
(continued)
dependent files needed to re-create the target file. Specifically, smake
performs the following actions:
1. Locates and identifies the target file. By default, smake remakes
the first target file specified in the smakefile. You can specify an
alternate target as described under "Using Alternate Targets,"
later in this section.
2. ensures that any file on which the target file depends already
exists and is up to date. To determine when dependent files were
last modified, smake looks at the time stamp of the file. A file is
considered current if it has a time stamp later than that of any of
its dependent files.
Note: Before using smake, make sure that your system clock
is accurate, using the date command if appropriate.
An example of the date command under AmigaDOS follows:
date 12-Aug-92 16:34:57
You must enter the time using 24-hour clock notation. Enter the
month as a three-character field.
3. Re-creates the target file if any of the dependent files have been
modified more recently than the target file.
Creating the smakefile
A smakefile has the following basic format:
# This is a comment.
target-file1: dependent-file1 dependent-file2...
actions
target-file2: dependent-file1 dependent-file2...
actions
.
.
.
You can include comments in a smakefile by entering a pound (#)
sign in the first column. smake will ignore the remainder of that line.
All target file names must
[] start in the first column
[] be followed by a colon (:)
[] be followed by
the name of any dependencies of the target.
275 Utility Reference
smake Maintains and updates records of file dependencies
(continued)
If there are too many dependent filenames to fit on one line, repeat the
target name and colon on the next line, and enter the remaining
dependent filenames.
Immediately after the target-dependency line are any actions
required to generate the target. Each of the action lines, if any, must
be indented a minimum of one tab or space. To continue an action line
onto additional lines, end each continued line with a backslash (\). You
can have as many action lines as necessary for each target-dependency
line. You can call smake from within a smakefile. You cannot issue
the cd (change directory) command from within a smakefile.
For example, suppose you have an executable file named myfile
that you created by linking two object files, file1.o and file2.o .
These object files are created by compiling the source files file1.c
and file2.c, and each of these source files includes the header
stdio.h. Figure 10.1 shows the relationships among these files.
----------
Figure 10.1 Executable File | myfile |
Example File (primaryTarget) ----------
Dependencies / \
/ \
Object Files ----------- -----------
(Dependents of Primary and | file1.o | | file2.o |
Targets of Source Files) ----------- -----------
/ \ / \
/ \ / \
----------- ----------- -----------
Source Files | file1.c | | stdio.h | | file2.c |
(Dependents) ----------- ----------- -----------
If any information in stdio.h changes, you would have to
recompile both source files and relink both object files to produce a
new executable file. However, you can create a smakefile that contains
all of the information necessary to recompile and relink these files and
then run smake
to recompile and relink as necessary.
276 Chapter 10
smake Maintains and updates records of file dependencies
(continued)
Your smakefile could look like this:
1 # Primary target is myfile
2 myfile: file1.o file2.o
3 slink FROM LIB:c.o+file1.o+file2.o TO myfile LIB \
4 LIB:sc.lib+LIB:amiga.lib
5
6 file1.o: df1:source/file1.c stdio.h
7 sc data=absolute code=far dfl:source/file1.c
8
9 file2.o: df1:source/file2.c stdio.h
10 sc data=absolute code=far df1:source/file2.c
Note: Do not enter line numbers in your smakefiles. Line numbers
are included here for use in the discussion that follows.
The first line is a comment line. The second line identifies the two
dependent object files of the target file myfile. That is, it identifies
the files that must be current before myf ile can be generated:
file1.o and file2.o.
Lines three and four give the commands (actions) necessary to
produce myfil e. In this example, the only command necessary to
produce myf ile is a call to the linker, slink.
The sixth line identifies the files required to produce the object file
file1.o. The two files are df1:source/file1 .c and stdio.h.
Line seven gives the command necessary to produce the object file: a
call to the compiler, sc. Lines nine and ten identify the dependent files
and actions required to produce file2.o.
Target-dependency and action lines are the primary components of a
smakefile. However, smake provides many special features that you
can use to make your smakefiles more powerful. These features include
macros, transformation rules, local input files, fake targets, and more.
The following sections describe all of the special features you can use
in your
smakefile.
277 Utility Reference
smake Maintains and updates records of file dependencies
(continued)
Using Special Symbols
You can use special symbols to override some of the default actions of
smake. These special characters are as follows:
- Normally, when an action generates an error, smake stops
processing. If you want smake to continue processing when it
encounters an error caused by a specific action, begin the action
line with a minus (--) sign. If you want smake to continue
processing after all errors, specify the command line option -k.
@ Normally, smake displays all commands and messages generated
by those commands on the screen as each command is executed. If
you do not want a command to be echoed to the screen, begin the
action line with the at (@) symbol. smake will still display any
generated messages. If you do not want any commands echoed to
the screen, specify the command line option - s.
$ The dollar ($) sign is an escape symbol for the dollar sign itself. In
other words, to enter a dollar sign in a filename, enter two dollar
signs ($$). If you enter only one dollar sign, smake thinks that
the dollar sign indicates the beginning of a macro.
\ The backslash (\) symbol is an escape symbol for the pound (#)
sign. Pound signs normally indicate the beginning of a comment.
To use a pound sign in a command line, enter a backslash before
the pound sign (\#).
& The ampersand (&) symbol is provided for compatibility with other
implementations of smake. The ampersand is ignored under
AmigaDOS.
Using Macros
You can use macros to represent any character string, including
AmigaDOS commands, directory specifications, header files, compiler
or assembler flags, and constant strings. Macros are especially useful
where long character strings are required.
Within a smakefile, you can define a macro using the equals (=) sign
as follows:
macro-name = definition
Make sure you define a macro before you attempt to use it. If you
reference a macro that has not yet been defined, that macro will be
expanded to an
empty.
278 Chapter 10
smake Maintains and updates records of file dependencies
(continued)
Note: You purposely can define a macro to be the empty string by
entering only the macro name and the equals (=) sign:
macro-name =
To refer to a macro within a smakefile, use the following format:
$(macro-name)
For example, you can define the macros source and f lags to
represent the pathname of your source file and the compiler options
you want to use to compile that file. Using these two macros, our
earlier example now looks like the following:
# Define macros for soUrce pathname and compiler options
SOURCE = df1:source/
FLAGS = data=absolute code=far
# Primary target is myfile
myfile: file1.o file2.o
slink FROM LIB:c.o+file1.o+file2.o TO myfile LIB \
LIB:sc.lib+LIB:amiga.lib
file1.o: S(SOURCE)file1.c stdio.h
sc $(FLAGS) S(SOURCE)file1.c
file2.o: $(SOURCE)file2.c stdio.h
sc $(FLAGS) $(SOURCE)file2.c
Overriding a Macro Definition
You can override the definition of a macro from the command line of
smake by specifying the new definition as follows:
macro-name = new-definition
If you specify a macro definition on the smake command line, do not
include spaces around the equals (=) sign. For example, you can
redefine the debug macro as follows:
smake -f editor
debug=yes
279 Utility Reference
smake Maintains and updates records of file dependencies
(continued)
Using Default Macros
smake provides five default macros that are defined after a target-
dependency line is processed and before the next action line is
processed.
Macro Definition
$@ target filename
$? list of dependent files, including the full directory
pathnames, that are not current (that is, they have time stamps
later than the target time stamps)
$* name of the first dependent file, including the full directory
pathname but excluding the filename extension
$< name of the dependent file that caused the action, excluding
the directory pathname but including the filename extension
$> name of the dependent file that caused the action, excluding
directory pathnames and filename extension
For example, your smakefile could contain the following target-
dependency line:
obj/new/test.o: src/new/test.c hdr/test.h
This line defines the source file as test.c located in the directory
src/new and the header file test.h located in the directory hdr. If
the source file test.c has a time stamp later than the target file
test.o, then the default macros will have the following values:
Macro Value
S@ obj/new/test.o
$? src/new/test.c
$* src/new/test
$ <test.c
$ >test
280 Chapter 10
smake M aintains and updates records of file dependencies
(continued)
Note: The value of each ofthese default macros changes after each
target-dependency line is processed.
Defining Transformation Rules
You can use transformation rules with macros to tell smake how to
make a file with a given filename extension from another file with a
different filename extension. Transformation rules are most useful
when you have several files with which you want to perform the same
action. smake uses transformation rules if you do not specify explicitly
the action required to create a certain target.
For example, you can have a transform ation rule that tells smake
how to create object files with extensions of .o from source files with
extensions of .c. Ifthe only action required to produce the object file
from the source file is a callto the co mpiler, your smakefile can
contain the following transformation rule:
.c.o:
sc $*
281 Utility Reference
smake Maintains and updates records of file dependencies
(continued)
Then, smake would compile source files (os.c and strbpl.c)
without an action line for each source file that explicitly specified the
call to the compiler:
.c.o:
sc $*
obj/os.o: os.c
obj/strbpl.o: strbpl.c
Using Fake Targets
Fake targets are a set of predefined targets that allow you to control
the behavior of smake. smake does not remake fake targets. Fake
targets allow you to set logical names, specify actions to be taken for
certain conditions, and suppress certain messages.
smake provides five fake targets:
.DEFAULT
.IGNORE
.ONERROR
.SET
.SILENT
The following list describes these targets in detail
.DEFAULT
specifies an individual action or a set of actions to be executed if
[] there are no actions specified for a given target-dependency line
[] there is no default transformation rule for the given target-
dependency pair.
The command line syntax used for the .DEFAULT target is as
follows:
.DEFAULT:
action- 1
action-2
.
.
.
action-n
282 Chapter 10
smake Maintains and updates records of file dependencies
(continued)
You can use .DEFAULT actions to display messages to the screen as
smake is running. For example, your smakefile can consist of the
following lines:
.DEFAULT:
; this target needs remaking $@
alpha.cpp: alpha.clp
If alpha.clp has a later time stamp than alpha.cpp, smake
will print the following message to your screen:
this target needs remaking alpha.cpp
.IGNORE
tells smake to ignore any error caused by the action lines.
Specifying . IGNORE is equivalent to calling smake with the -i
option. To specify . IGNORE, include the following line in your
smakefile:
.IGNORE:
.ONERROR
specifies an action or set of actions to be performed when smake
detects an error. For example, you may want to delete certain
temporary files or transfer them to a different directory if an error
occurs. Specify the actions to be taken after the . ONERROR target:
.ONERROR
action-l
action-2
.
.
.
action-n
.SET
allows you to set the values of logical name assignments (as created
by the assign command) from within a smakefile. When the
logical name is set from within a smakefile, the logical
name retains
283 Utility Reference
smake Maintains and updates records of file dependencies
(continued)
the specified value and will be in effect for any secondary processes
spawned from the main process. To specify . SET, use the following
format:
.SET: logical-name = value
The value may be any character, including a space. However, the
leading and trailing space characters are ignored.
For example, you can redefine the logical name INCLUDE as
follows:
.SET: INCLUDE: = df0:sc/examples
.SILENT
tells smake not to echo the action lines to the standard output
device before they are executed. Specifying . SILENT is equivalent
to calling smake with the -s option. To specify . SILENT, include
the following line in your smakefile:
.SILENT:
Using Multiple Targets
If you have several target files that are dependent on the same
dependent files, you can specify the target files together on the same
target-dependency line. For example, if prog.c, my file.c, and
newcode.c all included the header file stdio.h, you can use the
following lines in your smakefile:
prog.c myfile.c newcode.c: stdio.h
sc $@
Using Alternate Targets
Unless you specify an alternate target, smake remakes only the first
target file specified in the smakefile and, if necessary, any dependent
files needed to re-create the target file. However, your smakefile can
contain
target-dependency and actions lines for several targets. To tell
284 Chapter 10
smake Maintains and updates records of file dependencies
(continued)
smake to remake a target other than the first one specified in the
smakefile, enter the name of the target on the smake command line:
smake target-name
For example, you can have the following smakefile that specifies two
targets, clean and backup:
clean:
delete S(OBJ)files.o.Ds
delete $(OBJ)os.o
delete $(OBJ)strbpl.o
backup:
copy files.c to df1:
copy os.c to df1:
copy strbpl.c to df1:
If you enter the smake command without specifying a target, smake
runs the commands listed under clean. To run the commands listed
under backup, you must use this command line:
smake backup
Using Local Input Files
From within a smakefile, you can create a temporary disk file
containing instructions that is passed to AmigaDOS when you run
smake. Local input files are useful when you need to enter command
lines that are too long to fit on one line.
Any macros defined in the smakefile can be used within a local input
file. Local input files are automatically deleted before smake
terminates.
You can construct a local input file with action lines as follows:
command <[preface] <[!] [(filename)]
statement1
statement2
.
.
.
statementn
285 Utility Reference
smake Maintains and updates records of file dependencies
(continued)
where:
command is the command to be handed to AmigaDOS.
preface is any text or symbol to be passed to AmigaDOS before
the temporary filename. The preface may contain
spaces.
tells smake to create a local input file containing the
statements you specify but not to pass the filename as
part of the generated command line.
filename is the name of the local file. If you do not specify a
name, smake uses the temporary filename
temp _ smake . tmp. If you specify a filename, enclose
the filename in parentheses, and do not enter spaces
before or after the filename.
statementl-n are the statements that you want included in the local
input file.
The following example shows a smakefile that uses macros and a
local input file to create the target grep. grep is a utility that is
composed of C source files and one assembly language module, the
startup module c.a.
1 # Generate an Updated version of GREP
2
3 # Define macros
4 SCHDRS = grep.h pat.h
5 OBJ = obj/
6 FLAGS = IDIR=INCLUDE: IDIR=INCLUDE:sc/ OUT=$(08J)
7 SC = SC:sc
8
9 # Specify file dependencies for GREP executable, generate link
10 # command to be passed to AmigaDOS, then specify contents of
11 # WITH file .
12 grep: $(oBJ)grep.o $OBJ)c.o $(OBJ)-main.o $(OBJ)re_gen.o
13 grep: $(OBJ)re_match,c S(OBJ)os.o
14 slink <WITH <
15 FROM $(OBJ)c.o+$(OBJ)grep.o+$(OBJ)-main.o+$(OBJ)re_gen.o
16 FROM $(OBJ)re_match.o $(OBJ)os.o
17 TO grep
18 LIBRARY LIB:sc.lib+LIB:amiga.lib
286 Chapter 10
smake Maintains and updates records of file dependencies
(continued)
19 <
20
21 # Specify remaining file dependencies for file needed to generate
22 # GREP executable.
23 $(OBJ)grep.o: grep.c $(LCHDRS)
24 $(SC) 5(FLAGS) define GREP grep
25
26 $(OBJ)c.o: c.a
27 asm -iinclude: -o$(OBJ)c.o c.a
28
29 $(OBJ) main.o: main.c
30 $(SC) 5(FLAGS) define GREP main
31
32 $(OBJ)re_gen.o: re_gen.c S(LCHDRS)
33 $(SC) $(FLAGS) define GREP re_gen
Note: Do not enter line numbers in your smakefiles. Line numbers
are included here for use in the discussion that follows.
Lines three through seven define macros. Lines 12 and 13 list the
files that must be current before smake can remake the grep target.
If a target has too many dependent files to fit on one line, retype the
target filename and colon on the next line, and enter the remaining
dependent filenames.
Line 14 tells smake to
1. create a local input file, using the default temporary filename,
that contains all the lines up to the less than (<) sign in line 19
2. execute slink to generate the target grep
3. pass the local input file to slink as a local input file.
smake generates the following command and passes it to AmigaDOS:
slink WITH temp_smake.tmp
The temporary file temp_smake.tmp contains the following lines:
FROM $(OBJ)c.o $(OBJ)grep.o $(OBJ)-main.o $(OBJ)re-gen.o
FROM $(OBJ)re_match.o $(OBJ)os.o
TO grep
LIBRARY
LIB:sc.lib+LIB:amiga.lib
287 Utility Reference
smake Maintains and updates records of file dependencies
(continued)
Using Default (.def) Default files are smakefiles that smake searches whenever
your
Files smakefile does not specify what action is required to create a target.
smake provides a default file called smake.def.
To determine what action to take to create a target, smake looks for
instructions in the following order:
1. actions specified below the dependency relation.
2. transformation rules in your smakefile.
3. .DEFAULT rules specified in your smakefile or in the smake .
def file.
4. rules taken from an alternate .def file.
5. rules taken from a file named smake .def in the current
directory.
6. rules internal to this implementation of smake. smake internal
rules are the same rules that are in the default smake .def file.
However, editing smake.def does not change the internal rules.
Using the smake.def File
smake provides a default file, smake.def, that contains the basic
command for compiling and linking a file, and it contains
transformation rules for converting assembly language, C source code,
and header files into object files. You can change these rules as
necessary by editing smake.def .
smake.def contains the following:
sc = sc:sc
SCFLAGS = IDIR=INCLUDE:
ASM = SC:asm
LINK = SLINK:slink
.DEFAULT:
$(SC) $(SCFLAGS) $*
.a.o:
$(ASM) $* -iinclude: -o$*.o
.c.o:
$(SC)
$(SCFLAGS) $*
288 Chapter 10
smake Maintains and updates records of file dependencies
(continued)
.h.o:
delete $*.o
$(SC) $(5CFLAGS) $*
Creating and Using Your Own Default File
You can create your own default files. To use a.def file other than
smake.def, specify the -b option on the smake command line as
follows:
smake -bfilename.def
Your default file must have the file extension .def .
Running smake You can run smake from the Workbench or from the CLI.
To run smake from the Workbench, double-click on the Build
icon. smake looks for the smakefile in your current directory. The
default file names that smake looks for, in the order in which it looks
for them, are as follows:
1.smakefile
2.smakefile.smk
3.lmkfile
4.lmkfile.lmk
5.makefile
To use a different smakefile name, specify the -f option as described
later in this section. To specify options, define macros, or specify
alternate targets for the Build icon, select the Build icon, choose
Information from the Icons menu, and add the necessary
parameters in the Tool Types box.
When rurming smake from the Workbench, the search order of files
is based on the assignment of the device smake _ files: . You can
assign a value to this device using the following command (from the
CLI):
assign smake_files: your-device:
When no assignment has been made, smake searches the current
directory for the
required files.
289 Utility Reference
smake Maintains and updates records of file dependencies
(continued)
To run smake from the CLI, enter the smake command as follows:
smake [options] [macro definitions] [targets]
As with the suild icon, smake looks for one of the three default
smakefile names in your current directory. To use a different smakefile
name, specify the -f option as described later in this section.
smake supports the following options:
-a rebuilds all targets and subtargets without regard to time
stamps.
-b file uses the . def file you specify instead of the default file
smake.def.
-c tells smake to record everything it would have done if it had
executed the command you entered. When you specify the -c
option, smake does not execute the command you enter.
Instead, it creates a batch file containing all the instructions
it would have executed if you had not specified the -c
option. This file is named smakefile.bat in the current
directory, and you can run it by entering the following on the
command line:
execute smakefile.bat
-d prints detailed debugging information about the processing of
the smakefile.
-e erases any out-of-date targets before remaking them.
-ffile uses the filename you specify as the input smakefile. smake
attempts to locate the file with the exact name you have
specified. If this search is unsuccessful, smake searches for a
file with the name you specified plus an extension of
.smake. For example, suppose you have an executable
named alpha and a smakefile named alpha.smake in the
same directory. If you specify smake -falpha, smake will
assume that alpha is your smakefile. If you receive an error
message such as Line too long or Unexpected
punctuation, try renaming your file with an explicit
.smake extension and running smake with the full
filename.
290 Chapter 10
smake Maintains and updates records of file dependencies
(continued)
-h prints help information and then exits.
-i ignores errors caused by executing the actions. Both the -k
and -i actions should be used with caution because smake
will continue running. The -k option incorporates all of the
functionality of the - i option.
-k ignores error returns from actions passed to AmigaDOS and
from smake not knowing how to make certain targets. Both
the -k and -i actions should be used with caution because
smake will continue running. The -k option incorporates all
of the functionality of the - i option.
-n displays the actions smake would have taken, but smake
does not execute these actions.
-p prints target descriptions and expanded macros.
-q determines if the target file is current. smake prints a 1 if
the target is current or a 0 if it is not. smake will not
execute any actions.
-s does not echo actions to the screen before executing them.
-t touches the target files by updating them with the current
system time. smake does not execute any of the actions
associated with these targets.
-u rebuilds unconditionally all targets and subtargets without
regard to time stamps.
-x is for UNIX compatibility. If you specify this option, smake
attempts to detect any features of the smakefile that would
prevent it from working correctly with the llNIX make
utility.
Examples of such features are:
[] using a local input file
[] defining an action line without an initial tab character
[] specifying multiple target files on a single target-
dependency line.
In each case,
smake displays a message describing the incompatibility.
291 Utility Reference
splat Searches for and replaces patterns that match regular expressions
Synopsis splat [>destination] [options] pattern string file . .
Description
splat replaces all occurrences of pattern with string in each file that
you specify. splat does not overwrite the original version of the file
unless you specify the -o option. If you do not redirect the output by
specifying a greater than (>) sign followed by a destination, splat
places the changed file in either a temporary file or, if you use the -d
option, in the specified directory. splat uses the same root filename
with an extension of .$$$.
You must use the rules recognized by grep for specifying the
pattern and string. For example, to specify a string that contains spaces,
you must enclose the string in double quotes. For additional
information, see the description of the grep utility earlier in this
chapter.
splat supports the following options:
-ddirectory
specifies the directory where you want splat to place the new
files. Using this option leaves the original versions untouched. If the
specified directory does not exist, splat attempts to create it. If
the attempt fails, splat displays an error message. The -o and -d
options are mutually exclusive.
-o
tells splat to overwrite the original version of the file with the
new version. The -o and -d options are mutually exclusive.
-s
displays the name of the file on which splat is currently working.
It also displays a message saying that no substitutions have been
performed if it was unable to find the specified pattern in the file. If
you do not specify -s, splat performs its task silently.
-v
displays all lines in which substitutions are made, but it does not
create new versions of the files. You can use this option to
determine the changes that splat will make to your files.
Examples
For example, suppose you want to substitute INT for int in every
declaration of an integer identifier in your C source files. The following
command replaces int with INT in all files with the .headers and
.source extensions in your current directory. It writes the new
versions of these files in the directory named /backup.
splat -d/backup/ int INT N?.headers #?.source
292 Chapter 10
splat Searches for and replaces patterns that match regular expressions
(continued)
However, you do not want calls to printf to become prINTf.
Because in these declarations, the string int is followed by a space
character, you should use the following command instead:
splat -d/backup/ "int 1" "INT " #?.headers #?.source
Similarly, the following command performs the same substitutions, but
it writes the new versions of the files in the subdirectory backup of
the current directory:
splat -dbackup/ "int " "INT " #?.headers #?.source
To avoid errors such as replacing printf with prINTf, you can use
the -v option to determine, without changing your source files or
creating new files, if you have entered the correct command. The
following command performs the same substitutions as the previous
command and displays those changes on the screen, but it does not
change the files:
splat -v "int " INT " #?.headers #?.source
The following command replaces all occurrences of the string
un signed char with ehar within all files with the .c extension in
the current directory:
splat "unsigned char" char #?.c
The following command appends the string -cc to the end of each
line that contains the string sc1 in the file comp.bat:
splat -dbak/ "sc1.*$" " -ccll comp.bat
The pattern sc1.*$ matches any string beginning with sc1 followed
by O or more of any character and ending with the end of the line.
The string& -cc appends a space followed by -cc to the end of the
line.
293 Utility Reference
splat Searches for and replaces patterns that match regular expressions
(continued)
You can also use splat to insert lines in a file or to break single
lines into multiple lines. For example, you can have a file named
text.c that contains the following line:
parms(s);usage();exit(l);
Suppose you want the calls to usage and exit to be on separate
lines and indented one tab stop; enter the following command (all on
one line):
splat parms(s);usage();exit(1); parms(s);\n\tusage();
\n\texit(1);\n\ttext.c
294 Chapter 10
tb Displays traceback information
Synopsis tb [>destination] [options] [tbfile [program]]
Description
The tb utility processes the traceback file that is created when you
link your program with catch.o and your program terminates
abnormally.
To get traceback information for your program, you must link your
program with catch.o. If your program terminates abnormally,
catch.o creates a standard IFF format file named Snapshot . TB in
your current directory. This file contains up to six sections:
[] symbol cross reference
[] stack
[] registers
[] environment
[] memory
[] user data.
Each section contains information about your program at the time it
terminated. (Two sections, memory and user data, may not be available
for your program.)
tb displays the traceback information on the screen unless you
redirect it by specifying a greater than (>) sign followed by a
destination.
If you do not specify any options, tb displays only the current stack
frame, which indicates the location where the program terminated. By
specifying options, you can print 211 of the sections in the traceback
file.
By default, tb looks for the traceback file Snapshot . TB in your
current directory. If you want tb to use a different traceback file,
specify the traceback file as the tbfile parameter.
The program parameter specifies the program from which you want
tb to read debugging information. If you do not specify program, this
utility uses the program specified in the traceback file.
Note: Specifying a program is useful when you have two
executables of your program: one created with debugging information
and another without debugging information. The version without
debugging information loads faster, but you still have access to the
traceback
information if your program crashes.
295 Utility Reference
tb Displays traceback information
(continued)
tb supports the following options:
-l displays all sections present in the traceback file
-x displays the location of all symbols encountered in the program
-s displays the contents of the entire stack at the time your program
terminated
-r displays the current contents of registers at the time your
program terminated
-v displays the callback chain and the location where the program
terminated
-m displays the amount of memory available at the time your
program terminated (if present in Snapshot.TB)
-u displays any user data generated by your program (if present in
Snapshot.TB).
Examples
Suppose you have a program named testit that you link with
catch.o, and testit terminates abnormally when you run it. You
can display information about where the program terminates by
entering the tb command without any options, as follows:
1> tb
Program Name: testit; run from CLl
Program load map (addresses are APTRs, sizes are in bytes)
220f78 $1110 211268 $5b4
Terminated with GURU number 00000005, Divide by Zero Error
Error occurred at address 221cde = _foo line 5
called from 22156a = main line 11
called from 221c60 = _main + 704
called from 2210ca = hunk 0 + $152
However, the file created by catch.o contains much more
information. To display all of the information contained in
Snapshot.TB, you can specify the -l option, as follows:
1> tb -1
TraceDump 0.88
Copyright (c) 1988 The Software Distillery
296 Chapter 10
tb Displays traceback information
(continued)
TraceDump Utility: catch.o; Version 1, Revision O
Processor type: 68000
VBlankFreq 60, PowerSupFreq 60
Symbols for hunk O
_foo = 22153c _main = 22155c
Program Name: testit; run from CLI
Program load map (addresses are APTRs, sizes are in bytes)
220f 78 S 1110 21 1268 $5b4
Terminated with GURU number 00000005, Divide by Zero Error
Error occurred at address 221cde = _foo line 5
called from 22156a = main line 11
called from 221c60 = _main + 704
called from 2210ca = hunk 0 + S152
Registers:
DO=00221cde D1=00000000 D2=00000001 D3=00002718
D4=00000001 D5=0000002b D6=0000003b D7=00000000
A0=00221f54 A1=00243fcc A2=0024460a A3=00225c68
A4=00211268 A5=002445be A6=002033c8 A7=002445ae
PC 221cde C=0 V=0 Z=1 N=0 X=0
stack top: 244640, stack pointer: 2445ae, stack length: $94
entire stack, size = $94 bytes
2445AE: 000003ED 00221558 0000002B 00000000: ...m.".X...+....
2445BE: 002445CA 0022156A 00225C68 002445F6: .$EJ.".j."h.$E.
2445CE: 00221C60 00000001 00211620 00225CC4: .".'.....!. ."D
2445DE: 00226030 00225C68 83D10000 00000021: ."'0."h.Q.....!
2445EE: 13230021 00211620 00244640 002210CA: .#.!.!..$F@.".J
2445FE: 00244602 74657374 6974000A 00000022: .$F.testit...."
24460E: 60300000 27100000 27180000 00010000: '0'..'...'.....
24461E: 002B0000 003B0022 60300022 61300020: .+...;."'0."a0.
24462E: 35300022 0F740024 464400FF 425800FF: 50.".t.$FD..BX..
24463E:
424C0022 :
BL."
297
Part3
Using the SAS/C
Macro Assembler
Chapter 11 Using Assembly Language with C Language
288
299
11 Using Assembly Language
with C Language
299 Introduction
300 Writing Assembly Language Functions
300 Writing Assembler Statements
304 Using Assembler Directives
308 Defining and Using Macros
309 Defining Control Sections
314 Communicating between Assembly Language and C Language
314 Calling Assembler Functions from C Functions
322 Calling C Functions from Assembler Functions
322 Referencing Global Data
323 Running the Assembler
Introduction
The SAS/C Macro Assembler reads an assembly language source file
and produces an object file in the Amiga object file format. You can
use the assembler to generate assembly language modules for your C
programs, or you can generate programs written entirely in assembly
language. For example, some operations such as directly accessing CPU
and I/O registers cannot be handled easily in the C language. Also,
assembly language is sometimes necessary to get the best combination
of code size and speed.
The assembler supports the full set of 68xxx mnemonics, an
extensive set of assembler directives, and a powerful macro facility. To
use the assembler, you should understand thoroughly the Motorola
68xxx instruction set. The "Additional Documentation" section in
"Using This Book" lists books that describe the Motorola 68xxx
instruction set. If you are writing assembly language modules to be
called from C functions, or if your assembly language modules call C
functions, you should also understand the SAS/C function protocol.
This chapter assumes that you have a knowledge of assembler, but not
necessarily the SAS/C Macro Assembler.
This chapter describes the directives supported by the assembler,
discusses how to write and use macros, and describes how to call C
functions and
assembler modules.
300 Chapter 11
Writing Assembly Language Functions
The following sections provide an overview of the syntax expected by
the SAS/C Assembler. The topics covered include
[] the format of assembler statements
[] the directives supported by the Assembler
[] how to create and use macros
[] how to define control sections
[] how to specify addresses in assembler statements
[] how to specify floating-point data
[] the offsets supported by branch instructions.
Writing Assembler Statements
Each assembly language source line has the following format:
[label:] operation[.size] operand . . . [;comment]
You can enter white space (spaces or tabs) before any field. You
must enter white space between the operation and operand. The fields
of the source line are described below:
label
can start in any column and end with a colon, or can start in
column one and end with either a colon or white space. A label can
be up to 31 characters long and can contain letters, digits,
underscores (_), and dollar ($) signs. A label cannot start with a
digit, and the case of letters is significant. For example, the
assembler differentiates between xYz, xYZ, and xyz.
operation
is the name of an instruction, a directive, or a macro. Do not begin
an operation in column one. If no label is present, precede the
operation with white space. If a label is present, you must include a
colon or white space between the label and operation. The case of
this field is not significant. For example, MOVE is the same as
move.
size
specifies either the size of the operands or the offset, depending on
the type of instruction. See the following section, "Specifying Sizes,"
for additional information.
operand
may contain 0 or more expressions, depending on the specific
operation. Expressions are composed of constants, variables, and
operators. The information in the following section, "Specifying
Expressions," describes constants and operators in more detail.
301 Using Assembly Language with C Language
comment
can be entered in your assembler source code by preceding the
comment text with a semicolon.
Specifying Sizes
Support for size suffixes depends on the instruction that you enter and
the processor that you use. Check the documentation for your
processor to determine which size suffixes are valid. For most non-
floating-point instructions, the following suffixes are valid:
Suffix Meaning
none defaults to word (two bytes)
B byte
L long
S short (same as byte)
W word
For floating-point instructions, the following suffixes are valid:
Suffix Meaning
none defaults to word
B byte
D double
L long
P packed
S single
W word
x extended
302 Chapter 11
For branch instructions BSR and BRA, the sizes supported by the
assembler are as follows:
Suffix Meaning
none calculates the size offset needed. For externs, the assembler
generates a 16-bit offset.
s generates 8-bit offsets.
B generates 8-bit offsets.
w generates 16-bit offsets.
L generates 32-bit offsets.BSR.L is supported only on the 68020
and higher processors, and you cannot use BSR.L to branch to
externs.
For example, the following instruction creates a 32-bit branch:
BRA.L subpr
Data are converted into single, double, or extended precision
according to the type of instruction. For example, the following
instruction converts 2.1 into single precision and stores it in floating-
point register 1:
fmove.s #2.1,fpl
As an additional example, the fmove instructions for the decimal
number 2.1 specifying the bit pattern in hexadecimal are as follows:
fmove.s #$40066666,fpl
fmove.d #$4000CCCCCCCCCCCD,fPl
fmove.x #$400000008666666666666666,fpl
Specifying Expressions
As described earlier, an expression is composed of constants, variables,
and operators.
A variable is a label name or a name defined using an assembler
directive.
303 Using Assembly Language with C Language
A constant is a decimal, hexadecimal, octal, or binary mlmber, or an
ASCII literal. Unless you specify otherwise, the assembler expects a
decimal number. To specify an ASCII literal, enclose the literal in
single quotes. To specify a hexadecimal number, precede the number
with a dollar sign. To specify an octal number, begin the number with
an at (@) sign. To specify a binary number, begin the number with a
percent (%) sign. The following table shows how to enter different
types of constants:
Type or Base Prefix Example
decimal none 1234
ASCII literal 'literal' 'AC9T'
hexadecimal $ $89AB
octal @ @743
binary % %1011
floating point none 2.1
scientific notation none 2.1E+10
hexadecimal floating point $ $4066666
Note: If you use hexadecimal notation to specify floating-point
numbers, you must use either the IEEE or FFP bit pattern
representation. For information about this representation, refer to a
manual for the 6888x math coprocessor.
The following table lists the operators recogni~ed by the assembler in
the order in which they are processed.
Order Operator Meaning
1 - unary minus
2 >> right shift
<< left shift
(continued)
304 Chapter 11
Order Operator Meaning
3 * multiply
/ divide
% modulus
4 + add
- subtract
5 < less than
<= less than or equal to
> greater than
>= greater than or equal to
== equal to
!= not equal to
6 & bitwise AND
! bitwise OR
For example, in the following expression, PDQ is first negated and
then multiplied by DEF, and the result is added to ABC:
ABC+DEF*-PDQ
Each expression represents a 32-bit value. An absolute expression is
one that contains only constants. A relocatable expression contains
symbols whose values are determined during the linking and loading
procedure.
Using Assembler Directives
With the exception of the DC, DCB, and DS directives, an assembler
directive is an instruction to the assembler instead of an instruction to
be translated into object code. Directives cannot begin in the first
character of the input line.
The assembler supports the following directives:
[label] CNOP offset,alignment
aligns any data structure or entry point to any boundary. alignment
is the alignment required for the base, such as 4 for long word, and
offset is the
offset from that alignment.
305 Using Assembly Language with C Language
CSECT name,type,align,rtype,rsize
defines section type and alignment requirements. The section
"Defining Control Sections," later in this chapter, discusses the
CSECT macro.
[label] DC[.size] expression[,expression] . . .
defines a constant value in memory.
[label] DCB[.size] n,expression
defines a constant block in memory. Using the DCB directive is
equivalent to using the DC directive n times.
[label] DS[.size] n
reserves (defines) n memory locations of the size indicated by .size.
ELSE
begins an alternative for the IF directive.
[label] END
defines the end of the program.
ENDC
defines the end of conditional assembly. This directive turns off
each of the IFxx directives.
ENDM
ends a macro definition.
label EQU expression
assigns permanently the value of expression to label.
label EQUR register
equates an address or data register with label.
EXITM
exits the macro expansion. This directive is a synonym for MEXIT.
FAIL
generates an error for the next input line.
FORMAT
is included for compatibility only.
IDNT name
defines a program unit name.
IF expression
assemb]es the following statemeIIts to the next ELSE or ENDIF if
the expression supplied as its argument is not 0. IF statements may
be nested.
IFC string, string
assembles if
the strings are identical.
306 Chapter 11
IFD symbol
assembles if the symbol is defined.
IFEQ expression
assembles if the expression is 0.
IFGE expression
assembles if the expression is greater than or equal to 0.
IFGT expression
assembles if the expression is greater than 0.
IFLE expression
assembles if the expression is less than or equal to 0.
IFLT expression
assembles if the expression is less than 0.
IFNC string,string
assembles if the strings are not identical.
IFND symbol
assembles if the symbol is not defined.
IFNE expression
assembles if the expression is not equal to 0.
INCLUDE "filename"
includes external files into the source. You can nest INCLUDE
directives up to a depth of 3.
LIST
tells the assembler to produce a listing file.
LLEN n
sets the number of characters per line in the listing file. n can be
any value from 60 to 132. The default value is 132 characters.
label MACRO
begins a macro definition. The following section, "Defining and
Using Macros," describes how to define and use macros.
MASK2
is included for compatibility only.
MEXIT
exits the macro expansion. This directive is a synonym for EXITM.
NARG
is the reserved symbol to which the assembler assigns the index of
the last argument passed to the macro in the parameter list.
NOFORMAT
is included for
compatibility only.
307 Using Assembly Language with C
Language
NOLIST
tells the assembler to stop producing a listing file.
NOPAGE
tells the assembler to stop inserting page breaks and title headers in
the listing file.
NOOBJ
stops the production of the object file.
OFFSET n
defines offsets. To define a table of offsets using the DS directive,
you use the OFFSET directive. To end an offset section, use a
RORG, OFFSET, SECTION, or END directive.
OPSYN oldname newname
defines a synonym for opcodes.
PAGE
inserts a page break into the listing file.
PLEN n
sets the number of lines per page in the listing file. n can be any
value from 24 to 100. The default is 60 lines.
label REG R1[-R2][/R3 [-R4]] . . .
assigns permanently the register list to label. You can specify
individual registers by separating each register with a slash
(R1/R2/R3), or you can specify a range of registers by specifying
the first and last registers separated with a hyphen (R1-R3). You
can also combine individual registers with a range of registers
(R1/R3-R5/R7). The assembler translates this list into the register
list mask format used by the MOVEM instruction.
[label] RORG n
sets the program counter to n bytes from the start of the current
relocatable section.
[label] SECTION name[,type]
defines a program section. name is a character string, and type must
be CODE, DATA, or BSS. The section "Defining Control Sections,
later in this chapter, discusses the SECTION macro.
label SET expression
assigns temporarily the value of the expression to the symbol
identified by label.
SPC n
skips n blank
lines in the listing file.
308 Chapter 11
TTL title
sets the title string that is printed in the page headers in the listing
file. The title can be no longer than 40 characters.
XDEF label[,label] . . .
defines an internal label as an external entry. By using the XREF
directive, you can then refer to the symbols generated by these
labels from other modules and from routines written in the C
language.
XREF label[,label]. . .
references an external symbol defined with the XDEF directive.
Defining and Using Macros
You can define a macro using the following sequence of directives and
instructions:
label MACRO
.
.
.
ENDM
You must begin the definition with a MACRO directive on a line by
itself. After the MACRO directive, enter the lines that constitute the
macro procedure. End the macro definition with the ENDM directive on
a line by itself. You can use the EXITM directive within the macro
procedure to exit the macro before the ENDM directive.
For example, you could define a macro called acopy as follows:
acopy MACRO
move.w 4(sp),\1
move.l 6(sp),\2
ENDM
You can invoke this macro with the following statement:
acopy d0,a5
The assembler expands the macro as follows:
move.w 4(sp),d0
move.l 6(sp),a5
309 Using Assembly Language with C Language
Defining Control Sections
The SAS/C Macro Assembler does not assume any default control
sections. You must use either the SECTION or CSECT directive before
you define any code or data. A SECTION or CSECT directive defines
the beginning of a relocatable control section. Pararneters on these
directives allow you to name each control section. The assembler uses
these named control sections to control the location of data and code
during linking.
Chapter 12, "How Does the Compiler Work?," in SAS/C
Development User's Guide, Volume I, describes the sections produced
by the compiler.
Using the SECTION Directive
The SECTION directive follows this format:
[label] SECTION name[,type]
The following list describes each of the parameters.
name specifies the name of the control section. You can use the name
__MERGED for near data. You can use a specific name only
once in a given asm file.
type specifies the type of section. The type can be BSS, DATA, or
CODE.
Specifying Addresses with the SECTION Directive
You can define symbols to be in the data section by USillg XREF and
XDEF after the SECTION directive. The following exarnple uses 16-bit
addressing to reference both code and data:
SECTION __MERGED,DATA
XREF xdata
data1 DC.W 10
data2 DC.L 20
.
.
.
SECTION TEXT,CODE
XREF cfunc
XDEF afunc
afunc JSR cfunc(PC)
MOVE.W data1(A4),D0
MOVE.L data2(A4),D1
MOVE.L d1,xdata(A4)
310 Chapter 11
To use 32-bit addressing, remove references to the register A4 and to
the Program Counter (PC).
Using the CSECT Directive
The CSECT directive follows this format:
CSECT name[, type][, align][, rtype][, rsize]
The name and type parameters describe the control section being
defined. The rtype and rsize parameters define how to access the
information in the section. The align parameter is ignored. The
following list describes each of the parameters:
name specifies the name of the control section. You can use the name
__MERGED for near data. You can use a specific name only
once in a given asm file.
type specifies the type of section. A value of 0 indicates a code
section, 1 indicates a data section, and 2 indicates an
uninitialized data section (like the udata section used by the
compiler). The default value is 0 (code).
align specifies the alignment requirements of the control section as a
power of 2. For example, an alignment of 1 means that the
section will begin on an even address, and a value of 2 means
that the section will begin at an address divisible by 4.
Note: This parameter is not used on the Amiga. All sections
are long-word aligned.
rtype specifies whether the code or data in the section are addressed
relative to register A4 or to the PC. The default value is 0.
rsize specifies the size of the offset for the address. If you specify an
rsize of 4, the assembler uses absolute addressing. If you
specify an rsize of 2, the assembler uses the value of rtype to
determine how to address code or data in the section. The
default
value is 4.
311 Using Assembly Language with C Language
The following table summarizes the valid types and sizes of
relocation information on the 68000:
rtype rsize Description
0,1,2 4 32-bit absolute address
0 2 PC-relative address (code section)
1 2 A4-relative address (data section)
2 2 A4-relative address (BSS section)
Specifying Addresses with the CSECT Directive
By specifying parameters in the CSECT directive, you can generate
assembler modules that are compatible with C programs compiled with
the data=near (base-relative data) and code=near (program
counter-relative addressing) compiler options.
You can force address register-relative addressing of data in the BSS
section by specifying an rtype of 2 and an rsize of 2. Any XREF
statements for external data elements must appear after the CSECT
statement, and all data must be addressed relative to register A4. For
example, the following code moves data around:
CSECT __MERGED,1,,2,2
XREF xdata
datal DC.W 10
data2 DC.L 20
.
.
.
CSECT TEXT,0
MOVE.W datal(A4),DO
MOVE.L data2(A4),D1
MOVE.L d1,xdata(A4)
Note: If the XREF statement for the external data precedes the
CSECT statement, you can use a standard reference to a four byte
external address.
You can force program counter-relative addressing of data in the
code section by specifying an rtype of 0 and an rsize of 2. The
XREF statement for the external function must appear
after the CSECT
312 Chapter 11
statement. and the function must be called relative to the program
counter. For example, the following code calls the function cfunc
relative to the PC:
CSECT TEXT,0,,0,2
XREF cfunc
XDEF afunc
afunc JSR cfunc(PC)
RTS
Note: If the XREF statement for the external function precedes the
CSECT statement, you can use a standard JSR instruction to a 4-byte
external address.
In addition to specifying addresses relative to address registers and
to the program counter, you also can specify absolute addresses or
enter immediate data. The following tables summarize the addressing
modes supported by the SAS/C Assembler and provide examples of
each mode. The notation used in these tables is as follows:
Notation Meaning
Anan address register (a0 a7)
bda 32-bit byte displacemer1t
data actual data you want loaded into the register
Dn a data register (d0--d7)
d8 an 8 bit displacement
d16 a 16-bit displacement
od the 32 bit outer displacement
PC program counter
Xn an index register (a0.w--a7.1)
xxx any number in decimal, hexadecimal, octal, or binary format
You can specify the displacements, data, and numbers in decimal,
hexadecimal, octal, or binary format. The information on entering
operands in the section "Writing Assembler Statements," earlier in this
chapter,
describes how to specify each type of constant.
313 Using Assembly Language with C Language
Note: All fields of the operands on the addressing modes marked
68020 are optional.
The following table shows examples of register-direct addressing
modes:
Mode Example
Dn add.w d1 ,d0
An addq.w #1 ,a1
The following table shows examples of register-indirect addressing
modes:
Mode Example
(An) add.w (a1) ,d0
(An)+ add.w (a1)+,d0
-(An) add.w -(a1),d0
d16(An) add.w 10(a1),d0
d8(An,Xn) add.w 10(a1,a2.l),d0
bd(An,Xn) add.w $10000(a1,a2.l),d0 (68020 only)
([bd,An],Xn,od) add.w ([10,a1],a2.l,20),d0 (68020 only)
([bd,An,Xn],od) add.w ([10,a1,a2.l],20),d0 (68020 only)
The following table shows examples of absolute addressing modes:
Mode Example
(xxx).W add.w (100).w,d0
(xxx).L add.l (100).l,d0
314 Chapter 11
The following table shows how to specify immediate data:
Mode Example
#data add.1 #100,d0
The following table shows examples of program counter-relative
addressing modes:
Mode Example
d16(PC) add.w 10(PC),d0
d8(PC,Xn) add.w 10(PC,a2.l), d0
bd(PC,Xn) add.w $10000(PC,a2.l) (68020 only)
([bd,PC],Xn,od) add.w ([10,PC],a2.l,20),d0 (680Z0 only)
([bd,PC,Xn],od) add.w ([10,PC,a2.l],20),d0 (68020 only)
Communicating between Assembly
Language and C Language
The following sections describe how to call assembler functions from C
functions and how to call C functions from assembler modules.
Calling Assembler Functions from C Functions
Assembler modules may be called from C functions in three ways:
[] passing parameters by placing them on the stack. Unless you specify
the parameters=register option or use the __asm keyword, C
functlons pass parameters on the stack.
[] compiling your program with the parameters=register option.
This option tells the compiler to pass parameters in registers, but it
allows the compiler to determine which registers to use.
[] using the __asm keyword and specifying which registers
parameters are placed in.
Passing parameters in registers produces a faster, smaller executable
module.
315 Using Assembly Language with C Language
Passing Parameters on the Stack
As previously stated, C functions pass parameters on the stack if you
do not specify the parameters=register option or use the __asm
keyword.
For example, the following assembler module, func, adds or
subtracts an integer argument and a double argument depending on
whether a plus ( + ) sign or a minus (--) sign is passed in the
character argument.
; NOTE: This code assumes that you have a math co-processor.
;If you do not, your machine will crash when you run
;this program.
xdef _func
section code
_func:
fmove.d 8(a7),fp0 ; middle
cmpi.b #'+',7(a7) ; should I add?
bne.b noadd ; no, check subtract
fadd.l 16(a7),fpO ; add 'mrright' to 'middle'
bra.b exitpoint ; ready to return
noadd:
cmpi.b #'-',7(a7) ; should I subtract?
bne.b nosub ; no, exit with error
fsub.l 16(a7),fp0 ; subtract 'mrright'
bra.b exitpoint from 'middle'
nosub:
fmove.b #-1,fpO ; return -1 for error
exitpoint:
fmove.l fp0,d0 ; return 'int' in d0
rts
end
The func assembler module returns an integer.
316 Chapter 11
To call an assembler module from your C program, include the
prototype for the assembler module in your C source file before calling
the function. The prototype for the previous example is the following:
int func (char lefty, double middle, int mrright);
For example, you can write the following program to call the f unc
module:
#include <stdio.h>
int func(char lefty, double middle, int mrright);
void main(void)
{
char lefty;
double middle;
int mrright;
lefty = '+';
middle = 12345.;
mrright = 99;
printf("func(+) = %d\n", func(lefty, middle, mrright));
}
If you save the assembler module func in a file named testa.a, you
can assemble test.a with the following command:
asm -m2 testa.a
If you save the C source code in a file named test, you can compile
and link test with the following commands:
sc math=868881 test
slink lib:c.o test.o testa.o lib lib:sc.lib
The test program will pass parameters on the stack. When you run
test, you should see the following output:
func(+) = 12444
317 Using Assembly Language with C Language
To use the parameters inside your assembler module, you must
retrieve the parameters from the stack. The arguments are placed on
the stack from right to left; that is, the leftmost argument is
immediately above the 4-byte return address in the stack. For example,
in the following function call, the compiler generates code to push the
arguments mrright, middle, and then lefty onto the stack.
char lefty;
double middle,
int mrright;
func(lefty,middle,mrright);
Next, the func module is called, and the return address is pushed
onto the stack. Figure 11.1 shows the stack after the func module has
been called.
Figure 11.1 | Bottom of Stack |
The Stack after the | |
func Module Is High | mrright |
Called Memory | | <-- A7+12+n
| middle |
| | <-- A7+8+n
| lefty |
| | <-- A7+4+n
| return address |
| | <-- A7+n
Low | work area |
Memory | of size n |
| |
| Top of Stack |
The arguments mrright, middle, and lefty use 4 bytes, 8
bytes, and 4 bytes, respectively.* Register A7 is the stack pointer, and
it points to the 4-byte return address.
Note: If you specify the shortintegers option, integers will be
2 bytes instead of 4.
Before retrieving arguments from the stack into non-scratch
registers, you must first save the contents of those registers, so they
--------------------------------------------------------------------------------
* The smallest item that can be pushed onto the stack is the size of an integer.
The size depends on whether you specify the shortint compiler OptiOII. A char
will be promoted to an int.
318 Chapter 11
may be restored when your function terminates. Scratch registers are
registers D0, D1, A0, A1, FP0, and FP1.
The following list describes the steps your assembler module should
take to save register values and establish frame pointers. In these
steps, n refers to the size of your work area in bytes.
1. Enter the SUBI instruction if you need local storage:
SUBI n,A7
2. Save registers D2 through D7, A2 through A6 if they will be
changed during execution of the module.
3. Save floating-point registers FP2 through FP7 if a 68881 math
coprocessor is present and will be used by the module.
You can address the arguments from A7 as follows:
Location Size Contents
(A7) + n 4 return address
(A7)+4+n 4 argument lefty
(A7)+8+n 8 argument middle
(A7)+16+n 4 argument mrright
Using the parameters=register Option
Using the parameters=register option tells the compiler to pass
some of the function arguments in registers instead of on the stack.
Specifically, the first two pointer arguments are in A0 and A1, and the
first two integral arguments are in D0 and D1. All other arguments
are passed on the stack.
The compiler identifies functions that expect arguments in registers
by placing an @ in front of the function name. The @ replaces the
underscore (_) that the compiler normally places at the beginning of
function names.
319 Using Assembly Language with C Language
Using the parameters=register option is similar to passing
parameters using the stack. For example, make sure you:
[] include a prototype of your assembler module in your C source
program.
[] retrieve any parameters that are passed on the stack before using
them.
[] use the same asm command to assemble your assembler code.
[] use the same slink command to link your C code.
However, you must specify the parameters=register option in
the sc command as follows:
sc parameters=register test
Using the __asm Keyword
Using the __asm keyword on a function prototype or definition tells
the compiler to pass parameters in specific registers.
When you use __asm, the calling C function places the parameters
in the registers required by the assembler module, so no stack
manipulation inside the assembler module is necessary.
The following assembler code is the same f unc module that is
described previously in the section "Passing Parameters on the Stack,"
but it is modified to use the __asm keyword.
; NOTE: This code assumes that you have a math co-processor.
;If you do not, your machine will crash when you run
;this program.
xdef _func
section code
_func:
cmpi.b #'+',d0 ; should I add?
bne.b noadd ; no, check subtract
fadd.l d1,fp0 ; add 'mrright' to 'middle'
bra.b exitpoint ; ready to return
noadd:
cmpi.b #'-',d0 ; should I subtract?
bne.b nosub ; no, exit with error
320 Chapter 11
fsub.l dl,fp0 ; subtract 'mrright' from 'mlddle'
bra.b exitpoint
nosub:
fmove.b #-1,fp0 ; return -1 for error
exitpoint:
fmove.l fp0,d0 ; return 'int' in d0
rts
end
To use the __asm keyword, you must modify the prototype of the
assembler module in your C source file. For each parameter that you
want to pass in a register, precede the parameter with the register
keyword, two underscores (__), and the register into which you want
the parameter placed.
The prototype for the previous example is the following:
int __asm func(register __d0 char lefty,
register __fp0 double middle,
register __d1 int mrright);
The lefty argument is placed into register d0, the middle argument
is placed into register fp0, and the mrright argument is placed into
register d1.
The remainder of your C program is the same as that shown earlier
in the section "Passing Parameters on the Stack." You also use the
same asm, sc, and slink commands as shown in in the section
"Passing Parameters on the Stack."
Returning Values to the Calling Function
Your assembler module should return values in one or more registers.
The register(s) depend on the data type of the calling function.
Function return
values are passed back in one or more registers,
321 Using Assembly Language with C Language
depending on the data type declared for the calling function. The
conventions are as follows:
Return Length
Type (Bits) Syntax Meaning
char 8 D0.B low byte of D0
short 16 D0.W low word of D0
long 32 D0.L all of D0
pointer 32 D0.L all of D0
float 32 D0.L all of D0
float (68881) 32 FP0. S single precision in FP0
double (IEEE) 64 D0.L,D1.L high bits in D0
double (FFP) 32 D0.L all of D0
double (68881) 96 FP0.X all of FP0
If the assembler module returns a structure or union, it must define
a static work area (not on the stack) to hold the returned object and
return a pointer to this object in the D0 register. The calling function
should immediately move the data to the appropriate place.
Note: This approach implies that functions returning structures or
unions are not re-entrant, although they are serially reusable. Such a
function can be recursive if it is designed carefully with this return
technique in mind.
After setting up the return value, the assembler module exits by
reversing the steps described earlier:
1. restore registers that were saved.
2. advance the stack pointer in register A7 past the work area.
3. return to the caller using an RTS instruction.
The calling
function removes the arguments from the stack.
322 Chapter 11
Calling C Functions from Assembler Functions
The steps you take to call a C function from an assembler program
vary, depending on whether or not you compile your C function using
the parameters=register option.
If you are not using registerized parameters, follow these steps:
1. push the arguments on the stack in the correct order.
2. call the function using the JSR instruction.
3. after control returns from the called function, adjust the stack
pointer to account for pushed arguments.
For example, the following code calls the function cfunc with two
parameters that are currently in registers D7 and D6 and stores the
return code in the ret variable.
XREF cfunc
MOVE.L D7,-(A7) ;push argument
HOVE.L D6,-(A7)
JSR cfunc ;call function
ADDQ #8,A7 ;restore stack ptr
MOVE.L D0,ret ;save return value
If you are using registerized parameters, follow these steps:
1. place the appropriate arguments in the correct registers.
2. push any remaining arguments onto the stack.
3. add an ~ to the front of the function name, and call the function
using the JSR instruction.
4. after control returns from the called function, adjust the stack
pointer to account for pushed arguments (if any).
For example, the following code calls the function cfunc with two
parameters that are currently in registers D7 and D6 and stores the
return code in the ret variable.
XREF @cfunc
MOVE.L D7,D0
MOVE.L D6,D0
JSR @cfunc ;call function
MOVE.L D0,ret ;save return value
If your C function is declared using the __asm keyword, you should
pass the parameters in the appropriate registers.
Referencing Global Data
Instead of passing parameters into and out of a function, you can use
global data.
323 Using Assembly Language with C Language
You can access data declared in an assembler module from a C
function by placing the data declarations inside a data section and
defining the data with an XDEF statement. The following code defines
two variables in assembly language and shows how to declare them in
a C function.
In Assembly Language In C Language
CSECT data extern long VAR1;
XDEF VAR1,VAR2,VAR3 extern long VAR2;
VAR1 DC.L $4000
VAR2 DC.L $8000
You can access data declared in a C function from an assembler
module using the XREF statement, as follows:
In C Language In Assembly Language
long VAR1=0x4000; XREF VAR1,VAR2
long VAR1=0x4000; .
.
.
MOVE.L VAR1,D0
Running the Assembler
After you have created your modules or programs in assembly
language, you can run the Assembler by entering the asm command as
follows:
asm [>listfile] [options] filename
The filename is the name of the assembly language source file that
you want to assemble. The assembler assumes a source filename
extension of .a, and it produces an object file with the same filename
but with the .o extension. You can then use the linker,
slink, to
324 Chapter 11
combine these object modules into an executable file, called a load
module.
If you include >listfile, the assembler sends the source listing and
error messages to that file.
The assembler supports the following options:
-cx
specifies that the sections designated by x are to be loaded into
memory addressable by the Amiga system's custom hardware. You
should specify -c for screen image and audio data. The x can be
one or more of the following:
b bss or uninitialized data
c code segment
d data segment
By default, the assembler loads the segments into memory not
addressable by custom hardware, if it is available. This action
avoids bus contention between the processor and the custom
hardware. For example, the following command causes all segments
to be loaded into chip-addressable memory, regard0ess of the system
memory configuration:
asm -ccdb prog.a
-d
activates the debugging mode.
-dsymbol [ =valuel
defines symbol as if your source file contained this statement:
symbol EQU value
If you do not specify a value, the assembler assigns a value of 1.
-hx
specifies that the sections designated by x are to be loaded into
memory not addressable by the Amiga system's custom hardware.
The x can be one or more of the following:
b bss or uninitialized data
c code segment
d data segment
By default, the assembler loads the segments into memory not
addressable by
custom hardware, if it is available. This action
325 Using ~ssembly Language with C Language
prevents the specified segments from being loaded into chip-
addressable memory even if no other memory is available. This
action could also prevent programs from running if external high-
speed memory is not available on the machine. For example, the
following command loads all three sections into high-speed r~AM
asm -hcdb prog . a
-iprefix
specifies a prefix that should be placed in front of filenames in
INCLUDE directives. You can enter up to four -i options. The
assembler will search for the files in the order in which you specify
the prefixes. If you specify a directory name as a prefix, include the
trailing slash (/). For example, you can assemble the file named
testprog. a with the following command:
asm -imyinc/ -iyourinc/ testprog.a
If your program contains the statement include abc . i, the
assembler searches for the file in the current directory. If that fails,
it searches for myinc/abc . i and then yourinc/abc . i.
-l[x][m][i]
sends a listing of the source file to the standard output, usually the
screen. The listing displays the appropriate location counter and
code- or data-generated information beside the source line. The x,
m, and i produce the following slightly different listings:
x lists the expansion text for macros.
m lists additional data generated for source lines that camlot be
listed beside the original source line. This option allows
multiple listing lines for each source line.
i lists the source for text from INCLUDE files as well as the
original source file.
-m0
specifies that only 68000 instructions are allowed. This option
issues warning messages if, for example, you use instructions that
are only available on the 68020. This option is the default.
-m2
turns off the warnings generated by the -mO option. Use this option
if 68020
instructions are allowed.
326 Chapter 11
-m3
turns off the warnings generated by the -m0 option. Use this option
if 68030 instructions are allowed.
-m4
turns off the warnings generated by the -mO option. Use this option
if 68040 instructions are allowed.
-oprefix
specifies a prefix that you want placed in front of the output
filename. If you specify a directory name as a prefix, include the (/).
Any drive or directory prefixes in the input filename are discarded
before the new prefix is added. Do not include blanks in the prefix.
-s
includes the section name at the beginning of each hunk.
-u
specifies that you want the assembler to prefix external references
with an underscore (_). Do not use this option if you entered all
external names with leading underscores. You should specify this
option when you assemble startup code.
-w
defines the symbol shortint to be 1. This option works as if you
had specified -dshortint= 1.
For example, the following command assembles the file named
modn.a, produces an object file named modn.o, and generates a
listing file named modn. 1st that lists the source code and any error
messages:
asm
>modn.lst -l modn
327
Part 4
Using the SAS/C
Optimizer
Chapter 12 Optimizing Your Code
328
329
12 Optimizing Your Code
329 Introduction
329 The Global Optimizer
334 The Peephole Optimizer
334 Running the Optimizers
335 Global Optimization Compiler Options
336 Global Optimization and the Debugger
Introduction
Your SAS/C Development System provides the following two
optimizers:
global optimizer (GO)
analyzes the intermediate code produced by the compiler, performs
several types of optimizations, and produces output in the same
form as the compiler. Because the global optimizer works on
intermediate code, it has no knowledge of the target processor or its
instructions.
peephole optimizer
analyzes the assembler instructions and replaces inefficient
sequences of instructions with shorter, more efflcient sequences.
The Global Optimizer
The global optimizer optimizes the flow of control and data through an
entire function. The global optimizer performs several types of
optimizations:
register assignment
analyzes the function to determine which auto variables, formal
variables, temporary values, and constant values should be assigned
to registers at each point in the function. The optimizer assigns up
to three address registers, four data registers, and, if a math
coprocessor is present, four floating point registers for the use of
register variables.
Generally speaking, the variables that are most used at a given
point are
assigned to registers. For example, variables occurring in
330 Chapter12
loops are more likely to be assigned to registers. The global
optimizer attempts to keep a variable assigned to a register for as
long as possible.
Using the ampersand (&) operator with a variable prevents the
global optimizer from allocating that variable to a register because
it cannot predict when the resultant pointer will be used to read or
modify the variable's value in memory. The same condition applies
to an external variable because it may appear in another function
or the & operator may be used with it elsewhere.
The effect of global optimization's register allocation is quite
different from the use of the register storage class. In general, a
variable declared using the register keyword is associated with a
machine register throughout the entire block in which it is declared
(usually the entire function). In most functions, the variable is
heavily used in some places and not used in other places. Yet, if a
machine register is assigned to the variable, then the same register
cannot be reused even in those sections where the variable is not
used. Therefore, global optimization changes a register's assigned
variable during the evaluation of the expression to ensure that the
most heavily used variables are always in machine registers.
The global optimizer overrides the register keyword in the
declarations of integer, double, and pointer variables. Because of
the portability of the C language, it is difficult for a programmer to
know the number of available registers provided by the target
machine and the compiler. The concept of a register variable is
based on the idea that the variable is kept in a register for the
entirety of its scope. Such restrictions no longer apply when a
compiler uses the more advanced registration allocation algorithms
in SAS/C software. Even though the compiler does not have
dynamic information about program execution that would indicate
which statements are executed more heavily, it can use the loop
nesting structure to make a reasonable approximation.
dead store elimination
eliminates the assignment of a value to a variable if the value is not
used. The assignment can be eliminated as in this example:
index = 23;
.
.
.
/* code that does not refer to index */
.
.
.
index = 12;
331 Optimizing Your Code
The first assignment to index can be removed. Since the global
optimizer inspects all references to the variable throughout the
entire function, even subtle dead stores are eliminated.
dead code elimination
eliminates code that never can be executed.
common subexpression merging
eliminates recalculation of values that have been computed
previously within the same function. For example, the following
code
x = i / 3;
y = i / 3 + 4;
can be changed to
temp = i / 3;
x = temp;
y = temp + 4;
moving invariants out of loops
moves a calculation in a loop, whose value is the same on each
iteration, to the outside of the loop. For example, the loop
for (i = O; i < j; i++)
{
a[i]= p->q.r[10];
}
can be changed to
temp = p->q.r[10];
for (i = 0; i < j; i++)
{
a[i]= temp;
}
Refer to the explanation for optloop later in this chapter for
more information about this type of optimization.
induction variable transformations
changes to addition loops containing multiplications (usually those
associated with
array indexing).
332 Chapter 12
copy propagation
eliminates definitions of the form leftvar = rightvar when all
uses of leftvar have this definition as the single reaching
definition and rightvar will not change before each use. This
optimization supports other optimizations.
constant propagation and folding
replaces references to a variable with a constant when the variable
is defined as that constant. If the variable is used only in
expressions with a different type (for example, if an int variable is
only used in a comparison with f loat variables), global
optimization creates a constant of the correct type. If the variable is
used only as a constant, global optimization eliminates the variable
entirely. The following example demonstrates these optimizations:
void f(double d)
{
i = 10;
for (; d < i; ++d)
{
.
.
.
}
return;
}
The previous code can be changed to the following:
void f(double d)
{
for (; d < 10.0; ++d)
{
.
.
.
}
return;
}
Constant propagation is often useful in programs that contain
inline functions since one or more parameters to the inlined
function
actually may be constants.
333 Optimizing Your Code
auto variable elimination and remapping
eliminates unused auto variables and reassigns storage offsets. Often
the variable is unused because of previous optimizations.
very busy expression hoisting
moves an expression that is computed along all paths from a point
in the code to a single, common location. For example, the code
if (expression
x = i + j;
else
y = (i + j) * 2;
can be changed to
temp = i + j;
if (expression
x = temp;
else
y = temp * 2;
various reductions in strength
performs associative reordering of additive operations involving
constants to reduce the operation count.
Various arithmetic operations involving constants are reduced in
strength.
Conditional and logical expressions whose results are unused are
converted into corresponding if code. For instance, putchar
from stdio.h is implemented with a conditional expression. If the
result (the original character or an error indication) is not used, GO
converts it into if else code, eliminating a load into a register.
various control flow transformations
performs various transformations to eliminate unreachable code or
useless control structures.
reordering of operations to reduce value lifetimes
moves expressions with a single use adjacent to the operation that
uses them. This optimization helps reduce temporary lifetimes and
supports optimizations that move code around. For example, in the
following code, the computation of the address ~ p 1 i ] can be
moved after the call:
P[i] = f();
334 Chapter 12
The Peephole Optimizer
The code generator contains all of the knowledge about the target
processor and its instructions and makes full use of the 680x0
instruction set. The code generator tries not to generate extra
instructions, but the peephole optimizer can help catch the few places
where this is not possible.
As stated earlier, the peephole optimizer analyzes the assembler
instructions and replaces inefficient sequences of instructions with
shorter, more efficient sequences. For example, for the following set of
instructions, the peephole optimizer deletes the TST.L instruction:
MOVE.L D1,D2
TST. LD2
BNE LABEL
The test instruction is not needed because the condition codes for the
branch instruction are set by the move instruction.
Currently, the peephole optimizer optimizes 22 patterns of assembler
instructions. If you find additional patterns that the optimizer should
recognize, contact the Technical Support Division at SAS Institute Inc.
Running the Optimizers
To run the optimizers, specify the appropriate compiler option:
Option Effect
optimize turns on both the global and peephole optimizers.
optimize turns on only the global optimizer.
nooptpeep
In many cases, optimized code is more difflcult to debug than non-
optimized code. You may want to use the optimizer only after the main
program has been
tested and most errors have been corrected.
335 Optimizing Your Code
Global Optimization Compiler Options
The compiler accepts the following options to modify the operation of
the global optimizer:
optalias
disables typebased aliasing assumptions. If optalias is used, the
global optimizer uses worst-case aliasing. Using this option can
significantly reduce the amount of optimization that can be
performed. The nooptalias option is the default.
optcomplexity
defines the complexity of functions considered small by
optinline. For more information, refer to Chapter 8, "Compiling
and Linking Your Program," of SAS/C Development System User's
Guide, Volume I: Introduction, Compiler, Editor.
optdepth
defines the maximum depth of function calls to be inlined. The
range is 0 to 6, and the default value is 3.
optinline
inlines small functions (as defined by optcomplexity) as well as
those with the __inline keyword. The optinline option is the
default when optimize is used. Refer to Chapter 11, "Using
Amiga Specific Features of the SAS/C Language," in the SAS/C
Development System User's Guide, Volume I, for information about
the _\ts_inline keyword.
optinlocal
inlines single-call static (local) functions.
optloop
assumes that loops have multiple iterations when the number of
iterations is variable. This assumption enables the movement of safe
code out of loops. The optloop option is the default. For more
information, see "moving invariants out of loops," earlier in this
chapter.
When a loop is not executed at all, the moved code is executed in
cases where it previously would not have been. For example, the
code
for (i = 0; i < n; ++i)
for (j = 0; j < m; ++j)
p[i * m + j] += 1;
336 Chapter 12
can be changed to
for (i = 0; i < n; ++i)
{
temp = i * m;
for (j = 0; j < m; ++j)
p[temp + j] += 1;
}
In the changed code, i*m can be calculated when m is less than or
equal to 0. When optloop has been specified, there may be a
small cost in time for every loop that is not executed. There is also
a significant time saving for loops that are executed many times, as
most are.
Some types of code may cause an exception, for example, division
by 0. For this reason, the global optimizer restricts moved code to
safe operations, including integral and pointer arithmetic other than
division by 0, but not including iloating-point operations. The global
optimizer avoids incorrect exceptions regard0ess of the setting of
optloop.
optrdepth
defines the maximum level of recursive function calls to be inlined.
The range is 0 to 6, and the default is 1.
optsize
disables optimizations that might sacrifice code size to save time.
Only some loop optimizations do this. The nooptsize option is
the default. Specifying both opttime and optsize may result in
code that is both slower and larger than most optimized code.
opttime
disables optimizations that might sacrifice time to save space. The
noopttime option is the default.
Global Optimization and the Debugger
To use all the capabilities of the debugger, the lines in the source code
file must correspond exactly with the lines in the object code file.
Optimizing your code may change this correspondence. Also, the
debugger may not know about variables that the optimizer moves or
eliminates.
If you use the debugger on optimized code, run the debugger in
mixed mode by entering the following command on the debugger
command line:
opt source mixed
337 Optimizing Your Code
In mixed mode, the debugger displays both assembly language
instructions and C source lines in the source window. Use the
assembly language code to determine if the variables you examine are
actually located where the debugger thinks they are.
338
339
Part 5
Appendix
Appendix diff File-Matching Algorithm
340
341
Appendix
diff File-Matching Algorithm
This appendix describes the file-matching algorithm used by the diff
utility. The algorithm used by the diff utility is described in A
Technique for Isolating Differences Between Files by P. Heckel.*
The matching algorithm described by Heckel is simple, fast, and
effective. Briefly, it works as follows:
[] Identify those lines that occur only once in each file. Assume that
these lines match one another.
[] Sweep downward into the first file. Each time you come to a line L
that is already matched to the line L1 in the second file, examine the
next line. This second line is referred to as L+1.
[] If L+1 is the same as the corresponding line L1+1 in the second
file, then match those lines as well.
[] After this downward sweep is completed, sweep upward in the first
file attempting to match lines in the same way (except that you look
at L-1 and L1-1 when finding a matched line L).
The effect of the matching algorithm is to match blocks of text to each
other in the two files.
However, the algorithm frequently cross-matches single lines or two
blocks of lines. That is, lines L and L+k may be matched to lines L1
and L1-j. Consequently, after the process described previously is
completed, the matches must be untangled to generate a coherent
report of the differences. Therefore, the diff utility cross-matches
blocks and then unmatches the smaller of the blocks. This process is
an attempt to satisfy the notion that the differences reported should be
minimal.
In addition, this algorithm must first seed itself by identifying lines
that occur exactly once in each file. Therefore, this algorithm may fail
to match any lines even when there is an obvious match.
----------------------------------------------------------------------------
* Heckel, P. (1978), "A Technique for Isolating Differences Between Files,"
Communications
of the ACM (April), 264-8.
342 Appendix
For example, you may have two files with the following contents:
File 1 File 2
aaa bbb
xxx xxx
xxx xxx
yyy zzz
The algorithm will fail to match the blocks of xxx lines because it does
not find any lines that occur exactly once in each file to seed the
algorithm.
343
Index
A nesting aliases 92
positional parameters 90
-a option, smake utility 289 referencing aliases commands with
abort command, SC_SCMSG AREXX port back-tick character (`) 92
262, 262-264 syntax 89, 128
absolute addressing modes 313 aliases for dump command in previous
absolute expressions 304 releases 146 147
accelerator keys 23-24, 29, 34 alternate targets, smake utility 283 284
actions, smake utility 273 altfile command, SC _ SCMSG AREXX port
actions gadget 267 262
activate command 107, 111, 127 altline command, SC _ SCMSG AREXX
Address field, tasks command 109 port 262
address parameter 118-119 ampersand operator (&)
examples 118-119 identifying addresses 118
using with location parameter 40 using with global optimizer 330
addresses ampersand symbol (&)
absolute addressing modes 313 special symbol in smake utility 277
addressing modes supported by SAS/C and operator (&)
assembler 312 not used with register variables 58
dumping 62 append block, diff utility 221
forcing program counter-relative AREXX interface 101
addressing 311 invoking editors 261-262
register-direct addressing modes 313 AREXX macros 101-104
specifying with CSECT directive 311-314 command output 103-104
specifying with SECTION directive invoking macros 102-103
309-310 libraries.cpr 106
addsym option macros provided by CodeProbe 101-102
adding to slink automatically 8, 9 return codes 103
generating H_SYMBOL hunk 8 values returned from CodeProbe
purpose 74 commands 103-104
AddTask function 114 AREXX port 262-264
after option args command 130
break command 49, 135 array-slice parameter 119-120
go command 40, 42, 156 arrays
alias command 89-92, 128-129 displaying 31, 59-61
See also define command setting watches or watch breaks 71
See also expand command arrdim option, opt command 86 87, 165
compared with define command 92,93 ASCII option, dump command 65-66
displaying alias definitions 90 asm command 323-326
displaying current aliases 89-90 -c option 324
escape characters 19 -d option 324
examples 91, 128-129 -d symbol(=value) option 324
expanding alias
names 90, 91 -h option 324-325
344 Index
asm command (continued) used in array-slice parameter 119
-i option 325 wild card indicator 34
-m0 option 325 asynchronous tasks 108
-m2 option 325 at sign ((?)
-m3 option 326 oml utility 251, 253
-m4 option 326 replacing underscore in function names
-o option 326 for compiler 318
options supported 324 326 special symbol in smake utility 277
s option 326 specifying octal numbers in assembler
syntax 323 statement expressions 303
u option 326 auto variable elimination and remapping
w OptiOII 326 333
__asm keyword 319 320 autoedit option, scmsg utility 255
assembler directives 304-308 autoswap mode 29, 88
See also specific directives autoswap option, opt command 88, 165
assembly language 299 326
addresses, specifying with CSECT
directive 311 314 B
assembler directives 304-308
assembler statements, writing 300-304 -b option
__asm keyword 319-320 diff utility 219
calling assembler functions from C oml utility 253
functiolls 314 321 smake utility 289
calling C functions from assembler back-tick character (`)
fullctions 322 non-expansion of escaped macro
communicating with C language 314-323 definitions 92 93, 141
control sections, defining 309-314 referencing aliased commands 92
CSECT directive 310 314 backslash character (\)
expressions, specifying 302 304 continuing lines in aliases 90
fields in source line 300-301 Control-\ for terminating oml 251
format of source lines 300 escape character in grep searches 227,
macros, defining and using 308 231, 232-233
options supported by assembler 324-326 escape character preceding semicolon 93
parameters=register option 318-319 extending commands across lines 18
passing parameters on the stack 315-318 interpretation in character strings 19,
referencing global data 322-323 123
returning values to calling function special symbol in smake utility 277
320 321 badchar option, opt command 87, 165
rulming the assembler 323-326 bclear command 131
SECTION directive 309-310 definition 36, 48
size sumxes, specifying 301 302 examples 131
writing assembly language functions syntax 131
300 314 bdisable command 48, 132
assembly mode benable command 48, 133
ps command 47 blist command 36, 48, 134
setting 46, 83 bottom command, SC_SCMSG AREXX
trace command 45 port 262
asterisk ( ) braces ({})
grep search pattern 225, 226, 230-231 defining aliases 90
removing all aliases 92 using in cmd_list parameters 50
345 Index
brackets ([]) C
enclosing characters in grep search 226,
228-230 C functions, calling
See calling assembler functions from
branch instructions C functions
assembler statement size suffixes 302 See calling C functions from assembler
break command 48-53, 135 136 functions
See also bclear command C mode 83
See also bdisable command -c option
See also benable command asm command 324
See also blist command diff utility 219
after option 49, 135 grep utility 225
cmd0ist parameter 50, 135 smake utility 289
call command 137-138
definition 39 call frame 6
examples 136 calling assembler functions from C
go command as last command of cmd list functions 314-321
parameter 51 __asm keyword 319-320
quiet option 52 53, 135 calling an assembler module 316
syntax 48-49, 135 parameters=register option 318-319
temp option 52-53, 135 passing parameters on the stack 315
318
trace option 51, 52-53, 135 retrieving parameters from the stack
when option 49, 135 317
returning values to calling function
Break menu 21 22 320-321
breakpoints saving register contents 317-318
attaching actions to 50 53 stack, example 317
caution against placing in libraries 110 calling C functions from assembler
conditional 49 50 functions 322
definition 5, 32, 47 Calls window l4
executing up to a breakpoint 32 caret (^)
multitasking programs 108 grep search pattern 226
nesting 52 case option, opt command 85, 165
catch command 107, 112, 139
preventing debugger from stoppin 51 Catch New Devices option
resident libraries 105, 106 See devices option, opt command
setting 32, 47-48 catch option, opt command 89, 166
temporary, set by go command 40, 43 change block, diff utility 221
turning off 32 character classes, grep utility 226
using with detach command 111 112 specifying 228-230
-buffer command-line option 78 79 characters and strings, dumping 65 66
build command, SC_SCMSG AREXX port class command, SC _ SCMSG AREXX port
262 clear command SC SCMSG AREXX port
Build menu, scmsg utility 259 262
built-in functions 202-203 -cli command-line option 11, 79
See also specific functions cmd_list parameter, break command 50,
list of functions 203 135
parameters 202 CNOP assembler directive 304
purpose 202 Code Generation Options window 266
346 Index
CodeProbe 3-24 command-line editing 16-19
See also debugging programs determining editing modes 17
basic features 4 editing function keys 17-18
changes and enhancements 5 escape characters in commands 19
command line 16-19 escape sequences in character
compiling and linking programs 9 strings18 19
controlling 8 extending commands across lines
cpr command 9-10 using backslash (\) 18
debugging procedure 7-8 command-line options 78-81
entering commands 16-24 adding as tool types 78
function and special keys 22-23 -buffer 78-79
introduction 3 4 -cli 11, 79
line mode 11 -command 79
menu accelerator keys 23-24 -device 97
multitasking features 4-5 -i 79
opening windows 15-16 -line 79
pull-down menus 20-22 -nok 98
quit command 10 -noprofile 79-80
requirements 7 -pipe 97
running 9-11
running on optimized code 336 337 -screen 80
starting 25 34 setting up in Workbench screen 11
terminology 5_7 -speed 97
windowing interface 12-16 -startup 26, 80
Workbench support 10-11 -symfile 98
CodeProbe sample session 25-34 -unit 97
activating autoswap mode 29 using with cpr command 10
breakpoints, setting 32 -w 80
clearing watches and watch breaks 34 -wb. 11, 80
compiling and linking 25 -wd0alog 81
continuing execution 30 -wregister 81
controlling debugging session 27-34 -wsource 81
displaying arrays and structures 30-32 -wwatch 81
displaying variable values and types 32 command output for AREXX macros
executing breakpoints 32 103-104
executing until variable changes value command parameter, help command 27
33-34 commands
go command 26 See also specific commands
invoking the debugger 26 address parameter 118 119
online help 26-27 array-slice parameter 119
quitting the debugger 34 command-line editing 16-19
restart command 26 command-line equivalents for menu items
source mode, setting 27-28 20-22
starting the debugger 25-26 customizing Dialog window commands
stepping over code 29-30 89-94
watch and watch break commands 32-34 editing function keys 17-18
comma (,) editing modes 17
separating multiple arguments in display entering on command line 16-19
command 58 escape characters in strings 18-19
command command line option 79 expression parameter 120
347 Index
extending across lines using backslash controlling program execution
(\) 18 See program execution, controlling
function and special keys 22-23 copy propagation 332
list of commands 116-118 cover utility 216-218
location parameter 120 121 dir= option 217
menu accelerator keys 23-24 example 217-218
number parameter 121 merge option 217
pull-down menus 20-22 nosource option 217
range parameter 121-122 options supported 217
register parameter 122-123 running 216
SC_SCMSG AREXX port 262-264 syntax and description 216 217
shortcuts for command names 16 cpr command 9-10
speclal parameterS 118-125 available command-line options 10
specifying in oml utility 252-253 changing the default environment 11
subrange parameter 123-124 -cli option 11
syntax 16 invoking the debugger 26
type parameter 124 syntax 9, 75
variable parameter 125 -wb option 11
>prompt 16 .cpr extension for macros 102
comment field, assembly language source cprinit file
line 301 comment lines 82
comment lines, cprinit file 82 examples 81-82
communications parameters initializing CodeProbe 81-82
defining for cross debugging 97 suppresSing execution with -noprofile
-device 97 option 79 80
-pipe 97 CPRK
-speed 97 See also cross-development mode
-unit 97 examples 99
comparing files options 98
See diH utility required on target machine 96
compiler running 96
See sc command starting before CPRX 97, 98
compiler options, setting starting the kernel 98
See scopts utility terminating 99-100
Compiler Options Index window 266 CPRX
Compiler Options window 266 See also cross-development mode
compiling examples 99
compiling and linking programs 7 -nok option 98
sample program (lines.c) 25 starting 98-99
condition control register (CCR) flags 110 stripping debug information with -x
config= option, scmsg utility 255 option 96
constants -symfile option 98
assembler statement expressions 303 syntax 98
optimizing 332, 333 terminating 99-100
reductions in strength 333 -x option 99
context option, opt command 85, 166 cross-debugging 6
control flow transformations 333 cross-development mode 95-100
control sections See also CPRK
See CSECT assembler directive See also CPRX
See SECTION
assembler directive
debugging applications 99
348 Index
cross-development mode (continued) data structures, displaying
defining communications parameters 97 See structures, displaying
examples 99 DC assembler directive 305
host machine 96 DCB assembler directive 305
Nl LL modem cable 96 deactivate command 107, 111, 140
preparing to use cross debugger 96 dead code elimination 331
procedure 96 99 dead store elimination 330
reasolls for cross-debugging 95-96 Debug field, tasks command 109
running cross debugger 96-100 DEBUG tool 11
starting the cross debugger (CPRX) debug= options 74-76
98 99 determining which option to use 76-77
starting the kernel (CPRK) 98 list of options 74
target machine 96 debug=full option 74
terminating CPRX and CPRK 99-100 using 76
CSECT assembler directive 310-314 when to use 76 77
addressing modes supported 312 debug=fullflush option 74
definition 304 using 76
forcing program counter-relative when to use 76-77
addressing 311 debug=line option 74
format 310 generating H DEBUG hunks 8
parameters 310 using 75
program counter-relative addressing debug=symbol option 74
modes, examples 314 generating H DEBUG hunks 8
register-direct addressing modes 313 using 75-76
specifying addresses 311-314 when to use 76-77
specifying immediate data 314 debug=symbolflush option 74
valid types and sizes of relocation adding to sc command 9
informatioll 311 displaying full debugging information 25
CTRL-C, terminating CPRK and CPRX 99 using 76
Ctrl-L key 23 when to use 76-77
Ctrl-W key 23 debugger
curly braces See CodeProbe
See braces ({}) debugging environment, setting up 73-94
cllrrellt task, displaying 89 alias command 89 92
cycles gadget 267 arrdim option 86-87
autoswap mode 88
badchar option 87
D case option 85
Catch New Devices option 88
d command catch option 89
oml utility 252 changing default environment
short form of display command 30 with -cli and wb options 11
-d Option choosing command-line options 78-81
asm command 324 context option 85
smake utility 289 current task 89
splat utility 291 customizing Dialog window commands
-d symbol(=value) option, asm command 89-94
324 debug= options 74-76
data, examining debug=full option 76
See dump
command debug=fullflush option 76
349 Index
debug=line option 75 restart command 26
debug=symbol option 75-76 running CodeProbe 9-11
debug=symbolflush option 76 sample program 1 37-38
define command 92-93 sample program 2 53-56
echo mode 84 setting breakpoints 32
ibytes option 84-85 setting source mode 27-28
ignorepath option 85 single stepping 44-47
initializing CodeProbe 81-82 starting the debugger 25-26
list option 86 stepping over code 29-30
radix option 86 steps for debugging 8
rangelen option 87 trace commands 45-46
search path 87 88 watch and wbreak commands 32-34,
setting and showing options 82-89 70-72
source file location 77 78 watches and watch breaks 69-72
source modes 83 84 whatis command 68-69
Step Into ResLib option 88 89 decimal option, dump command 65
strlen option 86 .DEFAULT fake target 281-282
unalias command 92 default files, smake utility 287 288
unassemble option 86 #define capability, C preprocessor 93
undefine command 94 define command 141
when to use debug= options 76-77 compared with alias command 92, 93
debugging programs 25 34, 35 72 compared with C preprocessor #define
See also multitasking programs, capability 93
debugging defining symbols to nothing 93
See also resident libraries, debugging displaying macro definitions 93
activating autoswap mode 29 examples 141
break command 48-53 syntax 93, 141
breakpoints 47-53 delcomp command, SC_SCMSG AREXX
clearing watches and watch breaks 34 port 262
commands for running sample delete block, diff utility 220
programs 36 delete command, SC_SCMSG AREXX port
compiling and linking programs 9, 25 263
continuing execution 30 delfile command, SC_SCMSG AREXX
controlling program execution 27-34, port 263
39-53 delnum command, SC_SCMSG AREXX
display command 57 61 port 263
displaying arrays and structures 30-32 dependent file, smake utility 273
displaying variable values and types 32 detach command 111-112, 142
dump command 61-66 definition 107
examining data and data structures examples 142
57-72 precautions 111-112
executing breakpoints 32 syntax 111, 142
executing until variable changes value device command-line option 97
33-34 devices option, opt command 88, 166
go command 26, 39-44 Diagnostic Message Options window 266
invoking the debugger 26 Dialog window
online help 26-27 echo mode 84
proceed commands 46-47 functions 14
quitting the debugger 34 open by default 12, 26
register command
66-68 scrolling 31
350 Index
Dialog window (continued) special symbol in smake utility 277
specifying start-up window coordinates specifying hexadecimal numbers in
81 assembler statement expressions
zooming to full size 30 303
Dialog window commands -$ option, grep utility 225
alias 89-92 DS assembler directive 305
customizing 89-94 dump command 61-66, 145 147
wclear 34 addresses, dumping 62
diff file-matching algorithm 341-342 ASCII option 65-66
diff utility 219-223 characters and strings, dumping 65-66
append block 221 compared with register command 77
-b option 219 compatibility aliases 146-147
-c option 219 decimal option 65
change block 221 examples 147
delete block 220 float option 64
error messageS 222-223 floating-point numbers, dumping 64-65
examples 221-222 format parameter 145
-F option 219 integers, dumping 65
-L option 219 pointers, dumping 63-64
-I option 219 ranges, dumping 62-63
-o option 219 syntax 61, 145
options supported 219-220 variables, dumping 61-62, 75
-p Option 220 dzero command 148
-q Option 220 displaying ASCII text string 66
syntax and description 219-221 examples 31, 148
-w Option 220 syntax 148
dir= option, cover utility 217
disassembling object modules (omd utility) E
249
display command 57-61, 143-144 -e option, smake utility 289
compared with register command 77 echo command 149
examples 143-144 echo option, opt command 84, 166
expresslon parameter 57 Edit menu, scmsg utility 260
format parameter 57 AREXX for invoking editors 261-262
multiple arguments 58 examples 264-265
overriding default format 57 SC_SCMSG AREXX port 262-264
string parameter 58 editcommand option, scmsg Project menu
structures and arrays 30-32, 59-61 257
syntax 57, 143 editing modes 17
value and type of variables 32 ELSE assembler directive 305
variable types 75 END assembler directive 305
dollar parameter ($) ENDC assembler directive 305
dump command 145 ENDM assembler directive 305, 307
line command 161 env command 150-151
set command 177 environment 6
dollar sign ($) See also debugging environment, setting
grep search pattern 227, 229, 231 up
indicating macros 277, 278 representing state of the machine 14
positional parameters in aliases 90, 128 run environment 6
prefixing register
names 119 user environment 6
351 Index
environment variable (sc/cprpath) 11 FAIL assembler directive 305
EQU assembler directive 305 fake targets, smake utility 281-283
equals sign (=) file command, SC _ SCMSG AREXX port
defining macros in smake utility 277-278 263
EQUR assembler directive 305 file comparison
errnum command, SC_SCMSG AREXX See diff utility
port 263 file dependencies, tracking
errors and warnings, searching for See smake utility
See scmsg utility file-matching algorithm 341-342
escape characters 18-19 File menu
alias command 19 Line and Find Current Line items 20
backslash (\) in character strings 19 menu items and command-line
backslash (\) in grep searches 227 equivalents 20-22
character strings 18-19 finish command 100, 154
commands 19 flags, modifying
double quotes (" ") around 18-19 See rflag command
dumping with ASCII option 66 float option, dump command 64
single quotes (' ') around 19 floating-point instructions
string parameter support 123 assembler statement size suffixes 301
exception hand0ing 113-114 floating-point numbers
exclamation mark (!) dumping 64-65
marking watch breaks 33 hexadecimal notation in assembler
negation character in grep search 226, statement expressions 303
230 FORMAT assembler directive 305
execute command 152 format parameter
executing code display command 57
See program execution, controlling dump command 145
EXITM assembler directive 305, 307 fregister command 155
expand command 153 function keys
expression parameter actions performed 22-23
display command 57 command-line editing 17-18
operators not accepted 120 function line parameter, location
expressions parameter 41
absolute 304 function parameter, location parameter 41,
optimizing subexpressions 331 42
reductions in strength 333 functions
relocatable 304 See built-in functions
reordering 333
specifying in assembler statements
302-304 G
very busy expression hoisting 333
gadgets in scopts utility 267 268
global data, referencing 322-323
F global optimizer 329 333
auto variable elimination and
-f option remapping 332
grep utility 225 common subexpression merging 331
Istat utility 244 constant propagation and folding 332
smake utility 289 control flow transformations 333
-F option, diff utility 219 copy propagation 332
352 Index
global optimizer (continued) -f option 225
dead code elimination 331 -n option 225
dead store elimination 330-331 number of times characters may appear,
induction variable transformations 331 specifying 230-231
moving invariants out of loops 331 options supported 225
optalias option 335 -p option 225
optcomplexity option 335 patterns at beginning or end of line,
optdepth option 335 specifying 231
optinlille option 335 patterns containing special characters,
optinlocal option 335 specifying 232 234
optloop option 335-336 -q option 225
optrdepth option 336 redirecting output 224
optsize option 336 -s option 225
opttime option 336 single character, specifying 228
reduction5 in strengtll 333 specifying patterns 225-227
register assignment 329-330 syntax 224
reordering of operations 333 -v option 225
runnirlg 333_337 -V option 225
running the debugger on optimized code -$ option 225
336 337 gst utility 237 239
very busy expression hoisting 333 error messages 239
global symbol information 8 examples 238 239
global symbol tables list optlon 237 238
See gst utility options supported 237 238
See hypergst utility syntax and description 237_238
go command 39-44, 156-157 unload option 238
after clause 42, 156 verbose option 238
completing execution before running other
commands 30 H
examples 44, l56 157
executing until breakpoint 30, 32 -h option
last command of cmd list parameter 51 asm command 324-325
location parameter 156 smake utility 290
location parameter forms 40 42 H_DEBUG hunks 7, 8
parameters 40 help command 26 27, 158
starting execution of sample program 26 Help key 23
syntax 39 Help menu 16
syntax errors 43-44 Help window 14
when clause 42 44, 156 hidden option, scmsg Project menu 258
go main command 26, 80 hidden option, scmsg utility 255
gotofile option, scmsg Project menu 257 hide command, SC_SCMSG AREXX port
gotoline option, scmsg Project menu 258 263
greater than sign (>) host machine 6, 96
See also redirecting output (>) hunks
> prornpt for command line 16 H_DEBUG hunks 7, 8
grep utility 224 236 H_SYMBOL hunks 8
-c option 225 hunks command 159
description 224 227 hypergst utility 240-241
error messages 234 236 hyphen (-)
examples 227 specifying range
in grep search 226
353 Index
I keys
function key actions 22-23
-i command-line option 79 function keys for command-line editing
-i option 17-18
asm command 325 menu accelerator keys 23 24, 29, 34
smake utility 290 special keys 23
ibytes option, opt command 84 85, 166
IDNT assembler directive 305
IF assembler directive 305 L
IFC assembler directive 305
IFD assembler directive 306 l command, oml utility 252
IFEQ assembler directive 306 -l option
IFGE assembler directive 306 diff utility 219
IFGT assembler directive 306 tb utility 295
IFLE assembler directive 306 -L option, diff utility 219
IFLT assembler directive 306 label field, assembly language source line
IFNC assembler directive 306 300
IFND assembler directive 306 left-Amiga m keyboard shortcut 29, 34
IFNE assembler directive 306 less than sign (<)
.IGNORE fake target 282 diff utility 220
ignorepath option, opt command 85, 166 oml utility 251
image 6 libraries
image parameter, location parameter 42 See resident libraries, debugging
INCLUDE assembler directive 306 libraries, managing
infinite loops 112 See oml utility
initializing CodeProbe libraries.cpr AREXX macro 106
See cprinit file line boundary 6
Input window 15 line command, SC_SCMSG AREXX port
insert editing mode 17 263
instruction bytes -line command-line option 11, 79
See ibytes option, opt command line parameter, location parameter 41
integers, dumping 65 link library 250
interlace mode link option 9, 25
See -i command-line option linker
invoking the debugger See slink
See cpr command Linker Options window 267
linking programs 9, 25
LIST assembler directive 306
J list command 161 162
list option
jump command 89, 160 gst utility 237
opt command 86, 166
Listing/Cross Reference Options window
K 266
lists gadget 267
-k option, smake utility 290 LLEN assembler directive 306
kernel load module 324
See CPRK local input files, smake utility 284-286
354 Index
location parameter 40 42, 123-124 Memory window 15
address parameter 40 memory, dumping
definition 40, 120 See dump command
forms 40 memset function 207
function line parameter 41 menu accelerator keys 23-24, 29, 34
function parameter 41, 42, 121 menus
go command 40 42, 156 See pull-down menus
image parameter 42, 120 merge option, cover utility 217
integer parameter 121 Message window 15
line parameter 41 See also wmsg command
module parameter 42, 120 MEXIT assembler directive 306
syntax 120 minus sign (-)
log command 163-164 special symbol in smake utility 229, 277
log file 6 mixed mode 83-84
loops opt source mixed command 46, 77
induction variable transformations 331 running the debugger on optimized code
moving invariants out of loops 331 336-337
Iprof utility 242 243 setting 83-84
Istat utility 244 248 module 7
-f option 244 module parameter, location parameter 42
options supported 244 Modules window 15
syntax and description 244 multiple targets, smake utility 283
-t option 244 multitasking programs, debugging 107-114
z option 244 activate command 111
asynchronous tasks 108
breakpoints and task handling 108
M catch command 112
CodeProbe features 4-5
-m option, tb utility 295 commands for controlling tasks 107,
MACRO assembler directive 306 109 113
macros deactivate command 111
See also AREXX macros design considerations 113-114
See also define command detach command 111-112
defining assembly language macros 308 exception hand0ing 113-114
escaped macros not expanded 92-93 opt task command 110 111
hiding in double quotes 92 symload command 112-113
macros, smake utility 277-281 synchronous tasks 108
default macros 279-280 task handling by CodeProbe 108
defining transformation rules 280-281 tasks command 109-110
defining with equals sign (=) 277-278 terminating tasks 108
overriding definitions 278 trap handling 113-114
referring to macros 278 types of tasks 108
Map Options window 267 -m0 option, asm command 325
MASK2 assembler directive 306 -m2 option, asm command 325
maximum bad characters -m3 option, asm command 326
See badchar option, opt command -m4 option, asm command 326
memcmp function 204
memcpy function 205
memmove function 206
Memory menu 22
355 Index
N -n option 253
-o option 253
-n option options, specifying 253
grep utility 225 r command 252
oml utility 253 -s option 253
smake utility 290 syntax and description 250-251
Name field, tasks command 109 -t option 253
name= option, gst utility 238 terminating 251
NARG assembler directive 306 -v option 253
nested breakpoints 52 x command 252
networks -x option 253
using for cross debugging 97 @ command 253
next command, SC_SCMSG AREXX port .ONEERROR fake target 282
263 online help
nodebug option 74 See help command
NOFORMAT assembler directive 306 OpenDevice function 114
-nok option 98 OpenLibrary function 114
NOLIST assembler directive 307 operand field, assembly language source
non-floating-point instructions line 300
assembler statement size suffixes 301 operation field, assembly language
NOOB) assembler directive 307 source line 300
NOPAGE assembler directive 307 operators
-noprofile command-line option 79-80 assembler statement expressions
nosource option, cover utility 217 303-304
NULL modem cable for cross debugging 96 OPSYN assembler directive 307
number parameter 121 opt command 82-89, 165 167
numeric keypad modes 17 arrdim option 86-87, 165
autoswap option 88, 165
badchar option 87, 165
O case option 85, 165
catch option 89, 166
-o option context option 85, 166
asm command 326 devices option 88, 166
diff utility 219 displaying current task 89
oml utility 253 echo option 84, 166
splat utility 291 env option 112
Object Module Disassembler 249 examples 167
Object Module Librarian ibytes option 84-85, 166
See oml utility ignorepath option 85, 166
objects, determining type or configuration list option 86, 166
See whatis command radix option 86, 167
OFFSET assembler directive 307 rangelen option 87, 167
omd utility 249 reslib option 88 89, 167
oml utility 250-254 search option 87-88, 166
-b option 253 source option 46, 77, 83, 84, 166, 336
commands, specifying 252-253 strlen option 86, 167
d command 252 syntax 165
examples 254 task option 107, 110-111, 167
invoking 250 unassemble option 86, 167
I command
252 opt env command
112
356 Index
opt source asm command 46 Output window 15
opt source mixed command 46, 77, 84, overwrite editing mode 17
336
opt task command 110 111
definition 107 P
examples 111
task addresses 111 -p option
task-lD argument 110 diff utility 2Z0
using 110 111 grep utility 225
optalias option, global optimizer 335 smake utility 290
optcomplexity option, global optimizer 335 PAGE assembler directive 307
optdepth option, global optimizer 335 parameters=register option 318 319
optimized code, rumling debugger on pass count 7, 40, 42
336-337 specifying 135
Optimizer Optiolls window 266 patterns, searching for
optimizing code See grep utility
See global optimizer pausing 179
See peephole Optimizer peephole optimizer 329
optinline option, global optimizer 335 functions 334
optinlocal option, global optimizer 335 running 334
option results command (AREXX) 103 beginning AREXX templates 261
options specifying binary numbers in assembler
See also command-line options
See also debug= options statement expressions 303
See also opt command Period (.)
See also scopts utility grep wildcard character 225, 228, 230
-pipe command-line option 97
addsym 8, 9, 74 PLEN assembler directive 307
cover utility options 217 plus sign (+)
default options, displaying 82
diff utility options 219 220 grep search pattern 226, 231
global optimizer compiler options portname option, scmsg Project menu 258
335-336 pound sign (#)
grep utllity options 225 ANSI # and ## operators not supported
lstat utility options 244 Indicating comments m smakefiles 274
oml utility options 253 inserting before undefine command 191
parameters=register option 318-319 prev command, SC_SCMSG AREXX port
scmsg utility options 255-256 263
scmsg utility Project menu options Pri field, tasks command 109
257 258 printing expressions
setting and showing within CodeProbe See grep utility
82-89 proceed command 46-47, 168
smake utility 289-290 See also ps command
splat utility 291 assigned to Return key 29
tb utility 295 compared with trace command 44,
Options menu 20 21 46 47
optloop option, global optimizer 335-336 definition 29, 39
optrdepth option, global optimizer 336 examples 47, 168
optsize option, global optimizer 336 integer parameter 47
opttime option, global optimizer 336
syntax 46, 168
357 Index
profile scripts quit option, scmsg utility 255
See also cprinit file quotes, double (" ")
suppressing execution with -noprofile defining aliases 90
option 79-80 hiding macros 92
program counter-relative addressing surrounding character strings 18
examples 314 using in grep patterns 227
forcing 31] quotes, single ('')
program execution, controlling enclosing literals in assembler statement
See also debugging programs expressions 303
break command 48-53 surrounding character strings 19
clearing watches and watch breaks 34
continuing execution 30
executing until variable changes value R
33 34
executing up to breakpoints 32 r command, oml utility 252
go command 26, 30, 32, 39-44 -r option
proceed commands 29, 46-47 tb utility 295
setting breakpoints 32, 47-53 radix option, opt command 86, 167
single stepping 29, 44-47 range parameter 121 122
stepping into called functions 29 rangelen option, opt command 87, 167
stepping over code 29-30 ranges
trace commands 45-46 caution when using variables for setting
using watch and watch break commands watches 71
32-33 dumping 62-63
Project menu, scmsg utility 257-259 re-attaching tasks 112
Prototype Generation Options window 267 redirecting output (>)
ps command 169 diff utility 219
assembly mode 47 grep utility 224
example 169 lprof utility 242
syntax 46, 169 lstat utility 244
public screen, specifying 80 omd utility 249
public symbol 250 oml utility 251
pull-down menus 20 22 splat utility 291
See also specific menus tb utility 294
list of pull-down menus and command-line REG assembler directive 307
equivalents 20-22 register command 66-68, 171
See also fregister command
altering register contents 67-68
Q determining variable values 77
displaying register contents 67
q option examples 171
diffutility 220 syntax 66 67, 171
grep utility 225 register-direct addressing modes 313
smake utility 290 register parameter 122-123
quiet option, break command 52-53, 135 Register window 15, 81
quit command 170 registers
quitting the debugger 10, 34 altering contents 67-68
SC_SCMSG AREXX port 263 displaying contents 67
syntax and description 170 effect of opt task command 110
terminating
CPRX 100 modifying 110
358 Index
registers (continued) splat utility 291
optimizing 329-330 tb utility 295
saving contents before retrieving sample CodeProbe session
arguments from stack 317 See CodeProbe sample session
scratch registers 318 sample programs
relocatable expressions 304 commands for running sample
RemTask function 114 programs 36
resident libraries, debugging 105-106 lines.c 25
cautions for setting breakpoints 106, sample program 1 37-39
110 sample program 2 53-56
example 106 sc.examples drawer 25
libraries.cpr AREXX macro 106 saving option settings in scopts utility
limitations 106 268-269
setting breakpoints 105 sc command
symload command 106 adding addsym option to slink
reslib option, opt command 88-89, 167 automatically 8
restart command 172-173 debug=symbolflush option 9, 25
compared with start command 181 link option 9
crashes caused by improper use 26 parameters=register option 319
definition 26, 36 typical usage 9
examples 1 73 SC_CPR 101
running go command before using 30 See also AREXX macros
syntax and description 172 SC_SCMSG AREXX port 262-264
restoring previously saved options in scopts scmsg utility 255-265
utility 269 autoedit option 255
results variable, AREXX 103 Build menu 259
return codes available to AREXX macros command options 255-256
103 config=option 255
return command 174 Edit menu 260
Return key for executing proceed format of messages 256-257
command 29 hidden option 255
REXX language Project menu 257-259
See AREXX interface quit option 255
rexxonly command, SC_SCMSG AREXX rexxonly option 256
port 264 syntax and description 255-257
rexxonly option, scmsg utility 256 scopts utility 266-270
rflag command 175 entering options on command line 269
right-Amiga key 23 exiting without saving changes 269
RORG assembler directive 307 gadgets 267-268
run environment 6 restoring previously saved options 269
Run menu 21 saving option settings 268-269
tasks performed by 269-270
windows for setting options 266-267
S scratch registers 318
-screen command-line option 80
-s option script files
asm command 326 See cprinit file
grep utility 225 See profile scripts
oml utility 253 scsetup utility 9, 271-272
smake utility
290 search command
176
359 Index
search option, opt command 87-88, 166 addsym option 8, 9
search path 87 88 generating H_SYMBOL hunk 8
searching for expressions stripdebug option 77
See grep utility smake utility 273 290
searching for patterns -a option 289
See splat utility actions performed by 274
SECTION assembler directive 309-310 alternate targets 283 284
definition 307 -b option 289
format 309 -c option 289
specifying addresses 309-310 comments in smakefiles 274
segment lists creating and using default files 288
assigning pointers 113 creating smakefiles 274-276
determining address 112 -d option 289
select command, SC_SCMSG AREXX port default (.def) files 287-288
264 default macros 279-280
semicolon (;) defining transformation rules 280-281
escaping with backslash (\) in echo -e option 289
command 149 -f option 289
expanding alias names 90 fake targets 281-283
preceding with escape character 93 file dependencies, example 275
using in cmd list parameters 50 -h option 290
serial ports -i option 290
using for cross debugging 97, 98 -k option 290
SET assembler direetive 307 local input files 284 286
set eommand 177 178 macros 277-281
.SET fake target 282-283 multiple targets 283
setenv command 11 -n option 290
SetFunction 114 options 289-290
setting up new projects overriding macro definitions 278
See scsetup utility -p option 290
Shell -q option 290
starting across serial line 11 running smake 288-290
shortcut keys 23-24, 29, 34 -s option 290
shortcuts for command names 16 smake.def file 287-288
show [activate] command, SC_SCMSG special symbols 277
AREXX port 264 syntax 273, 289
SigWait field, tasks command 109 -t option 290
.SILENT fake target 283 terminology 273
single stepping through programs 29, -u option 290
44-47 -x option 290
size field, assembly language source line smake.def file 287-288
300 smakefile 273
size suffixes, assembler statements 301-302 source command 78, 180
slash (/) source file
second character in Dialog window's title specifying location 77-78
bar 17 source line fields, assembly language
sleep command 179 300 301
slink comment 301
adding or stripping debugging label 300
information
7 operand
300
360 Index
source line fields, assembly language strcpy function 210
(continued) string parameter 123
operation 300 display command 58
size 300 support for escape characters 123
source modes 83-84 strings, dumping 65 66
assembly mode 45, 46, 47, 83 strings gadget 267
C mode 83 stripdebug option 77
definition 27 strlen function 211
illustrations 26 strlen option, opt command 86, 167
mixed mode 46, 83-84, 336 structures
setting 27-28, 83-84 displaying 30-31, 57, 59-60
syntax of opt source command 83 setting watches or watch breaks 71
source option, opt command 83 84, 166 subrange parameter 119, lZ3 124
Source window symbol 7
functions 15 See also debug=symbol option
illustrations 26 global symbol information 8
open by default 12, 26 symbol command 183
specifying start-up window coordinates symbol= option, gst utility 238
81 symbol tables, global
sourceis option 77-78 See gst utility
SPC assembler directive 307 See hypergst utility
special keys 23 -symfile option 98
-speed command-line option 97 symload command 112-113, 184
splat utility 291-293 debugging resident libraries 106
-d option 291 definition 107
description 291 examples 184
examples 291-293 syntax and description 112-113, 184
-o option 291
-s option 291
syntax 291 T
-v option 291
stack, assembly language programs 317 -t option
stack variables 110 oml utility 253
StackPtr field, tasks command 109 smake utility 290
start command 181-182 -t= option, lstat utility 244, 245-248
See also restart command target files, smake utility 273
starting the debugger 25-34 alternate targets 283 284
-startup command-line option 26, 80 fake targets 281-283
State field, tasks command 109 multiple targets 283
state of the machine target machine 7, 96
See environment files required 96
statistics utilities task addresses 111
Iprof utility 242-243 task ID 110
Istat utility 244 248 task option, opt command 107, 110 111,
Step Into ResLib option 167
See reslib option, opt command tasks
stepping through code See also multitasking programs,
See program execution, controlling debugging
strcat function 208 displaying current task 89
strcmp function
209 turning
task catching on or off 89
361 Index
tasks command 109 110, 185 transformation rules for macros, smake
Address field 109 utility 280 281
all option 110, 112 trap handling 113 114
Debug field 109 ts command 45, 187
definition 107 TTL assembler directive 308
displaying tasks, example 109 Type field, tasks command 109
examples 185 type parameter 124
finding specific tasks 112
Name field 109
Pri field 109 U
SigWait field 109
StackPtr field 109 -u option
State field 109 asm command 326
syntax and description 185 smake utihty 290
tb utility 294-296 tb utility 295
description 294-295 unalias command 92, 188
examples 295-296 unassemble command 189 190
-l option 295 unassemble option, opt command 86, 167
-m optlon 295 undefine command 94, 191
-r option 295 underscore (_)
-s option 295 replaced by @ sign for compiler 318
syntax 294 -unit command-line Option 97
u option 295 unload option, gst utility 238
-v option 295 user environment 6
-x option 295 utilities
temp option, break command 52-53, 135 See specific utilities
terminating programs and tasks
See also quit command
CodeProbe tasks 108 V
CPRK and CPRX 99
oml utility 251 -v option
scmsg utility 255 grep utility 225
text command, SC SCMSG AREXX port oml utility 253
264 tb utility 295
tool types, adding 78 -V option, grep utility 225
top command, SC _ SCMSG AREXX port variable parameter 125
264 variables
trace command 45 46, 186, 187 assembler statement expressions 302
compared with proceed command 44, displaying value and type 32
46-47 dumping 61-62, 75
debugging programs 45-46 verbose option, gst utility 238
definition 39 View menu 21
examples 45 46, 186
integer parameter 45
stepping into a called function 29 W
syntax and description 45, 186
trace option, break command 51, 52 53, -w command line option 80
135 -w option
traceback information, displaying asm command 326
See tb
utility
diff utility 220
362 Index
wait option, scmsg Project menu 258 where command 110, 198
watch breaks 32-34 window command 199
clearing 34 windowing interface 12-16
creating 33 See also specific windows
example 34 functions of CodeProbe windows 14-16
function 70 opening windows 15
marked by exclamation mark (!) 33 screen layout 12-13
setting on structures or arrays 71 windows displayed in scopts utility
setting ranges 71 266-267
slow execution while using 33, 72 wlist command 69, 71, 200
static by default 70 wmsg command 201
watch command 70-72, 192 Workbench process, invoking 80
See also wbreak command Workbench screen
See also wclear command invoking CodeProbe 11
See also wdisable command running CodeProbe 10-11
See also wenable command specifying with -screen command-line
See also wlist command option 80
creating watches 33 specifying with -w command-line option
definibon 69 80
examples 192 -wregister command-line option 81
syntax and description 70, 192 -wsource command-line option 81
-watch command line option 81 -wwatch command-line option 81
Watch window
displaying watches and watch breaks 69,
70 X
functions 15
opening 335 x command, oml utility 252
specifying start-up window coordinates -x option
81 omd utility 249
watches 26, 69 oml utility 253
caution when using variables for ranges smake utility 290
71 stripping debug information 96
clearing 34 tb utility 295
creating 33 using with CPRX 99
dynamic by default 70 XDEF assembler directive 308
function 69-70 defining symbols in data section 309
setting on structures or arrays 71 referencing global data 322-323
-wb command-line option 11, 80 XREF assembler directive 308
wbreak command 70-72, 193 defining symbols in data section 309
wclear command 34, 194 referencing global data 322-323
-wdialog command-line option 81 using with CSECT directive 311-312
wdisable command 195
wenable command 196
whatis command 68-69, 197 Z
displaying value and type of variables 32
examples 68-69, 197 -z option, Istat utility 244
syntax and description 68, 197
when option
break command 49, 135
go command 40,
42-44, 156
363 Index
Special Characters @ (at sign)
See at sign (@)
{} (braces) ' (single quotes)
See braces ({}) See quotes, single ('')
\ (backslash character) " (quotes)
See backslash character (\) See quotes, double ("")
/ (slash)
See slash (/)
= (equals sign)
See equals sign (=)
[] (brackets)
See brackets ([])
. (period)
See period (.)
< (less than sign)
See less than sign (<)
+ (plus sign)
See plus sign ( +)
& (ampersand operator)
See ampersand operator (&)
& (ampersand symbol)
See ampersand symbol (&)
& (and operator)
See and operator (&)
! (exclamation mark)
See exclamation mark (!)
$ (dollar sign)
See dollar parameter ($)
See dollar sign ($)
(asterisk)
See asterisk (*)
; (semicolon)
See semicolon (;)
^ (caret)
See caret (^)
- (hyphen)
See hyphen (-)
- (minus sign)
See minus sign (-)
, (comma)
See comma (,)
% (percent sign)
See percent sign (%)
_ (underscore)
See underscore (_)
> (greater than sign)
See greater than sign (>)
(back-tick character)
See back-tick character (')
# (pound sign)
See pound sign (#)
SYSOP's Hut Rush CO-SYSOP's LawnMower Man Nickel
Falcon Red Wizard CMDR Quack Beast
___ _
____ / \ / \__________________________________
(THE_\ / \ / ) _ )
\_/ \\/ \ / / _________/(___ ________ /
) /\ \ / / (________ \ \ //
/ / /_ \/ / / /_ \ //
/ / // \ / ___ ____/ // \ \ //
_/ (_/(___) (_) (___)\_________/(___) \//
/ (
(_____________________________________________________)
Running CNet v2.63 with a USRobotics 16.8 Dual Standard
________ ____ _____/\ __/\ ______ _/\__ __/\
C00l US HQ\___ _// ¬\\__ \/ \\_ \ \_ \ / \
/ ||/ | \\|~ : / : \/ : \/~| \\/ : \
/ ·|\\ ¦ //| \\ ! / \ : \ | /
\___| \____/ |__|\\ X :_/~\\ |___/ _____/\ __/
....................\/.\/.....\/....\/LawNmoV\/....
NODE 1 <<<<The_NET>>>> 407-656-8205 NODE 3 <<<<The_NET>>>> 407-656-8246
NODE 2 <<<< RUSH >>>> 407-896-8113 NODE 4 <<The_Dungeon>> 407-654-0456
NODE 5 < High Society> 717-654-5061
[4;32m [0m
[4;31;43m NOW CALL: 1-407-656-8246!!! [0m[24;1H [22;1H