Craploads of Bugs
Posted: Sat Nov 02, 2002 8:22 pm
Okay, I've found a million tiny bugs that add up over time to crash bugs and other aberrant behavior.
99.9% of them are calling convention bugs.
For instance, the DInputDataDetour needs to have both the detour function AND the trampoline function pointer prototyped as __stdcall.
From what I can see all of the /commands fn pointers should be protoed as __cdecl.
/click has to be called from within a class method invocation context or you'll get weird, random bugs (I think this is the source of the "1 in a million /click doesn't work" bug).
I believe chat hook should be __stdcall. The project defaults to __cdecl at the moment so that ends up being a problem.
Basically the thing to do when troubleshooting these is to look at the called code and try to deduce if it's __stdcall, __cdecl or a class method invocation (__thiscall, I believe, but you can't prototype as __thiscall).
__stdcall/__cdecl bugs are easy to fix, but __thiscall problems are thornier. I believe that the need for __thiscall is why the command hook is wrapped in a class (to preserve the this pointer). Also note GetMaxMana -- it's mostly just an inline asm function called with ecx (this) preset. That's what you need to do in /click too, but using clsSpawns instead of the char info thingy.
I have these fixed on my MQ (and it's a MILLION times more stable and reliable) but my MQ is so radically different from release MQ now that I don't know if I can merge back. SO just passing along the joy.
One thing to try that catches stack corruption RIGHT away is to compile with the /RTCs flag set. This enables runtime stack checking, and a calling convention mismatch (like all of the bugs I've been finding) will immediately trip a debug break. So compile /RTCs and run it in the debugger -- you should find that virgin 1024 release crashes instantly. That's the DInputDataDetour calling convention mismatch. Then you have to go down the line ironing the rest out...
99.9% of them are calling convention bugs.
For instance, the DInputDataDetour needs to have both the detour function AND the trampoline function pointer prototyped as __stdcall.
From what I can see all of the /commands fn pointers should be protoed as __cdecl.
/click has to be called from within a class method invocation context or you'll get weird, random bugs (I think this is the source of the "1 in a million /click doesn't work" bug).
I believe chat hook should be __stdcall. The project defaults to __cdecl at the moment so that ends up being a problem.
Basically the thing to do when troubleshooting these is to look at the called code and try to deduce if it's __stdcall, __cdecl or a class method invocation (__thiscall, I believe, but you can't prototype as __thiscall).
__stdcall/__cdecl bugs are easy to fix, but __thiscall problems are thornier. I believe that the need for __thiscall is why the command hook is wrapped in a class (to preserve the this pointer). Also note GetMaxMana -- it's mostly just an inline asm function called with ecx (this) preset. That's what you need to do in /click too, but using clsSpawns instead of the char info thingy.
I have these fixed on my MQ (and it's a MILLION times more stable and reliable) but my MQ is so radically different from release MQ now that I don't know if I can merge back. SO just passing along the joy.
One thing to try that catches stack corruption RIGHT away is to compile with the /RTCs flag set. This enables runtime stack checking, and a calling convention mismatch (like all of the bugs I've been finding) will immediately trip a debug break. So compile /RTCs and run it in the debugger -- you should find that virgin 1024 release crashes instantly. That's the DInputDataDetour calling convention mismatch. Then you have to go down the line ironing the rest out...