Introduction
Within modern versions of the Operating System a new module called DiagnosticDump has been added to provide much more feedback for developers than was previously available. The DiagnosticDump module uses the new APCS backtrace augmentation feature of the SharedCLibrary to record details about application failures. This means that should a failure occur (CPU exception, abort, or assertion) and a backtrace be triggered, a record of the failure will be written to disc.
These records - known as Diagnostic Dumps, or DiagDump for short - can then be decoded by special tools to provide similar information as was displayed within the backtrace itself. Because these files are self-contained, they can either be interpreted by the user, or be transferred to the original developer of the application.
The purpose of these DiagDumps is to provide a means by which better diagnostics of problems can be obtained by developers, even where they do not have access to the system upon which the failure occurs.
By default, the module will record details about the failure and automatically open a Filer window displaying the saved dump. The filename of the dump will reflect the application run, together with the date and time of the failure.
Because sections of memory are recorded which may not directly relate to the failure, users should be careful about who they give the dump files to. See the 'Security issues' section for more details.
In addition to this the module may be called upon to explicitly write a diagnostic dump for the current system state through a SWI. Such a call will write a file (or buffer the file for later writing) which includes the full privileged stack and, if available, the non-privileged application space call trace. This can be used by developers in order to locate unexpected invocation paths or similar problems.
Technical Details
Details recorded
The DiagnosticDump module will record details about the failure to disc. At present the following information is recorded (where available):
- Call stack at point of failure
- Operating System and Platform version and features
- Processor type
- Time of failure
- Register set at point of failure
- Dynamic area names and extents
- Module names and extents
- Command line used to invoke application
- Data referenced by regions referred to within the Call stack.
In addition to this information, the user may choose to expand the regions of memory recorded from just the call stack up to the entire application space of the failing application. It is only expected that this be necessary in a very limited number of cases.
Dump files
A dump recorded because of a failure is given a name made from the date and time of the failure (in UTC) and the name of the application which failed, in the form YYYYMMDD-HHMM-application, within the dump directory. The application name is taken from the command which started the program; where the program is called !RunImage the name of the directory containing it is used instead, and where no useful name can be found the name Dump is used. Dumps requested with SWI DiagnosticDump_Write are named in the same way, with a unique number appended (-1, -2, and so on, counting from the start of the session). On a filing system which cannot hold names of this length a shorter name is used, which identifies only the date and the time.
Reading Diagnostic Dump files
The dump files are stored in a simple chunk format. This format can be obtained on request, although at the present time is subject to change. The BTSDump tool (version 0.35 and later) can be used to read these files. Typically, use:
*BTSDump -i -R <filename>
The BTSDump tool is the default run-type for the DiagData filetype and will cause the dump to be displayed within a TaskWindow.
System Variables
The DiagnosticDump module is controlled by this system variable. When a failure resulting in a backtrace occurs, the module will examine this variable and if enabled it will record the necessary details to a dump file.
The options variable takes a number of arguments. The generalised form of the variable's value is:
<optionchar> := 'A'-'Z' 'a'-'z'
<string> := any but ' '
<option> := <optionchar> |
<optionchar> '0'-'9' |
<optionchar> '=' <string> ' '
<optionlist> := <option> | <option> <optionlist>
The following options are supported at present:
| Option | Meaning |
|---|---|
| Y[<level>] | Enable the module. Without a 'Y' option, dumps will not be generated. If not specified, the <level> defaults to 0. The <level> values determine the amount of information recorded from the application space, in increasing order of dump size: 0 = record backtrace details (usually ~30K); 1 = record backtrace details and application heap; 2 = record backtrace details, application heap and application statics; 3 = record entire application space. |
| O | Automatically open the dump directory if no other handler shows an interest in the dump. After a dump has been recorded, the module issues Service_APCSBacktrace 20 with the name of the dump; if that service is not claimed, the directory is opened. |
When the module starts, if the variable is not set then it is set to 'Y0O'. To disable the module's automatic recording of diagnostic data entirely, unset the variable. Option characters which are not recognised are ignored.
The dump files are held in the directory specified by this variable or, if it is unset, in <Wimp$ScrapDir>.DiagDump. The directory is created if it does not exist.
SWI Calls
| R0 | = | Flags:
| ||||||||||||||||||||||||||||
| R1 | = | If R0 bit 2 is set and R1 is not 0, the name of the file to write to. Otherwise the name is generated in the standard directory: if R1 is 0 or points to an empty string the name of the current program is used, and otherwise R1 points to the name to use in place of the program name | ||||||||||||||||||||||||||||
| R2 | = | Pointer to a block of 16 (17 in 32bit mode) registers to record with the dump | ||||||||||||||||||||||||||||
| R0 - R2 | preserved | |
This SWI will write, or buffer for later writing, a diagnostic dump for the current system state. The dump can be tailored to the task at hand.
The type of 'application space access' in R0 bits 0 and 1 can change the amount of data in the dump file. At level 0, no application space access will be performed at all. At level 1, application space is accessible (for example from referenced call stack elements) but a backtrace will not be generated for it. At level 2, application space is accessible and the module will attempt to unwind the C-call stack from user mode, generating more references. At level 3, all the earlier levels will be performed and the entire application space will be recorded to the file. Note that recording the entire application space will generate a much larger file and it may not be possible to buffer the file in memory.
R0 bit 2 allows the caller to specify an explicit filename. This allows the caller to manage the dump files for their own purposes. If the caller expects to automatically transmit diagnostic data their documentation should state this clearly and include a mechanism to disable this feature.
R0 bit 3 causes the dumped data to be recorded in a dynamic area, rather than recorded to disc immediately. A transient callback will be used to write the data when the system is next unthreaded. This should allow the call to be made when the system would be otherwise unable to write the data to disc immediately.
Other bits are reserved for future expansion.
The register dump, if supplied, will be included within the file.
In order to ensure uniqueness for automatically generated files, even when many files are recorded within the space of a minute, a unique number is appended to the filename (see Dump files).
If the dump cannot be recorded (for example because the file cannot be created), no error is returned. The call returns an error if reserved flags are set, if it is called whilst buffered dumps are being written to disc, or if there is not enough memory to hold the data.
Error Messages
There was not enough memory to hold the data which was to be recorded.
SWI DiagnosticDump_Write was called whilst the module was writing buffered dumps to disc.
SWI DiagnosticDump_Write was called with a flag set which the module does not accept: a reserved bit, or (in versions up to and including 0.17) bit 4.
Security Issues
Users transferring such files should be aware that whilst the information contained within the dumps should only relate directly to the regions which are in question there may be data remaining from other operations which the user may consider to be sensitive. That is, the record may contain information that the user would prefer not to provide to the original developer.
The module will not transfer any information to other systems, or otherwise communicate with any other system, except when directed to do so because the dump file being saved resides on a network device.
Data within the Diagnostic Dump file is not encrypted in any way and may be examined both by the user and by any other parties who obtain it. Where there is concern over the content of the dump file, users should refrain from sending it to any untrusted party.
An example of an operation where there may be concern over the content of the dump might be a failure of a browser application during a session in which a password, user name, or other important information has been supplied (most typically credit card details).