BARR/RJE manual

Barr Memory Dump Overview

This topic describes memory dumps.


What Produces a Memory Dump?

A memory dump can occur in any of the following ways.

Layout of the Dump File

Every dump file has the same general layout; however, depending on the product and what options are included, there may be some differences.

The following information is generally included in a dump file.

Screens show up in the dump only if they have been selected while running the program.

Screens

The screens section of the dump file is sometimes overlooked, but it often contains clues for solving a problem.

When looking at the OPER screen, note the following items:

The SPOOL screen is also useful for getting details about the current printing status of jobs in spool. When looking at the SPOOL screen, note the following items:

Remember, screens will show up in the dump only if they have been selected while running the program.

Buffers and Associated Segments

Buffers and Queues

Buffers are used extensively throughout the Barr product. The first 16 bytes of a buffer are the buffer header. Data begins at offset 10H. The absolute maximum data offset within a buffer is given by the variable buffer_size_free. The value of buffer_size_free is calculated during program initialization. The variable b_after (second word of the buffer header) contains the offset within the buffer of the first byte after the user data. Notice that, in the dump file, the data shown for each buffer terminates in the line at offset b_after.

Another important field is b_que. This field is a double word in "segment:offset" notation and is located at offset 0CH in the buffer header, q_seg:q_offset. Every buffer resides on a queue. If the buffer is not allocated, then it lives on either free_que or xms_free_que.

A queue is a three-word data structure defined as follows:

Example 1 shows a sample buffer taken from a dump. This example is using Buffer 1F9B. The only significance of 1F9B is that, at the time this dump was taken, this buffer was located at memory location 1F9Bh.

Examining Buffers Belonging to Devices

The sample buffer given in Example 1 belongs to a device on the Assign Devices screen. Following is a list of the steps needed to find the associated device:

  1. To determine if the buffer belongs to a device, examine the buffer header's que_seg, located at offset 0Ch. If it is equal to 1A00h, then the buffer belongs to a device.

  2. The segment for the buffer resides at the memory location pointed to when a byte swap is done on the variable que_offset. This example has que_offset = 9942, which points to memory location 4299 when the value is byte swapped.

  3. To find the device, search for 4299 in the dump. When memory location 4299 is found, it is obvious the device in question is the LOG device.

  4. Each device in assigned devices is assigned to a destination. Determining the destination is done by byte swapping the r_assign variable located at offset 18h in the segment belonging to the LOG device. This example has an r_assign value of 9244, which points to memory location 4492 when the value is byte swapped.

  5. To find the assigned destination, search for memory location 4492 in the dump. In this example, the device LOG is assigned to SUSPEND.

  6. Notice that the value of r_assign for the destination SUSPEND (also located at offset 18h) points back to the destination's (LOG) location in memory, 4492.

Example 1

Search dump on byte swapped QUE_SEG to find the associated DEVICE

Search on byte swapped R_ASSIGN (4492) to locate DESTINATION of SOURCE

Buffer Activity Log

The buffer activity log is one of the most useful items contained in a dump file for development, because for all calls to get_buffer, free_buffer, and buffer_move, it lists the buffer, the source and destination queues, the action (get, free, or move) and the address of the caller. Note that each call to get_buffer and free_buffer contains an internal call to buffer_move with the source or destination queue being one of the free queues, respectively. Consequently, every G or F entry in the buffer activity log will be followed by its associated M entry.

Buffer

This is the buffer being gotten, freed, or moved.

Sque

This is the source queue. For get_buffer, this will be the free queue.

Dque

This is the destination queue. For free_buffer, this will be the free queue.

Action

(F)ree buffer, (G)et buffer, or (M)ove buffer.

By

This is the CS:IP of the call to get_buffer, free_buffer, or buffer_move.

The dump shows the activity of the last 10 buffers handled. Following is a sample activity log from a dump.

Buffer Activity

 

Buffer

SQue

DQue

Action

By

 

5B41

349D:62E4

43F5:0417

M

263A:04A3

 

5324

349D:2BD6

349D:62E4

G

263A:044B

 

5324

349D:2BD6

349D:62E4

M

1597:0530

 

5324

349D:62E4

43F5:0417

M

263A:04A3

 

7EA8

349D:2BD6

349D:62E4

G

263A:044B

 

7EA8

349D:2BD6

349D:62E4

M

1597:0530

 

7EA8

349D:62E4

43F5:0417

M

263A:04A3

 

82E1

349D:2BD6

349D:62E4

G

263A:044B

 

82E1

349D:2BD6

349D:62E4

M

1597:0530

 

82E1

349D:62E4

43F5:0417

M

263A:04A3

Mapped Segments

The program maintains a list of mapped segments. Each map name is eight characters long (padded with spaces if necessary). There is a rather loose naming convention, which goes something like this:

'NAME

'

– represents a code segment, task_seg, or other data type not mentioned below.

'NAME@

'

– represents an area for local storage by module NAME. This resides is the global stack.

'NAME#

'

– represents data within a code segment.

'NAME!

'

– represents initialization data.

Some map names contain spaces before the @, #, or ! character.

Examining the Mapped Segment PRODUCT

The product segment can be used to determine the product code of the software that supplied the dump. To find the product segment, search for "--PRODUCT" in the dump. The word "product" can appear several times within a dump. Searching for "--PRODUCT" will yield something similar to what is shown in Example 2.

Example 2

Examining the Mapped Segment XBUFFER@

The XBUFFER@ segment will show how many real and XMS buffers were free at the time of the dump. The information on the real buffers starts at offset 0006h and the XMS data starts at offset 000Ch. To find this segment in the dump, search for "XBUFFER@." Example 3 gives a typical XBUFFER@ segment.

Example 3