[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
E.5 Tracing on Symmetrix
This section documents the API used by the GDB agent to collect data on Symmetrix systems.
Cygnus originally implemented these tracing features to help EMC Corporation debug their Symmetrix high-availability disk drives. The Symmetrix application code already includes substantial tracing facilities; the GDB agent for the Symmetrix system uses those facilities for its own data collection, via the API described here.
- Function: DTC_RESPONSE adbg_find_memory_in_frame (FRAME_DEF *frame, char *address, char **buffer, unsigned int *size)
Search the trace frame frame for memory saved from address. If the memory is available, provide the address of the buffer holding it; otherwise, provide the address of the next saved area.
-
If the memory at address was saved in frame, set
*buffer
to point to the buffer in which that memory was saved, set*size
to the number of bytes from address that are saved at*buffer
, and returnOK_TARGET_RESPONSE
. (Clearly, in this case, the function will always set*size
to a value greater than zero.) -
If frame does not record any memory at address, set
*size
to the distance from address to the start of the saved region with the lowest address higher than address. If there is no memory saved from any higher address, set*size
to zero. ReturnNOT_FOUND_TARGET_RESPONSE
.
These two possibilities allow the caller to either retrieve the data, or walk the address space to the next saved area.
-
If the memory at address was saved in frame, set
This function allows the GDB agent to map the regions of memory saved in a particular frame, and retrieve their contents efficiently.
This function also provides a clean interface between the GDB agent and the Symmetrix tracing structures, making it easier to adapt the GDB agent to future versions of the Symmetrix system, and vice versa. This function searches all data saved in frame, whether the data is there at the request of a bytecode expression, or because it falls in one of the format's memory ranges, or because it was saved from the top of the stack. EMC can arbitrarily change and enhance the tracing mechanism, but as long as this function works properly, all collected memory is visible to GDB.
The function itself is straightforward to implement. A single pass over the trace frame's stack area, memory ranges, and expression blocks can yield the address of the buffer (if the requested address was saved), and also note the address of the next higher range of memory, to be returned when the search fails.
As an example, suppose the trace frame f
has saved sixteen bytes
from address 0x8000
in a buffer at 0x1000
, and thirty-two
bytes from address 0xc000
in a buffer at 0x1010
. Here are
some sample calls, and the effect each would have:
-
adbg_find_memory_in_frame (f, (char*) 0x8000, &buffer, &size)
This would set
buffer
to0x1000
, setsize
to sixteen, and returnOK_TARGET_RESPONSE
, sincef
saves sixteen bytes from0x8000
at0x1000
.-
adbg_find_memory_in_frame (f, (char *) 0x8004, &buffer, &size)
This would set
buffer
to0x1004
, setsize
to twelve, and returnOK_TARGET_RESPONSE
, since ‘f’ saves the twelve bytes from0x8004
starting four bytes into the buffer at0x1000
. This shows that request addresses may fall in the middle of saved areas; the function should return the address and size of the remainder of the buffer.-
adbg_find_memory_in_frame (f, (char *) 0x8100, &buffer, &size)
This would set
size
to0x3f00
and returnNOT_FOUND_TARGET_RESPONSE
, since there is no memory saved inf
from the address0x8100
, and the next memory available is at0x8100 + 0x3f00
, or0xc000
. This shows that request addresses may fall outside of all saved memory ranges; the function should indicate the next saved area, if any.-
adbg_find_memory_in_frame (f, (char *) 0x7000, &buffer, &size)
This would set
size
to0x1000
and returnNOT_FOUND_TARGET_RESPONSE
, since the next saved memory is at0x7000 + 0x1000
, or0x8000
.-
adbg_find_memory_in_frame (f, (char *) 0xf000, &buffer, &size)
This would set
size
to zero, and returnNOT_FOUND_TARGET_RESPONSE
. This shows how the function tells the caller that no further memory ranges have been saved.
As another example, here is a function which will print out the
addresses of all memory saved in the trace frame frame
on the
Symmetrix INLINES console:
void print_frame_addresses (FRAME_DEF *frame) { char *addr; char *buffer; unsigned long size; addr = 0; for (;;) { /* Either find out how much memory we have here, or discover where the next saved region is. */ if (adbg_find_memory_in_frame (frame, addr, &buffer, &size) == OK_TARGET_RESPONSE) printp ("saved %x to %x\n", addr, addr + size); if (size == 0) break; addr += size; } } |
Note that there is not necessarily any connection between the order in
which the data is saved in the trace frame, and the order in which
adbg_find_memory_in_frame
will return those memory ranges. The
code above will always print the saved memory regions in order of
increasing address, while the underlying frame structure might store the
data in a random order.
[[This section should cover the rest of the Symmetrix functions the stub relies upon, too.]]
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |