@database aos/english/StormRun.guide

@Master aos/english/StormRun.texi

@Width 72


This is the AmigaGuideŽ  file aos/english/StormRun.guide, produced by Makeinfo-1.68 from 
the input file aos/english/StormRun.texi.

   \\input texinfo

@node Main "StormRun.guide"
@next "Debug files"

StormRun
********

   This document describes StormRun, the debugger of the
StormC-environment version 4.

   Copyright (C) 2000,2001 HAAGE&PARTNER Computer GmbH.


 @{" Debug files " link "Debug files"}  
 @{" Resource tracking " link "Resource tracking"}  
 @{" Enforcer support " link "Enforcer support"}  
 @{" Debugging PPC programs " link "Debugging PPC programs"}  
 @{" Debugging shared libraries " link "Debugging shared libraries"}  
 @{" Programmed breakpoints " link "Programmed breakpoints"}  
 @{" Control window " link "Control window"}  
 @{" Address dialog " link "Address dialog"}  
 @{" Task window " link "Task window"}  
 @{" Segment window " link "Segment window"}  
 @{" Module window " link "Module window"}  
 @{" Function window " link "Function window"}  
 @{" Variable window " link "Variable window"}  
 @{" History window " link "History window"}  
 @{" Breakpoint window " link "Breakpoint window"}  
 @{" Stack window " link "Stack window"}  
 @{" Profiler  " link "Profiler"}  
 @{" Hex editor " link "Hex editor"}  
 @{" Disassembler " link "Disassembler"}  
 @{" Menu reference " link "Menu reference"}  

 @{" Index     " link "Index"}


@endnode

@node "Debug files" "StormRun.guide/Debug files"
@next "Resource tracking"
@prev "Main"
@toc "Main"

Debug files
===========

   If you wish, the compiler creates a debug file to each file, this
has the same name as the object file, with the suffix @{b}.debug@{ub} instead of
@{b}.o@{ub}. This file contains all information about the module: type
descriptions, variables, functions, and so on.

   The linker creates a link file. This has the same name as the
created program, but with the suffix @{b}.link@{ub} added to it. This file
describes which parts of an object file or linker library are written
to which parts of the program.

Debugging linker libraries
--------------------------

   In theory it is possible to build linker libraries by simply joining
the single object modules. The usage of the @{b}StormLibrarian@{ub} however also
allows the creation of a @{b}llnk@{ub}-ffile. This special link file, with a
format closely related to that of a link file of the linker, describes
which object files are in the linker library, and in which order.

   The debugger loads these llnk files as well as the link and
debugfiles, thus enabling the debugging in linker libraries just as in
other modules of the program. Modules from linker libraries are
highlighted extra in the module window.

The emergency debug file
------------------------

   If a program is outside the sourcecode, for instance in an assembler
part of the program or a shared library of the AmigaOS, the debugger of
course can not load a debug file. Accordingly all type descriptions,
which are normally taken from the debug file, fail.

   In this case, the debugger tries to load an emergency debug file
@{b}StormC:StormSYS/internal.debug@{ub}.  A minimal debug file is enough to show
at least the base types of the registers in the variable window. You
can also copy a larger debug file to this location - in that case all
types which are defined in this debug file will be available to you.
This way you can for instance cast registers to the relevant AmigaOS
datastructures.


@endnode

@node "Resource tracking" "StormRun.guide/Resource tracking"
@next "Enforcer support"
@prev "Debug files"
@toc "Main"

Resource tracking
=================

   StormRun can control various resources of the system, which are used
by the programs.  If those resources are not released at the end of the
program, a list of those resources will be shown. In this case, or if
the program crashes, you can free the resources.

   The controlled resources are memory, windows, screens, public
MsgPorts and semaphores and locks. If a program does not free these
resources, it will influence further working with the AmigaOS, or can
even lead to a system crash (SimpleRefresh window).

   In the programstart preferences of a project you can determine if a
program should work with or without resource tracking. If you turn on
resource tracking, this has the following consequences:

  1. Before each call of @{b}Wait()@{ub} the program passes the signalmask to the
     debugger, this is shown in the control window (Program waits on
     ...).

  2. After the @{b}Wait()@{ub} is ended, the program passes the received signals
     to the debugger, this is shown in the control window.

  3. All memory access with @{b}AllocMem()@{ub} and @{b}AllocVec()@{ub} are noted in a
     list. When memory is freed using @{b}FreeMem()@{ub} and @{b}FreeVec()@{ub}, the
     memory entries are removed from the list. Memoryblocs which remain
     in the list after program end, are shown as non-released
     memoryblocks in the resource tracking.

     Since a program can gather many such blocks very fast (asp. when
     aborting the program using Kill), only the first 20 memoryblocks
     are shown as single blocks in the log.  The other blocks are shown
     as one entry, with the entire size of the used memory.

  4. Shared Libraries opened with @{b}OpenLibrary()@{ub}, and not closed by the
     program with @{b}CloseLibrary()@{ub} are shown in the resource log.

  5. If MsgPorts are publicly created with @{b}AddPort()@{ub}, but not removed
     with @{b}RemPort()@{ub}, this will be shown in the resource log.

  6. Screens opened with @{b}OpenScreen()@{ub}, @{b}OpenScreenTagList()@{ub} or
     @{b}OpenScreenTags()@{ub}but not closed with @{b}CloseScreen()@{ub}, will be shown
     in the resource log.

  7. Windows opened with @{b}OpenWindow()@{ub}, @{b}OpenWindowTagList()@{ub} or
     @{b}OpenWindowTags()@{ub}, but not closed with @{b}CloseWindow()@{ub}, will be shown
     in the resource log.

  8. Locks created with @{b}Lock()@{ub}, @{b}CreateDir()@{ub}, @{b}DupLock()@{ub},
     @{b}DupLockFromFH()@{ub}, @{b}ParentDir()@{ub} or @{b}ParentOfFH()@{ub}, but not freed or
     passed to the DOS with @{b}UnLock()@{ub}, @{b}AssignLock()@{ub} or @{b}AssignAdd()@{ub}, will
     be shown in the resource log.

  9. Files opened with @{b}Open()@{ub} or @{b}OpenFromLock()@{ub}, but not closed or
     passed to the DOS with @{b}Close()@{ub}, @{b}CreateNewProc()@{ub} or @{b}SystemTagList()@{ub},
     will be shown in the resource log.

 10. Apart from that, further tasks or processes which a 68K program
     creates will also be put in the program control. Furthermore, the
     enforcer support will be activated.


