digitalmars.D.learn - Null pointer in __vptr
- frame (4/4) Nov 19 2021 Got a suspicious interface instance in the debugger and question
- Adam D Ruppe (4/6) Nov 19 2021 The `destroy` function (as well as other class destruction) will
- frame (11/14) Nov 19 2021 So, a partial nulled table shouldn't exist, right? like this:
- Adam D Ruppe (9/10) Nov 19 2021 Indeed.
- frame (3/7) Nov 19 2021 You got it! It was an abstract class involved and the method
- =?UTF-8?Q?Ali_=c3=87ehreli?= (7/21) Nov 19 2021 I am not sure that's correct. The way I picture it, the code reaches the...
- frame (7/14) Nov 20 2021 I think this is true for an object instance. But from an
- =?UTF-8?Q?Ali_=c3=87ehreli?= (36/42) Nov 20 2021 Everything needed is available from the pointer to a class object (or
- frame (3/7) Nov 21 2021 Ok, so they mean by instance is only one instance by type but not
Got a suspicious interface instance in the debugger and question myself: Is a null pointer entry in the __vptr[] valid or always a sign for corruption/wrong cast somewhere? thx
Nov 19 2021
On Friday, 19 November 2021 at 15:37:59 UTC, frame wrote:Is a null pointer entry in the __vptr[] valid or always a sign for corruption/wrong cast somewhere? thxThe `destroy` function (as well as other class destruction) will null out the whole vtable to help make use-after-free an obvious error. Possible that happened to you.
Nov 19 2021
On Friday, 19 November 2021 at 15:46:41 UTC, Adam D Ruppe wrote:The `destroy` function (as well as other class destruction) will null out the whole vtable to help make use-after-free an obvious error. Possible that happened to you.So, a partial nulled table shouldn't exist, right? like this: __vptr[0]: address __vptr[1]: 0000000 __vptr[2]: address __vptr[3]: address __vptr[4]: address __vptr[5]: address ... Because 0 should point to the object instance and next offsets are pointers to the member functions, correct?
Nov 19 2021
On Friday, 19 November 2021 at 18:04:17 UTC, frame wrote:So, a partial nulled table shouldn't exist, right? like this:Indeed. I've gotten that before as a result of a compiler bug... I had an abstract method that wasn't implemented but the compile time error got swallowed by a bug and thus the null method made its way to the binary. I think that bug was fixed.... but still you might want to check your code for the `abstract` keyword and ensure they are legit implemented in your cases.
Nov 19 2021
On Friday, 19 November 2021 at 18:14:03 UTC, Adam D Ruppe wrote:I've gotten that before as a result of a compiler bug... I had an abstract method that wasn't implemented but the compile time error got swallowed by a bug and thus the null method made its way to the binary.You got it! It was an abstract class involved and the method signature was just wrong, but no compile error. Thanks!
Nov 19 2021
On Friday, 19 November 2021 at 20:27:11 UTC, frame wrote:On Friday, 19 November 2021 at 18:14:03 UTC, Adam D Ruppe wrote:Seems like it was only partially fixed then, specifically for missing abstract methods, but not whether the signature was correct or not. Seems like a critical bug to me.I've gotten that before as a result of a compiler bug... I had an abstract method that wasn't implemented but the compile time error got swallowed by a bug and thus the null method made its way to the binary.You got it! It was an abstract class involved and the method signature was just wrong, but no compile error. Thanks!
Nov 22 2021
On Monday, 22 November 2021 at 13:21:22 UTC, bauss wrote:Seems like it was only partially fixed then, specifically for missing abstract methods, but not whether the signature was correct or not. Seems like a critical bug to me.At least it's still present in dmd 2.098.
Nov 22 2021
On 11/19/21 10:04 AM, frame wrote:On Friday, 19 November 2021 at 15:46:41 UTC, Adam D Ruppe wrote:I am not sure that's correct. The way I picture it, the code reaches the __vptr by following a pointer; so it's already known. Additionally, I am under the impression that there is only one __vptr for a given type, which all class objects of that type point to.The `destroy` function (as well as other class destruction) will null out the whole vtable to help make use-after-free an obvious error. Possible that happened to you.So, a partial nulled table shouldn't exist, right? like this: __vptr[0]: address __vptr[1]: 0000000 __vptr[2]: address __vptr[3]: address __vptr[4]: address __vptr[5]: address .... Because 0 should point to the object instanceand next offsets are pointers to the member functions, correct?My understanding is that all entries are that. Ali
Nov 19 2021
On Friday, 19 November 2021 at 21:09:16 UTC, Ali Çehreli wrote:I am not sure that's correct. The way I picture it, the code reaches the __vptr by following a pointer; so it's already known. Additionally, I am under the impression that there is only one __vptr for a given type, which all class objects of that type point to.I think this is true for an object instance. But from an interface instance, the object instance must be accessible somewhere? This is also how I would read the doc:The vtbl[0] entry is a pointer to the corresponding instance of the object.Interface class.On the other hand, I don't know what the debugger is really showing here - it's printed as void* array and I wonder where it gets the length of the array.
Nov 20 2021
On 11/20/21 7:19 AM, frame wrote:I think this is true for an object instance. But from an interface instance, the object instance must be accessible somewhere?Everything needed is available from the pointer to a class object (or interface). There are some offset arithmetic involved to get to the right vtbl pointer but the pointer of an object cannot be stored anywhere in the vtbl because there is just one vtbl but very many objects.This is also how I would read the doc:That is from https://dlang.org/spec/abi.html What they mean with object.Instance is the following definition I find e.g. in my /usr/include/dmd/druntime/import/object.d file: /** * Information about an interface. * When an object is accessed via an interface, an Interface* appears as the * first entry in its vtbl. */ struct Interface { TypeInfo_Class classinfo; /// .classinfo for this interface (not for containing class) void*[] vtbl; size_t offset; /// offset to Interface 'this' from Object 'this' } So, the first entry is a pointer to that struct. The ABI document mentions "pointer to instance of TypeInfo" as well, which is defined in the same object.d as well: /** * Runtime type information about a type. * Can be retrieved for any type using a * $(GLINK2 expression,TypeidExpression, TypeidExpression). */ class TypeInfo { // ... } AliThe vtbl[0] entry is a pointer to the corresponding instance of the object.Interface class.
Nov 20 2021
On Sunday, 21 November 2021 at 02:43:12 UTC, Ali Çehreli wrote:There are some offset arithmetic involved to get to the right vtbl pointer but the pointer of an object cannot be stored anywhere in the vtbl because there is just one vtbl but very many objects.Ok, so they mean by instance is only one instance by type but not data instance, got it.
Nov 21 2021