Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [dsdp-dd-dev] Memory service questions



On Mon, Oct 20, 2008 at 6:54 AM, Jesper Eskilson <jesper.eskilson@xxxxxx> wrote:
Francois Chouinard wrote:

Exact. Each time a memory monitor is created (by the user), the debug platform instantiates a corresponding IMemoryBlockExtension via a call to IMemoryBlockRetrieval.getExtendedMemoryBlock(). For DSF, these interfaces are implemented by DsfMemoryBlockRetrieval and DsfMemoryBlock respectively.

Following that, each time an update is requested, the UI makes a call to IMemoryBlockExtension.getBytesFromAddress(). In our case, depending on the requested block "location" (address and size) with respect to the cached block, and on the update policy (through IMemoryBlockUpdatePolicyProvider), we determine if the cached block (or parts of it) can be re-used and if a trip to the memory service is needed (IMemory.getMemory()).

If so (getMemory() was called), the retrieved block is compared with the cached block to flag the changed MemoryBytes so the UI can highlight them in the corresponding monitor.

The memory service itself should issue its requests through a CommandCache which handles the duplicates quite nicely and limits the number of trips to the back-end.

Even if I ignore multiple identical requests, I still get OutOfMemory issues when I scroll alot, so even with a CommandCache I would have problems.


I didn't experience this problem when the service was designed but things might have changed since. I will try to reproduce it and come back to you. Other than opening a memory monitor and scroll it, is there anything special about your use case?



   The issue here is that I get alot of *identical* getMemory()
   requests (same address, same range, same wordsize, etc.). If I start
   scrolling, the service is sometimes flooded with calls until I get a
   OutOfMemory error.


Each of these getMemory() requests is ultimately triggered by the UI and should be factorized by the CommandCache. The UI will request a memory read upon receiving a DebugEvent (DebugEvent.CHANGE, DebugEvent.CONTENT). By any chance, does your service issue such events liberally? That could explain the flood of identical requests.

My memory service doesn't issue any debug-events at all at this time.

See above.

 


The HISTORY_KNOWN flag simply means that the CHANGED flag is meaningful (my english is lousy, I know...). In getBytesFromAddress(), DsfMemoryBlock compares the cached block with the newly retrieved one and flags the changed bytes. It also sets the HISTORY_KNOWN flag so the UI will correctly hightlight the changes (and put the little delta decorator too).

Does that mean that the memory service itself does not (and should not) set the HISTORY_KNOWN and CHANGED flags?

Today, DsfMemoryBlock will set these flags for the bytes that were modified with respect to the cached block (actually, only the intersection of the cached and the new block is considered to highlight what was modified since the last time the data was presented to the user).

DsfMemoryBlock will not clear any flag set by the memory service. The memory service of the reference implementation (MIMemory) does not set any flag (although it should at leats consider the endianness flag).

 


As Pawel mentionned, we elected to use a MemoryByte[] to represent our memory blocks. And each MemoryByte comes with its personalized set of flags :-) At first glance this might look inefficient, but this is what the UI expects (see IMemoryBlockExtension).

Not much to do then. Ideally I would like to be able to pass a primitive array (byte[]/short[]/int[],long[]), but I don't think this will really be an issue.


For the "word size", my understanding is that it corresponds to the size of the smallest addressable item, usually the byte (but, like a few other parameters, this should really be a launch configuration parameter).

That's not how I interpret it. If you have memory where the program has written 32-bit integers, and you tell the view to display 4-byte units, I expect the integers to come out correct. I.e. if I have this program

  uint32_t x = 0x11223344;

and display the location &x to be viewed as 4-byte units, I want the memory view to display

 11223344

and not

 44332211

Endianness is not (IMHO, I should add) a property of a single byte or a byte stream, it is a way to interpret a fixed sequence of bytes read from memory. How should 4 sequential bytes read from memory be converted into a 32-bit int?

Anyway, I'll have more reason to revisit the endianness issue further down the line. It is not a critical issue at the moment.

Technically, "word size" has at least 4 meanings (integer size, register size, memory address, processor-memory data path width, ...) and probably more. I agree that I took a simplistic approach by choosing it to be the size of the smallest addressable item.

However, in practice, our aim is to feed a memory monitor with an array of MemoryBytes i.e. not integers, nor IEEE-754 floating points, nor booleans. The basic memory monitor renderer displays the data in its rawest form as a series of 4-bytes chunks. I think the 4-bytes chunk has to do with convenience, not word-size (maybe I'm wrong here).

As for the display of &x, it can be argued that some users would want to see the data in its raw form i.e. as it is actually layed out in memory, as an array of bytes ordered by their actual address. The debug platform offers an integer renderer that will interpret correctly the array of bytes and display the corresponding integer (not in hex though). It also provides a Variable view that uses the debugger's formatting capabilities to display "x" in a variety of alternate forms.

Anyway, if you feel strongly about this, you should open a bug and we could discuss it more formally.

 


Anyway, to keep things simple, I found it is easier to provide an array of bytes then let the Memory View handle the formatting (ASCII, Integer, char, ...). I suggest that you adopt a similar approach and that you provide a specific memory renderer for your more exotic rendering needs. Of course, I might very well have overseen some critical aspect and, if you have one, I would very much like to have an example where this doesn't work.

My understanding of the endianness flag (another launch configuration parameter candidate) is really for the renderer to know how to handle the raw byte array.

I'll dig a little deeper into the flooding getMemory() calls and see what I can find.


--
/Jesper

_______________________________________________
dsdp-dd-dev mailing list
dsdp-dd-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/dsdp-dd-dev


Back to the top