@endnode

@node "Enforcer support" "StormRun.guide/Enforcer support"
@next "Debugging PPC programs"
@prev "Resource tracking"
@toc "Main"

Enforcer support
================

   The Enforcer divides the memory in allowed and forbidden
memory-areas, and throws "Enforcer hits" if programs access forbidden
memory-areas.

   StormRun catches such access, and halts the program at the relevant
place.  Resource tracking must be turned on for this to function.


@endnode

@node "Debugging PPC programs" "StormRun.guide/Debugging PPC programs"
@next "Debugging shared libraries"
@prev "Enforcer support"
@toc "Main"

Debugging PPC programs
======================

   Because of the peculiarities of the two CPUs, some special rules
apply to debugging a PPC program.

  1. Even though the debugger in theory catches all PPC programs that
     cause a WarpOS crash, you better start your programs in debug mode
     in the test phase, and start the program with the breakpoint in
     the @{b}main()-@{ub}function. By doing this, the PPC program is known to
     the debugger, and will be added to the list of programs (Task
     window).

     After that, you can also run the program fast by using the
     menu-item "Go" from the "Debug" menu. If a crash occurs, this
     doesn't lead to a WarpOS crash-dialog, but the program simply
     halts at the questionable point. With the help of the stack window
     you can then try to find the reason of the crash.

  2. The debugger has problems if a PPC program is not finished by the
     @{b}main()-@{ub}function, but by @{b}abort()@{ub} or @{b}exit()@{ub}. Even though the WarpOS
     task is finished, the entry in the Task window still exists. You
     either ignore this program, or simply quit the debugger. If you
     don't want to end the entire StormC system when doing this, you
     should not select the menu-item "Quit" from the "Project" menu,
     but you enter a shell, find the process number of the debugger
     using @{b}status@{ub} and send it a break signal using @{b}break@{ub}.

  3. The debugger can't pause PPC-programs, nor can it kill them.
     Furthermore, a priority-change doesn't refer to the PPC program,
     but always to the 68K program assigned to the PPC program.

  4. WarpOS contains something similar to the AmigaOS enforcer. The MMU
     watches all access to illegal memory-areas, if the program
     requests it even protected memory can be used. If this safety
     catch is not kept, the debugger will catch this error and stop the
     program at the relevant place.

  5. Be careful not to enter into context switches. Skip all calls to
     AmigaOS functions and other 68K functions with the menu-item "Step
     over". This causes the context switch to be executed fast. If you
     want to debug a 68K function, you must set a breakpoint at the
     entry point of the function called by the context switch. Do not
     forget to exit the 68K function with a "Go"!


@endnode

@node "Debugging shared libraries" "StormRun.guide/Debugging shared libraries"
@next "Programmed breakpoints"
@prev "Debugging PPC programs"
@toc "Main"

Debugging shared libraries
==========================

   If you want to debug from a 68K program into a shared library, in
