Thu May 12 17:54:00 GMT 2011
On 12/05/2011 1:11 PM, Corinna Vinschen wrote:
> On May 12 18:55, Corinna Vinschen wrote:
>> On May 12 12:31, Ryan Johnson wrote:
>>> On 12/05/2011 11:09 AM, Corinna Vinschen wrote:
>>>> - void *base;
>>>> + unsigned heap_id;
>>>> + uintptr_t base;
>>>> + uintptr_t end;
>>>> + unsigned long flags;
>>> We don't actually need the end pointer: we're trying to match an
>> No, we need it. The heaps consist of reserved and committed memory
>> blocks, as well as of shareable and non-shareable blocks. Thus you
>> get multiple VirtualQuery calls per heap, thus you have to check for
>> the address within the entire heap(*).
> Btw., here's a good example. There are three default heaps, One of them,
> heap 0, is the heap you get with GetProcessHeap (). I don't know the
> task of heap 1 yet, but heap 2 is ... something, as well as the stack of
> the first thread in the process. It looks like this:
> base 0x00020000, flags 0x00008000, granularity 8, unknown 0
> allocated 1448, committed 65536, block count 3
> Block 0: addr 0x00020000, size 2150400, flags 0x00000002, unknown 0x00010000
> However, the various calls to VirtualQuery result in this output with
> my patch:
> 00020000-00030000 rw-p 00000000 0000:0000 0 [heap 2 default share]
> 00030000-00212000 ---p 00000000 0000:0000 0 [heap 2 default]
> 00212000-00213000 rw-s 001E2000 0000:0000 0 [heap 2 default]
> 00213000-00230000 rw-p 001E3000 0000:0000 0 [heap 2 default]
> The "something" is the sharable area from 0x20000 up to 0x30000. The
> stack is from 0x30000 up to 0x230000. The first reagion is only
> reserved, then the guard page, then the committed and used tack area.
Hmm. It looks like heap 2 was allocated by mapping the pagefile rather
than using VirtualAlloc, and the thread's stack was allocated from heap
2, which treated the request as a large block and returned the result of
a call to VirtualAlloc.
Are the other two heap bases not "default share" then?
In any case, coming back to the allocation base issue, heap_info only
needs to track 0x20000 and 0x30000, because they are the ones with
offset zero that would trigger a call to heap_info::fill_on_match. I
argue that heap walking found exactly two flags&2 blocks, with exactly
those base addresses, making the range check in fill_on_match unecessary.
Again, I'll try running your patch instead of my own when I get a
chance, and see if yours finds regions mine fails to label. However, if
0x30000 above really is a large block region, then at least my worries
about flags&2 were unfounded, which is great news.
More information about the Cygwin-patches