Visual D 0.50.0-beta1 released

Bert Bert at gmail.com
Fri Aug 2 09:39:15 UTC 2019


On Friday, 2 August 2019 at 05:28:44 UTC, Rainer Schuetze wrote:
>
>
> On 01/08/2019 05:59, Bert wrote:
>> On Sunday, 28 July 2019 at 11:45:21 UTC, Rainer Schuetze wrote:
>>>
>>>
>>> On 28/07/2019 06:59, Bert wrote:
>>>> I can't imagine though why adding a simple field would screw 
>>>> the code up.
>>>>
>>>> e.g.,
>>>>
>>>> class X {} // works.
>>>> class Y { int y; } // fails.
>>>>
>>>
>>> This wouldn't have failed, int needs a class/interface 
>>> member, e.g.
>>>
>>> class X
>>> {
>>>    Q q; // non-null
>>>    I c; // null
>>>    Q s; // non-null
>>> }
>>>
>>>> I would think that such things would have no effect on the 
>>>> pointer value?
>>>>
>>>> Can you explain to me, for my own edification, why removing 
>>>> those non-essential lines would produce the effect?
>>>>
>>>
>>> The bug basically was similar to
>>>
>>> // global cache
>>> string[void*] mapVtblToClassName;
>>>
>>> void showX(X x)
>>> {
>>>    void* vtbl;
>>>    string classNameq;
>>>    bool rc = ReadProcessMemory(x.q, vtbl); // reads vtbl-ptr
>>>    if (rc)
>>>    {
>>>       if (vtbl in mapVtblToClassName)
>>>       {
>>>          classNameq = mapVtblToClassName[vtbl];
>>>          goto Lnext;
>>>       }
>>>       classNameq = getClassNameFromVtbl(vtbl); // Q
>>>    }
>>>    mapVtblToClassName[vtbl] = classNameq;
>>>
>>> Lnext:
>>>    string classNamec;
>>>    rc = ReadProcessMemory(x.c, vtbl); // fails, vtbl unchanged
>>>    if (rc)
>>>    {
>>>       // same as above...
>>>    }
>>>    mapVtblToClassName[vtbl] = classNamec; // overwrites entry 
>>> for Q
>>> }
>>>
>>> Next time a Q is evaluated, the determined class name will be 
>>> empty.
>> 
>> 
>> Thanks. Ok, I see how the caching can be overwritten but I 
>> still don't see how changing a field in the class, which won't 
>> even modify the vtable, will effect the cache. I'd expect some 
>> sort of determinism in this, in that if I compile the some 
>> code and everything works and then simply add a field to a 
>> class and recompile, little should change.
>> 
>> E.g., if the cache is being overwritten in the first case then 
>> adding the field shouldn't change it from being overwritten in 
>> the second case.
>> 
>> Oh, nevermind,
>> 
>> ReadProcessMemory(x.q, vtbl);
>> 
>> you are iterating over the entries in x to get their vtable! 
>> So changing a field could cause a shift in the execution order 
>> and hence initiate the overwrite. (some of the code is missing 
>> above but I see how it could lead to these problems).
>> 
>> While I still don't fully understand why the code is doing 
>> what it does(e.g., q and c? I assume these are suppose to be 
>> members). Seems there doesn't need to be a goto and 2nd branch 
>> in theory but I guess it's incomplete code so I'll assume it 
>> all is suppose to work[Or you are just showing a second 
>> iteration].
>
> Yes, this was pseudo code showing the effect showing two calls 
> to the same function. I used "goto" where a function would use 
> "return".
>
>> 
>> 
>> Essentially just one part of the code is buggy because 
>> classNameq is empty and it can blindly overwrite the vtbl 
>> value *if* any future iterations occur where the if(rc) check 
>> fails(e.g., an added field).
>> 
>>>    void* vtbl;
>>>    string classNameq;
>>>    bool rc = ReadProcessMemory(x.q, vtbl); // reads vtbl-ptr
>>>    if (rc)
>>>    {
>>>       if (vtbl in mapVtblToClassName)
>>>       {
>>>          classNameq = mapVtblToClassName[vtbl];
>>>          goto Lnext;
>>>       }
>>>       classNameq = getClassNameFromVtbl(vtbl); // Q
>>>    }
>>>    mapVtblToClassName[vtbl] = classNameq;
>> 
>> 
>> which then something like
>> 
>> if (classNameq) mapVtblToClassName[vtbl] = classNameq;
>> 
>> would fix the problem?
>> 
>> 
>> 
>
> The empty classname is also cached for invalid vtbl pointers 
> (e.g. when
> reading uninitialized data). The fix is to move the insertion 
> into the
> map into the "if(rc)" branch.


Ok, thanks. At least it makes it clear how these errors can 
happen.




More information about the Digitalmars-d-ide mailing list