other words entering the function in single steps, the debugger
recognises the change into the shared library by the special call (@{b}jsr
-offset(a6(@{ub}). It then executes the jump into the actual function, and
pauses there.

   Now the debugger tries to load the link file of the shared library.
If however the shared library was not loaded using an absolute path,
and the link file is in the same directory as the shared library, it
will hardly ever succeed. In that case, load the link file in the
segment window.

   After that you can show the PC using the menu-item "show PC" of the
"Debug" menu, and debug the function of the shared library.

   The segment of a shared library is not automatically removed when
the shared library is removed from the system. You can remove a shared
library which isn't opened anymore form the system using @{b}avail flush@{ub}.
You have to remove the segment from the debugger manually, or quit the
entire debugger.


@endnode

@node "Programmed breakpoints" "StormRun.guide/Programmed breakpoints"
@next "Control window"
@prev "Debugging shared libraries"
@toc "Main"

Programmed breakpoints
======================

   To be able to pause the program or a shared library at a specific
point, you can also program breakpoints. In 68K programs you can use
the stormdebug.lib. This contains a function

     void __stormbreak(void);

   If you call this function, the debugger pauses after the function.
If you did not start the program from the debugger, this doesn't
matter, the function then does not create a breakpoint or cause a crash.

   You can also enforce a harmless enforcer hit, for instance by
reading from address 0:

     char x = *(char *) 0;

   If you run the program from the debugger, with resource tracking
enabled, it will automatically be stopped at the enforcer hit. This
second method also functions with PPC programs.

   To continue the program you have to skip the command causing the
enforcer hit. To do that, set a breakpoint after the command, and in
the breakpoint window set the PC to this new breakpoint.


@endnode

@node "Control window" "StormRun.guide/Control window"
@next "Address dialog"
@prev "Programmed breakpoints"
@toc "Main"

Control window
==============

   The control window is used to control the program, and show the
resource-tracking.  It is automatically opened when a program is
started.

   * Status line:

     Shows status messages of the program. The most important messages
     are:
        * Program stopped at breakpoint: The program encountered a
          breakpoint, and pauses. This doesn't have to be a breakpoint
          you set, the debugger also sets breakpoints when stepping
          through the program, to group C and C++ commands, which
          normally consist of multiple machinecode commands, to one
          step.

        * Program continued: Shows that the program is currently
          running.

        * Program is waiting for ...:

          The program is waiting for signals in the Exec function
          @{b}Wait()@{ub}, the signal mask is shown. The bits 12 through 15
          represent the signals @{b}Ctrl-C@{ub}, @{b}Ctrl-D@{ub}, @{b}Ctrl-E@{ub} and @{b}Ctrl-F@{ub}.
          Signals for message ports usually have very high bitnumbers.

   * Debugger control:

     The group with the debugger controls contains a switch in the
     border, to turn the debugger on- and off. When the debugger is
     turned on, the buttons within the border, for controlling the
     program, can be used.

     If you just start the program, you can turn on the debugger at any
     time. In that case, the debugger-information will be loaded. The
     program must be stopped with a breakpoint at the right place. To
     do this, you select the program segment from the segment window, a
     module from the module window, and either directly set a
     breakpoint in the corresponding sourcecode or select a function
     from the functions and set a breakpoint there.

        * Go to next breakpoint: If you do not set any breakpoints in
          your program, the program will be executed as normal.

          The program runs at the maximum CPU-speed, until the next
          breakpoint is found. This must be set in the editor. Since
          the debugger and the editor go through the program fully
          multitasking, the breakpoint can also be set at a later time.

          The menu-item "Go" in the "Debugger"-menu has the same effect.

        * Go single step: This step always goes to the next breakpoint
          visible in a sourcecode. Functions are also entered and
          searched for breakpoints.

          Functions without sourcecode are still run in single step
          mode, so that sub-program calls, going back to a module in
          the sourcecode, can be paused. Such jumps back can also happen
          from linker-libraries using function pointers or virtual
          function-members in C++ -classes.  The running speed of
          library functions therefore is low.

          Functions from shared-libraries however are always executed
          at full CPU speed.  For this reason the program is not paused
          with jumps back from such a library.  So, if you want to test
          the behavior of a hookfunction, you must set a breakpoint in
          the hookfunction before calling the library function which
          calls your hookfunction.

          It can be important to step through @{b}Forbid()@{ub}/@{b}Permit()@{ub} parts in
          single steps. The protection is cancelled after each step
          (the program sends a message to the debugger, and waits for
          an answer) and other tasks can run again. If at this time one
          of the global systemlists isn't valid, the computer may
          crash. If you only use the @{b}Forbid()@{ub}/@{b}Permit()@{ub} part to copy the
          content of a global data-structure (for instance the list of
          all waiting tasks in the system), it is likely that the
          result is not correct.

          Inline-function can be treated as one command. The compiler
          inserts inline-functions directly in the program, using heavy
          optimizing. So a relation between the commands in the program
          and the sourcecode of the inline-function is not possible. For
          the testing phase of a program you can set the
          compiler-option "do not inline", forcing the compiler to
          treat each inline-function as a normal function. This way,
          you can also run inline-functions in single steps.

          The menu-item "Single Step" from the "Debugger"-menu has the
          same effect.

        * Go step and run functions fast: This step always goes to the
          next visible breakpoint in a sourcecode, but function calls
          are executed at full CPU-speed. If the program finds a
          breakpoint in the function, it pauses.

          The menu-item "Step over" in the "Debugger"-menu has the same
          effect.

        * Go until function is left: The program is executed in single
          steps, until the current function returns to the calling
          function. Sub-program calls are executed fast.

          The menu-item "Exit function" in the "Debugger"-menu has the
          same effect.

        * Show current PC in source: This position always is the
          position after the last step, or reaching a breakpoint.  If
          the sourcecode-position in the editor was lost, for instance
          by showing the position of a variable definition in the
          sourcecode, it can be shown using this button.

          Normally the debugger shows all sourcecodes in the same
          editor window, for every sourcecode change the new sourcecode
          will be loaded, and the old one removed from memory. This
          reduces the amount of open windows on the screen.

          If a sourcecode is very often needed however, it can pay off
          to keep this open at all times. Load the sourcecode by
          double-clicking its entry in the project (not by double
          clicking the entry in the module window). The text will be
          loaded normally.  If the text is needed the next time, the
          breakpoints are automatically added. Now you can work with 2
          (or 3, or 4, ...) sourcecode windows at the same time.

          The menu item "Show PC" from the "Debugger"-menu has the same
          effect.

        * Pause: Pauses the program as long as the button is pressed.
          The program will be taken from the list of running or waiting
          tasks. If the program receives signals while it is paused, it
          is not guaranteed that those signals are processed after
          reactivating.  Currently this doesn't function for PPC
          programs.

          The menu-item "Pause" in the "Debugger" -menu has the same
          effect.

        * Kill: The program will be stopped. It can not be considered
          if the program is in a critical situation. A
          @{b}Forbid()@{ub}/@{b}Permit()@{ub} section however can not be killed, because
          the kill of the debugger can only be processed after the
          @{b}Permit()@{ub}. This currently does not function for PPC programs.

          The menu-item "Kill" from the "Debugger" -menu has the same
          effect.

   * Priority-symbol:

     The priority of the program can be set from -128 to 127, but it is
     recommended to leave the priority between -20 and 20, to avoid
     conflicts with certain operating system tasks.

     The startpriority (normally -1) has be choosen on purpose: It is
     one smaller than the priority of the debugger, so smooth working
     with the debugger is guaranteed.

   * Signal group:

     The signals @{b}Ctrl-C@{ub}, @{b}Ctrl-D@{ub}, @{b}Ctrl-E@{ub} and @{b}Ctrl-F@{ub} can be set in the
     program at any time. These 4 signals can be used in the testing
     phase of a program for program control.

   * Log list:

     The list shows all resources for which no suitable freeing was
     done in the program. By double-clicking a line, the sourcecode
     position of the reservation can be shown, as long as the call of
     the corresponding operating system function is done directly by
     the program, meaning the function calls are defined using @{b}#pragma
     amicall@{ub} and @{b}#pragma tagcall@{ub} (StormC 3) or inline functions (GCC).

     If the resource can not be linked to a source code position, the
     beep will sound.  Resources without corresponding sourcecode are
     some memory blocks and the shared libraries. These resources are
     reserved by the library @{b}storm.lib@{ub}.

     To avoid unnecessary logs, only resources which are reserved from
     within the program are shown. So resources reserved indirectly
     from a shared library are not shown. You can maybe imagine how
     many implicit memory requirements a @{b}OpenWindowTags()@{ub} causes...

     The resources are freed vary carefully. Since the resources in
     general only are pointers to a data-structure, and a release by
     other operation system functions might not have been logged, it is
     first tested if for instance at the time or release a screen with
     the datastructure screen still exists, before the screen is closed
     with @{b}CloseScreen()@{ub}.

     Normally however all resources are freed.

   * Closegadget of the window:

     The window is automatically closed when the program is finished
     and now resource is reserved anymore.

     When closing the window you are asked if you want to free any used
     resources.


@endnode

@node "Address dialog" "StormRun.guide/Address dialog"
@next "Task window"
@prev "Control window"
@toc "Main"

Address dialog
==============

   From the menu "Debugger" with the menu-item "Search Address..." the
address dialog is opened. This shows the current address of the program
in two ways, and allows the entry of a new address in any of these two
ways, and the showing of this address in the source code.

   * Address: This textfield contains the address in hexadecimal
     notation.

   * Hunk: This textfield contains the hunk of the program, where the
     address is found.

   * Offset: This textfield contains the offset in the hunk of the
     program, where the address is found.

   * Search: Searches the sourcecode position of the given address or
     the hunk/offset pair. If the address can not be found, the beep
     sounds (or the screen flashes, depending on the settings in the
     sound prefs editor of the Workbench).

     The search far a hunk-/offset pair is always done in the segment
     (program or shared library) which is selected in the segment
     window.

   * Cancel: Closes the dialog.

   Every program on the Amiga consists of at least one hunk with the
number 0.  Further hunks have ascending numbers. Each address within a
program can be converted to a hunk and an offset in this hunk, and each
hunk-/offset pair to an address, when this is searches for in a
particular program.

   Many programs to find errors use this representation, because as
opposed to the physical address the hunk/offset notation still is valid
after for instance a restart of a program, whereas physical addresses
change every time a program is run.

   As soon as you change one of the three values, it is tried to
calculate the other notation. If you search for a certain hunk-/offset
pair (for instance after an enforcer hit of your program), you can
easily find the physical address, and use the button search to show the
corresponding sourcecode position.


@endnode

@node "Task window" "StormRun.guide/Task window"
@next "Segment window"
@prev "Address dialog"
@toc "Main"

Task window
===========

   The task window shows all running programs which are managed by the
debugger in a list. By selecting a program from the list this will
become the active program, which is controlled by the control window,
its variables are shown in the variable window, its history is shown in
the history window and so on.

   You can open the task window at any time using the menu-item "Tasks"
from the "Windows" -menu.

   A PPC program always consists of 2 programs: a 68k program, that at
least causes the start of the PPC program, and a PPC program.

   With the cycle gadget you can sort the list either by number of the
program, which corresponds to the starting order of the programs, or
alphabetical by the names of the programs.


@endnode

@node "Segment window" "StormRun.guide/Segment window"
@next "Module window"
@prev "Task window"
@toc "Main"

Segment window
==============

   In the segments window all segments controlled by the debugger are
shown. This includes the segments (Executables) of the single programs,
but also those from shared libraries or other programs which the
debugger searches for addresses. You can sort the segments either in
the order they where included in the debugger, or alphabetical by their
names.

   You can open the segments window at any time using the menu-item
"Segments" in the "Windows" menu.

   The selected segment in the list also determines which module is
shown in the module window, and in which segment the address dialog
searches.

   The first column of the lists shows with a symbol if a linkfile was
loaded to the segment. Aspecially with shared libraries the debugger
often can not automatically find the linkfile.

   * Load linkfile:

     With the first button you open a file requester to select a
     linkfile. The linkfile will than be loaded to the segment. Now the
     modules of the segment will also be available in the module window.

   * Remove segment from list:

     With this segments can manually be removed from the list, for
     instance before a new version of a shared library should be loaded.


@endnode

@node "Module window" "StormRun.guide/Module window"
@next "Function window"
@prev "Segment window"
@toc "Main"

Module window
=============

   In the module window all modules of a segment are listed. This
window can be opened at any time using the menu-item "Module" from the
"Windows" -menu.  From the list of the modules, the sourcecode of a
module can be shown by double-clicking the module name.

   The first column of the list with a symbol shows if the module has a
debug file.  Only then can the debugger process this module in a useful
way. The second column shows if the module comes from a linker-library.

   * Show source:

     The first button loads the sourcecode of the module in the editor.

   * Show functions: The second button shows all functions of the
     module in a new window.

   * Sorting:

     You can sort the modules as the linker puts them in the linkfile,
     or alphabetically by the names.


@endnode

@node "Function window" "StormRun.guide/Function window"
@next "Variable window"
@prev "Module window"
@toc "Main"

Function window
===============

   The function window is opened from the module window, and shows all
functions of a module. The functions are shown once with their names,
and at the right of this with their full prototype.

   * Show source:

     The first button loads the sourcecode of the module in the editor
     and puts the cursor at the beginning of the selected function. The
     position of the disassembler will be put to the address of the
     function begin. The same can be achieved by double-clicking a
     function-entry in the list.

   * Show disassembled code of function:

     The position of the disassembler will be put to the address of the
     function begin, and the disassembler window will be opened.

   * Set breakpoint at function entry:

     At the beginning of the selected function a breakpoint will be
     set. When the function is entered, the program pauses.

   * Sorting:

     Sort the functions either by the order in the debug files, which
     is about the same as the order in the sourcecode, or
     alphabetically by the function names.


@endnode

@node "Variable window" "StormRun.guide/Variable window"
@next "History window"
@prev "Function window"
@toc "Main"

Variable window
===============

   The window of variables shows all variables and watched variables.
It can be opened at any time using the menu-item "Variables..." from
the "Windows" -menu.

   Every variable will be shown with the name, the type, the memory
class and the value, for instance:

     counter <LONG, stack> 42

   The type will be displayed in Amiga specific notation, so @{b}LONG@{ub}
instead of @{b}long int@{ub} and @{b}UBYTE@{ub} instead of @{b}unsigned char@{ub}. The type is
followed by the memory class. This shows where the variable is saved.
By the optimization of the compiler, variables are often put in the
same registers, or in temporary used registers. Don't be surprised when
a variable with the memory class @{b}D0@{ub} changes its value constantly, since
this register is very often used.

   The list of memory classes:

   * far data: A global variable in the large data model.

   * near data: A global variable in the small data model with a4.

   * near data(a6): A global variable in the small data model with a6.

   * stack: A local variable or a function parameter on the stack.

   * D0 through D7, A0 through A6, FP0 through FP7, r0 through r31, fp0
     through fp31: A variable in the respective data-, address,
     FPU-register, common PPC register or PPC FPU-register.

   The values of the variables are shown in the suitable C syntax. Many
values however can be interpreted in more ways than one, and are
therefore also shown in more ways than one:

   Numbers are shown decimal and hexadecimal. Signed types (@{b}LONG@{ub}, @{b}BYTE@{ub}
and so on) are shown decimal with sign, but hexadecimal without sign.
@{b}UBYTE@{ub} and @{b}BYTE@{ub} (@{b}unsigned char@{ub} and @{b}char@{ub}) are interpreted as ANSI
character, if the sign is not a control sign.

   Floating point numbers are only shown in decimal notation, if you
are interested in the binary notation you should look in the hex editor.

   Enumeration types are shown with their numeric value and the name of
the constant.

   Pointers are also shown hexadecimal. This address is followed by the
arrow @{b}->@{ub} and the value at which the pointer points. If the pointer
points at @{b}UBYTE@{ub} or @{b}BYTE@{ub}, the pointer will also be interpreted as a
pointer to a string, and the first 40 characters will be shown.

   Structures and arrays are shown in brackets, like the constant
definition, and the elements contained in it. To restrict the length of
the value for a structure or an array, numbers are only shown decimal,
pointers will only be shown with the hexadecimal address and for
interlocking structures and arrays only the brackets @{b}{...}@{ub} are shown.
The inspection allows a closer look at the values of the elements.

   * Show actual variables: The first button shows all variables and
     parameters of the current function.

   * Show global variables: The second button shows the global
     variables of all modules, of which the debug files have already
     been loaded, in other words, the module has already been accessed
     in some way before.

     Variables which are only declared external are not shown.

   * Show watched variables: The third button shows all watched
     variables:

     In this list any variables from the other pages, or also elements
     of an inspection can be entered. The value of those variables is
     of course not always valid, for instance register variables are
     only valid in certain areas of a function, and variables on the
     stack only as long as the program is inside the function.

   * Show CPU registers: The fourth button shows all CPU registers.

   * Show source: The fifth button shows the definition of the selected
     variable in the sourcecode.  The sourcecode will be loaded, and
     the cursor will be put on the variable definition.

   * Show functions: The sixth button shows the member functions of the
     selected variable in a new window. Only variables with a @{b}struct@{ub} or
     @{b}class@{ub} type can have member functions in C++.

   * Inspect variable: The seventh button inspects the selected
     variable. For this the current variable list (can already be an
     inspection) will be replaced by a list of the elements of the
     variable.

     If the variable has a @{b}struct@{ub}, @{b}union@{ub} or @{b}class@{ub} type, all members
     will be shown. If the variable has an array type, the single
     array-fields will be shown. If the variable has a pointer type,
     the type of the pointer will be shown.

   * Pop inspection stack: With the eighth button the previous
     inspection will be shown anew with interlocking inspection,
     otherwise the variable page shown before the inspection, the
     current, global, watched, register- or stack- variables, will be
     shown.

   * Show value in hex editor: The ninth button opens the hex editor
     and puts the cursor at the address of the selected variable. The
     start- and end address of the memoryblock in the hex-editor will
     be the first and last address of the variable.

   * Watch variable: The tenth button inserts the variable in the list
     of watched variables.

   * Remove watched variable: The eleventh button removes the variable
     from the list of watched variables.

   * Cast: Allows you to change the type of a variable. In the typelist
     of the window the original type is always shown, the value shown
     will however depend on the type entered here.

     By clearing the field the original defined type will be restored.

     The type string must be the same as the output by the debugger.
     Only single types in Amiga-typical notations (@{b}BYTE@{ub}, @{b}LONG@{ub}, @{b}DOUBLE@{ub},
     pointers to these types (@{b}BYTE *@{ub}, @{b}LONG *@{ub}, etc) and all types which
     are defined at any point in the module can be entered.

     As a type string you can also enter an AmigaDOS pattern. By
     clicking the selection-menubutton at the right of the string
     gadget a selection menu will be opened with all types matching the
     pattern. Select a type from this list, it will replace the previous
     contents of the textfield.

   * Arraycast: To change a variable into an array you enter the low
     and the high index. Next, you use the arrow to pass these values
     to the type next to it, and cast it to an array this way.

   * Low: The low index normally is 0, this is the start address of the
     shown variable.  You can however also enter an index greater or
     smaller than 0, the start address of the new array type will be
     moved accordingly. The shown variable however always is at index 0.

   * High: The high index determines the last shown array element. It
     also can be greater or smaller than 0, but should always be
     greater than the low index.

   * Value: Numerical types allow direct changing of the value through
     the hex editor.  The entry can be done decimal, octal or
     hexadecimal in typical C-notation.

     Strings can be changed in the same way, the memory area at which a
     pointer to @{b}UBYTE@{ub} or @{b}BYTE@{ub} points can be filled with a new string
     directly.  It can not be checked if the new string is to long,
     overwriting the memory after the buffer reserved for the old
     string.

   * Sorting: You can leave the variable display unsorted, this is the
     order of the debug file. Or you sort the variables alphabetically
     by name, or by last changes. The last method always puts the last
     changed variable at the top of the variable list.

     Note however, that variables are saved in CPU registers when
     optimizing. So various variables in a function can be assigned one
     register. If this CPU register is changed, all variables will be
     changed, and move to the top of the variable list. The debugger
     can not see when a variable is really used - through optimizing a
     local variable is often used for a shorter period than its
     definition in the function.


@endnode

@node "History window" "StormRun.guide/History window"
@next "Breakpoint window"
@prev "Variable window"
@toc "Main"

History window
==============

   In this window the last steps of the program are logged. You can use
it to check how your program runs in the sourcecode, for instance when
you get unexpected behavior of your program, and want to check why it
can behave this way. The history window can be opened at any time using
the entry "History..." in the "Windows" menu.

   Double-clicking an entry shows the sourcecode location in the editor.

   * Show source: The first button loads the sourcecode in the editor,
     and puts the cursor on the line of the position which the program
     had at the previous time. The position of the disassembler will be
     set to the address of the former PC.

   * Show disassembled code: The second button puts the position of the
     disassembler at the address of the former PC, and opens the
     disassembler window.

   * Freeze history entry: The third button freezes the selected entry.
     This is shown by a small symbol at the left of the entry. Frozen
     symbols are not removed from the list by later entries, and are
     therefore always available.

   * Set PC to history entry: Each history step not only saves the
     program position, but also the CPU register according to the
     function @{b}setjmp()@{ub}. With the fourth button you can reset the PC and
     the CPU register, similar to a call of @{b}longjmp()@{ub}. So it is possible
     to return directly from interlocking functions.

   * Clear history: Removes all entries of the history.

   * Entries: The maximum number of entries in the history. This value
     must be between 10 and 256.


@endnode

@node "Breakpoint window" "StormRun.guide/Breakpoint window"
@next "Stack window"
@prev "History window"
@toc "Main"

Breakpoint window
=================

   In the breakpoint window all set breakpoint are shown. The
breakpoint window can be opened at any time using the menu-item
"Breakpoints" from the "Windows" menu.

   Double-clicking the entry shows the breakpoint in the editor.

   The top line contains 4 buttons and a cycle gadget.

   * Show source of breakpoint: The first button loads the sourcecode
     where the breakpoint is set in the editor, and puts the cursor at
     the respective line. Furthermore, the position of the disassembler
     is set to the address of the breakpoint.

   * Show disassembled code under breakpoint: The second button puts
     the position of the disassembler to the address of the breakpoint,
     just like the first button, but also opens the disassembler window.

   * Remove breakpoint: The third button removes the selected
     breakpoint.

   * Set PC to breakpoint: The fourth button sets the PC of the
     activated program to the address of the selected breakpoint.

     Note: This is an extremely easy way to make the program crash.
     Aspecially jumping from one function to a completely different
     function can almost only lead to a crash.

   * Sorting: Normally the breakpoints are shown in the order they are
     set. This sorting can be changed to alphabetical, where the first
     search item is the module name, and the second the line number of
     the breakpoint.

   Take care with breakpoints which are used by multiple tasks
simultaneously, for instance a dispatcher of a BOOPSI-gadget. Such a
dispatcher is processed by your program as well as by the task
@{b}input.device@{ub} (as long as the gadget is part of an open window). A
breakpoint in the dispatcher could lead to an exception in the
@{b}input.device@{ub}, crashing the entire system.

   PPC programs are more robust in this respect: as soon as a PPC
program encounters a breakpoint, the program is caught by the debugger,
and put under control of the debugger. This also goes for crashes of
PPC programs for other reasons.


@endnode

@node "Stack window" "StormRun.guide/Stack window"
@next "Profiler"
@prev "Breakpoint window"
@toc "Main"

Stack window
============

   The stack window shows the current structure of the stack of the
active program.  You can open the stack window at any time with the
menu-item "Stack..."  from the "Windows" -menu.

   The stack can only be displayed correctly, as far as the function
calls can be traced back. The program should at least be translated
using the option "Debugger frienly code".

   * Show source of function:

     The first button shows the function entry of the selected function
     in the stack list.

   * Show source position of function call:

     The second button shows the source position of the function call
     of the next function.  Furthermore the position of the
     disassembler will be set to the address following the call (the
     address followed by the jump back).

   * Show disassembled code of stack entry:

     The third button sets the position of the disassembler to the
     address followed by the call (the address followed by the jump
     back). Furthermore, the disassembler will be opened.

   * Show local variables of function:

     The local variables of the function at the time of the call are
     shown in the variable window.

     Note however that variable in CPU registers can not always be
     shown correctly.

   * Set breakpoint behind function call:

     A breakpoint is set at the address behind the function call. This
     way, the program pauses after the call.

   * Entries:

     Enter the maximum number of stack entries, between 10 and 256.


@endnode

@node "Profiler" "StormRun.guide/Profiler"
@next "Hex editor"
@prev "Stack window"
@toc "Main"

Profiler
========

   The profiler is an indispensable tool when a program must be
optimized. All optimizing possibilities of the compiler only can speed
up a program so far.  A profiler however can give indications, which
functions of a program need much time. These functions should, if
possible, be rewritten with a new algorithm or at least be optimized
manually as good as possible.

   To activate the profiler, the debug option in the compiler settings
has to be set to "Large debugfiles" or "Small debugfiles". In the
startup settings, the option "Use profiler" must be selected. Now the
program can be started as normal.  Debugging the program at the same
time is also possible, but can lead to small failures in the time
measuring.

   After starting the program the profiler log window can be opened.

   In the list the functions are shown with the following information:

  1. The function name:

     Memberber functions of a class or proceeded by the class name with
     two colons.

  2. The percentage time usage:

     Here the time the program spends in the function, or the
     underlying system operating function, is measured. Function calls
     in the own program or not considered.

     This is the most important value to find out which function needs
     very much time.  The sum of all functions in this column is 99 -
     100% (the failing percent is used in the startup code, and small
     failures).

  3. The percentage recursive time used:

     Here all subprogram calls are also measured. For this reason, the
     function main() almost always is 99 %.

  4. The absolute time used

  5. The maximum time used

  6. The minimum time used:

     These three columns allow an overview of the calls of this
     function. How a function can be optimized often depend on the fact
     if the function in general uses the same time for each call (small
     difference between maximum and minimum time), or needs much more
     time for some calls than for others (high difference). In this
     case, it might help to optimize those special cases.

  7. The number of calls:

     A function needing a lot of time, but only because it gets called
     often, but only uses a short time per call, is hard to optimize.
     Of course it can help here to declare the function as
     inline-function (@{b}__inline@{ub} in ANSI-C, @{b}inline@{ub} in C++).

   Above this list there are some elements to work with the log:

   The top line shows the CPU time used. This time is the real CPU
time, so the time the program waits (for signals, messages or I/O) is
not measured, as is time where the program is not running, while it is
the turn of other programs in multitasking.

   Below this there are four buttons at the left. The first one updates
the function list.

   With the second button you delete the log so far. This way, you can
measure separate parts of the program.

   With the third button you can save the profiler log as ASCII file, a
file requester is opened for this.

   The second button prints the log to a printer (uses the device @{b}PRT:@{ub}).

   At the right of this line you can determine the sorting of the
function list.  The first entry procentual sorts the list by the second
column, the entry recursive sorts the list by the third column, the
entry alphabetical sorts the list alphabetically by function names of
the first column. And the last entry calls sorts the list by the last
column.

   A line under this one is a text string gadget for a DOS-pattern.
This DOS-pattern is used for the function names, and allows you to keep
the list, which can get very long, a reasonable size. For instance you
can easily limit the list to all methods of a class, by entering the
class name followed by @{b}"#?"@{ub}.

   At the right of this you find an integer field where you can enter
the minimum percentage the functions must have, in order for them to be
shown. Functions with less than 5% or 10% are often very hard to
optimize, and even halving the runtime would only increase the program
by 2.5% or 5%.

   Apart from these selectable limitations, only functions which are
called at least once are shown.

   By double-clicking a function you can directly jump to it in the
source code.

   The profiler log is automatically opened at the and of the program
run, and the display is updated. If the control window is closed, the
profiler log window is also closed, and the list deleted. If you need
the profiler information at a later time, it must first be saved or
printed.

Technical information to the profiler
-------------------------------------

   When jumping into a function, the LINE $A commands @{b}$A123@{ub} and @{b}$A124@{ub}
of the 68K CPU are used.

   These machine commands are unused in all motorola 68k CPUs, and
cause an exception. This exception leads to logging of the times and
calls.

   For PPC programs the TWI commands are used at function entry. These
commands are unused in WarpOS, and cause an exception.

   Using exceptions has the minor disadvantage that they lower the
maximum program speed, the program runs slower than it would without
profiler. This can play a bigger role when many calls of smaller
functions are used.

   The use of recursions is limited: the minimum- and maximum values
are often not correct, the total time (and thus the procentual values)
can be wrong. A single recursion (@{b}f()@{ub} calls @{b}f()@{ub}) shows the correct
procentual values, an interlocking recursion (@{b}f()@{ub} calls @{b}g()@{ub} calls @{b}f()@{ub})
adds all times to one of both functions. Function calls leading out off
the recursion are treated correctly.

   The results of @{b}longjump()@{ub} is not exactly predictable, normally it
should however only cause a small error at function exit and function
entry.

   In theory not all functions can be measured: Only functions which
start with a @{b}link@{ub} or a @{b}momem@{ub} command in their machinecode in 68k or
contain a @{b}mlr r0@{ub} in the PPC are available to the PPC. These commands
are almost always available in 68k programs, but the @{b}mlr@{ub}-command in PPC
programs can only be guaranteed if a function calls another function.
Function which do not contain a function call can not be measured most
of the times. Their times are automatically added to the times of the
calling function.

   In general inline function can not be measured, since they are not
recognised as separate functions.


@endnode

@node "Hex editor" "StormRun.guide/Hex editor"
@next "Disassembler"
@prev "Profiler"
@toc "Main"

Hex editor
==========

   The hex editor shows a memory area in hexadecimal and as
ASCII-signs. The display can be done byte-, word- or longword wise.

   * Load binary from file to cursor address:

     The first button opens a file requester to select a file. The file
     will be loaded at the address. Careful: by doing this you can very
     easily overwrite other memory, crashing the entire system.

   * Save block to file:

     The second button opens a filerequester to select a filename. To
     this file, the memory from the start address to the end address
     will be saved.

   * Write ASCII dump of block to file:

     The third button opens a filerequester to select a filename. To
     this file an ASCII representation will be saved from the start
     address to the end address.

   * Print ASCII dump of block:

     The fourth button outputs the ASCII representation from the start
     address to the end address to the printer. The printer settings of
     the workbench printer are used.

   * Refresh window:

     The fifth button refreshes the screen display.

   * Freeze window:

     The sixth button freezes the screen display, even if a new display
     of the contents is created by the debugger. This way, the old
     memory contents will remain available on screen.

   * Inspect address under cursor:

     The cursor address is first round to even addresses, and the value
     of the longword in it is used as a new address. This way, you can
     trace pointers in the hex editor.

   * Return from inspection:

     When inspecting an address, the old cursor address is remembered
     on an address stack.  With the eighth button you can return to the
     last address.

   * Selecting the representation:

     This cycle gadget lets you select the representation of the
     hexadecimal values.  This can be either byte, word or longword.

   * The cursor address:

     This textfield shows the current address under the cursor, or sets
     a new address.

   * The start address:

     This textfield allows you to enter a start address of a
     memoryblock.

   * The end address:

     This textfield lets you enter an end address of a memoryblock.
     This memoryblock is automatically set by showing a variable from
     the variable window in the hex editor. Contents of the memoryblock
     or highlighted. The memoryblock can be saved as binary or an ASCII
     representation of it can be saved or printed.

   * The address column:

     In this column the address of the first byte of every line is
     shown. This address can also be changed directly, you don't have
     to use the address string gadget for this.

   * The hexadecimal column:

     In this column, the hexadecimal values at the memory point is
     shown. If the address points to an invalid memory area, only minus
     signs are shown, and changes are impossible. To avoid enforcer
     hits, the memory places are not read.

   * The ASCII column: In this column, the ANSI-sign of the memory cel
     is shown. If the value is outside the scope of the ANSI-table, a
     dot is shown, the same for invalid memory addresses.

Keyboard navigation
-------------------

   The four cursor keys move the cursor within the column.

   The @{b}Tab@{ub}-key allows you to change from one column to the next.

   In the address column and the hexadecimal columns the keys @{b}0@{ub} through
@{b}9@{ub}, @{b}a@{ub} through @{b}f@{ub} (also with @{b}Shift@{ub}, so @{b}A@{ub} through @{b}F@{ub}) are allowed.

   The ASCII-column of course contains each sign, that can be printed.

Scroll gadget
-------------

   To make work with a scroller even easier, the entire area of the
vertical scroller is limited to 8 KByte. If however you move the mouse
over the top or bottom border of the hex editor view, the shown address
is set to 4 KByte higher or lower. This way, you have an overview of
larger areas using the scroller.

   For really large address changes the direct input of the address is
recommended, because of the large address space of the CPU.


@endnode

@node "Disassembler" "StormRun.guide/Disassembler"
@next "Menu reference"
@prev "Hex editor"
@toc "Main"

Disassembler
============

   The disassembler shows 68K and PPC assembler.

   You can open the disassembler at any time using the menu-item
"Disassembler" from the "Windows" menu.

   In the left column the disassembler shows the possible and the set
breakpoints.  You can set a breakpoint at each valid machine command.

   Next to that is the address of the machine command, possibly the
hex-view and the Assembler text. The cursor line, the line of the
current address, is shown highlighted.

   * Debug:

     If the third button is pressed, debugging is done at disassembler
     level. This makes a single step in the debugger one machine
     command, and not a complete C command.

   * Show breakpoint code:

     If the second button is selected, the disassembler shows
     breakpoints with their real code (for instance an ILLEGAL command
     in 68K) instead of the original code.

   * Show hex dump:

     If the second button is pressed, the code is shown in hex notation
     between the address and the assembler text.

   * Code selection:

     With the code selection you select how the disassembler shows
     code. By selecting "Automatic" the disassembler tries to recognise
     automatically if 68K or PPC code must be shown. In programs
     compiled with StormC (StormC 3 or StormGCC) this normally
     functions, when jumping to foreign PPC shared libraries however it
     can happen that the disassembler shows PPC code as 68K code. The
     selection "M680x0" always shows 68K code, "PPC" always PowerPC
     code.

   * Address:

     In this string gadget is the address of the cursor. You can also
     set a new address - however, this doesn't influence the PC of a
     program.


@endnode

@node "Menu reference" "StormRun.guide/Menu reference"
@next "Index"
@prev "Disassembler"
@toc "Main"

Menu reference
==============

   * Project/About: Opens the information window of the StormShell.

   * Project/Quit: Ends the entire StormC development environment.

   * Edit/Open Clip: Opens a filerequester to select a file, which will
     be copied to the clipboard.

   * Edit/Save Clip As: Opens a filerequester to select a filename. The
     clipboard will be saved to this file.

   * Edit/Show Clip: The contents of the clipboard is shown on the
     public screen of StormC.

   * Debug/Go: The program is continued, and only paused at the next
     breakpoint.

   * Debug/Single Step: The program goes one step further. This is
     either a C command or one single machinecode command.

   * Debug/Step over: The program goes one step further, but the
     function calls in it are processed completely, if the program is
     not paused through a breakpoint.

   * Debug/Exit Function: The program is executed in single step mode,
     until the function is left. Function calls are executed fast.

   * Debug/Show PC: The position of the program is shown in the
     sourcecode and the disassembler.

   * Debug/Search Address: A dialog is opened, where you can search for
     an address or a hunk/offset pair.

   * Window/Messages: The message window of the StormShell is opened.

   * Window/Tasks: The window with the list of all running programs is
     opened.

   * Window/Segments: The window with the list of all program segments
     is opened.

   * Window/Modules: The window with the list of the modules of the
     selected program segment is opened.

   * Window/Variables: The window with the variables of the active
     program is opened.

   * Window/History: The window with the history of the active program
     is opened.

   * Window/Breakpoints: The window with all set breakpoints is opened.

   * Window/Stack: The window with the stack of the active program is
     opened.

   * Window/Profiler log: The window with the profiler log of the
     active program is opened.

   * Window/Hex editor: The hex editor is opened.

   * Window/Disassembler: The disassembler is opened.

   * Help/Bubble Help: With it the Bubble Help can be toggled on and
     off.

   * Help/Help: A dialog is opened, where you can enter a keyword for
     the search index.


@endnode

@node "Index" "StormRun.guide/Index"
@prev "Menu reference"
@toc "Main"

Index
=====

@index "Index"



 @{" .debug                                   " link "Debug files"}   Debug files
 @{" .link                                    " link "Debug files"}   Debug files
 @{" .llnk                                    " link "Debug files"}   Debug files
 @{" __stormbreak(void)                       " link "Programmed breakpoints"}   Programmed breakpoints
 @{" Breakpoints                              " link "Breakpoint window"}   Breakpoint window
 @{" Emergency debug file                     " link "Debug files"}   Debug files
 @{" Enforcer                                 " link "Enforcer support"}   Enforcer support
 @{" Enforcer hit                             " link "Enforcer support"}   Enforcer support
 @{" Forbid()                                 " link "Control window"}   Control window
 @{" History                                  " link "History window"}   History window
 @{" Hunk & Offset                            " link "Address dialog"}   Address dialog
 @{" internal.debug                           " link "Debug files"}   Debug files
 @{" Memory classes                           " link "Variable window"}   Variable window
 @{" Permit()                                 " link "Control window"}   Control window
 @{" Resource tracking                        " link "Resource tracking"}   Resource tracking

@endnode

