www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - 0xC0000005: 0x0000000000000000 access violation...

reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
This one look nasty...

I get an access violation crash after some time. The crash is 
reproducible in that it always happens after some time while executing 
the same code sequence (meaning the same function call chain).

The debugger kicks in with a call stack, but it looks strange to me:

 	0000000000000000()	Unbekannt
	reactive-gui.exe!app.mouseMove.__lambda3(app.box * b, bool a) Zeile 
875 reactive-gui.exe!app.mouseMove.dispatchHandler!((a, b) => a.mouseMove_downward(b), (a, b) => a.mouseMove_upward(b)).dispatchHandler(app.winMsg this, app.osStream * s) Zeile 947 reactive-gui.exe!app.mouseMove(app.winMsg s, app.osStream * wm) Zeile 875 That's line 875: a is an object and b a bool. So, I'm giving the memember function to call by the handler dispatchHandler!((a,b) => a.mouseMove_downward(b), (a,b) => a.mouseMove_upward(b))(wm,s); That's the signature of dispatchHandler: void dispatchHandler(alias funcDownward, alias funcUpward)(winMsg wm, osStream s) { And the line the debugger kick in is: node_box is valid if(funcDownward(node_box, false)) updateScreen = true; In the variable inspect window there is nothing unnormal for the variables I use, up to one thing. I see a this 0x0000000000000000 So, why do I see a "this" at all? Is this because the code gets called via a lambda? How can such a situation happen? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Jul 01 2018
parent reply =?iso-8859-1?Q?Robert_M._M=FCnch?= <robert.muench saphirion.com> writes:
On 2018-07-01 09:05:56 +0000, Robert M. Münch said:

 This one look nasty...
And it was... the problem was, that I kept D allocated pointers in C code without informing the GC that the memory can't be collected nor moved. Bridging from D to C and back, is pretty tricky to not miss any allocated memory. Couldn't such a problem be mitigated with an annotation like externalRef or so, which would add the code to protect such memory from being GC? It would make the code much more explicit. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Jul 01 2018
parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Sunday, 1 July 2018 at 22:04:05 UTC, Robert M. Münch wrote:
 On 2018-07-01 09:05:56 +0000, Robert M. Münch said:

 This one look nasty...
And it was... the problem was, that I kept D allocated pointers in C code without informing the GC that the memory can't be collected nor moved. Bridging from D to C and back, is pretty tricky to not miss any allocated memory. Couldn't such a problem be mitigated with an annotation like externalRef or so, which would add the code to protect such memory from being GC? It would make the code much more explicit.
An annotation probably won't do it. This might: struct ExternalRef(T) { T* ptr; alias ptr this; void free() { import core.stdc.stdlib : free; free(ptr); } } auto externalRef(T)() { import core.stdc.stdlib : malloc; return ExternalRef!T(cast(T*)malloc(T.sizeof)); } extern(C) void sendToC(ExternalRef!int p); extern(C) ExternalRef!int getFromC(); unittest { sendToC(externalRef!int()); getFromC().free(); } This is hardly a production-quality piece of code, but should give some ideas for what's possible. -- Simen
Jul 02 2018