Thu May 12 19:19:00 GMT 2011
On 12/05/2011 2:48 PM, Corinna Vinschen wrote:
> On May 12 13:53, Ryan Johnson wrote:
>> 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?
> Here's what I see for instance in tcsh:
> 00010000-00020000 rw-p 00000000 0000:0000 0 [heap 1 default share]
> 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]
> 002E0000-00310000 rw-p 00000000 0000:0000 0 [heap 0 default grow]
> 00310000-003E0000 ---p 00030000 0000:0000 0 [heap 0 default grow]
>> 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.
> Nope. As I wrote in my previoous mail and as you can still see in my
> quote above, the two virtual memory areas from 0x20000 to 0x30000 and
> from 0x30000 to 0x230000 together constitute a single start block in
> heap 2. The OS is a great faker in terms of information returned to
> the application, apparently.
OK. I finally understand now. I was assuming the heap would not report
multiple allocations as a single heap region.
Windows is weird.
More information about the Cygwin-patches