digitalmars.D - NullPointerError signals are useful and here is why we should have
I was developing a game within my engine, and I've stumbled in some problems out there with null pointers. Imagine this simple program: ```d class Test { void doIt(){} } void main() { Test t; t.doIt(); } ``` It compiles and then it kills with signal 11 when using DMD on linux. If we were using Java, this program would not even build, because it would fail stating that it was never initialized. But I don't really care about analyzers, I would rather have a runtime error or exception showing where and when it had this invalid value. So, the main thing about this, is that I don't know how many people developed using DLLs in D, but its experience is far from ideal, put together to classes and hot reloading and things can go worse than expected. Whenever my program crashes without messages, I simply go to Visual Studio and open my exe and try to run it again. This time I've done the same thing, and it wasn't able to find anything on the program, instead, it got a completely random and misleading error message. ![The procedure entry point _d-arraycatT could not be located in the dynamic link library G:\HipremeEngine\projects\letter_rain\letter_rain_hiptemp.dll](https://i.ibb.co/Mf09jSK/err.png) Try to understand what is the problem in that code? Yes, exactly, it is a null pointer. And yes, in this case it is fairly simple, but I was in the middle of a refactor, and instead of using arrays, I went into using pools: So, reduced, check this code: ```d class MainScene : AScene, IHipPreloadable { mixin Preload; Strip[] stripList; /** Constructor */ override void initialize() { foreach(i; 0..30) { import hip.math.random; Strip s = new Strip(); stripList~= s; s.pos.x = Random.range(0, 800); } } } ``` After some refactor, I got this code: ```d class MainScene : AScene, IHipPreloadable { mixin Preload; Pool!Strip stripList; /** Constructor */ override void initialize() { foreach(i; 0..30) { import hip.math.random; stripList.get().pos.x = Random.range(0, 800); } } } ``` Now, the problem looks obvious! I need to initialize the pool instance with `new Pool!Strip()`. But while I was doing, it wasn't this obvious, and getting this error message (built with LDC), didn't help me solving my problem at all. Beyond this simple problem, there is hot reloading there. That means, whenever you save your code, the file is rebuilt and reloaded automatically, and the problem is that at least for me, I tend to keep saving and resaving many times, that means I create incomplete code there, and then it just crashes my main program because my code wasn't even complete. And currently, there's no obvious way how I could control for it to say "It's okay, simply unload the DLL". Working with DLLs have been a pain for me since the beginning from how hard it was to find the correct flags, from how different it behaves per compiler, and from how incomplete the support is. I believe that requiring someone to fix DLL right now would simply have priority 0, so, here I stand making a request proposal that would benefit the entire language much beyond the current hot new subject.
Oct 23 2023
I use DLL and i do hotreload in my engine I have a single file module that solve this: https://github.com/ryuukk/backtraced/ Works in both linux/windows I setup my signal handler this way, very simple: ```D version(DLL) export extern(C) void on_reload(State* state) { LINFO("reloaded"); debug rt_register_crash_handler(); } ``` And this example code in the DLL: ```D int* test = null; *test = 5; ``` Will give me this: ``` -------------------------------------------------------------------+ Received signal 'exception' (3221225477ll) -------------------------------------------------------------------+ C:\dev\kdom\projects\game\app.d:144 - game.app.on_tick C:\dev\kdom\projects\game\app.d:144 - game.app.on_tick C:\dev\kdom\projects\game\app.d:144 - rt_register_crash_handler C:\dev\kdom\projects\game\app.d:144 - BaseThreadInitThunk C:\dev\kdom\projects\game\app.d:144 - RtlUserThreadStart make: *** [makefile:36: game-run] Error 2816 ``` I now know where exactly the code failed and i can fix it ```D version(DLL) export extern(C) void on_tick(State* state) { if (state.engine.input.is_key_just_pressed(Key.KEY_SPACE)) { int* test = null; *test = 5; } } ``` I think someone made a PR to have something similar already, but i forgot where (phobos or druntime)
Oct 23 2023
On Monday, 23 October 2023 at 20:53:04 UTC, ryuukk_ wrote:I use DLL and i do hotreload in my engine I have a single file module that solve this: https://github.com/ryuukk/backtraced/ [...]Thanks a lot! I'll try to work with that and see how far I can reach with it :D
Oct 23 2023