Page 1 of 1

ahkThread_Free, ahkTerminate, or both? Confusing.

Posted: 04 Mar 2018, 11:42
by Drugwash
Since a rather complex script, when compiled, is still randomly crashing either on start or on restart, either on one machine or another, either in a folder or another, I'd like some clarifications on exiting the threads started by main script before restarting/reloading it.
Said script crashes regardless of whether is compiled with the bin or the exe, and the error is always the same:
"The instruction at <address> referenced memory at 0x00000014; memory could not be read". Instruction address changes from one compile to another but memory address being referenced remains the same.
20180303100724.png (10.59 KiB) Viewed 2693 times
As the title says, being unfamiliar with AHK_H I don't know exactly what each of the two functions does and which is best to use to exit a thread in a clean manner.

Additionally, I'd like to know whether threads do execute any OnExit command when closed and which of the two functions allows the OnExit label/function to be executed completely before exiting the thread.

Oh and almost forgot: can those functions be called dynamically (for compatibility with AHK_L)? In example:

Code: Select all

endfunc := "ahkThread_Free"
termfunc := "ahkTerminate"
If isAhkH
; or
I'm trying to eliminate any possible bugs and coding errors from the script before blaming it on AHK_H itself, therefore any help would be appreciated. Thank you.

Re: ahkThread_Free, ahkTerminate, or both? Confusing.

Posted: 04 Mar 2018, 17:39
by HotKeyIt
ahkthread_free triggers ahkthread_release for all threads loaded with ahkThread, ahkthread_release then calls ahkTerminate for each thread and frees memory. It is not necessary to call any of the functions on close or reload, they will be called automatically.
OnExit in dll script will be called.
You can call the functions dynamically if AhkThread is included! #include <AhkThread>

Can you reproduce the crash with a simple script?

Re: ahkThread_Free, ahkTerminate, or both? Confusing.

Posted: 04 Mar 2018, 18:04
by Drugwash
What happens if a thread is lazy? Is it possible that the compiled script will reload before one thread has completely shut down? There is a thread that uses gdiplus and I know that library is quite lazy at startup/shutdown. For now I put its shutdown and FreeLibrary() in an OnExit function.

That #include doesn't work, error "file not found". I know it's in compiler Lib folder but script won't search there for some reason.

Haven't tried any simple scripts so far. I'll try that tomorrow and report the findings. But what if a simple script doesn't crash because it's too… simple?
Will see tomorrow. Thanks for the details.

Re: ahkThread_Free, ahkTerminate, or both? Confusing.

Posted: 04 Mar 2018, 18:11
by HotKeyIt
It will wait until thread exits, even if it is lazy.

Do you get #include error when compiling?

Re: ahkThread_Free, ahkTerminate, or both? Confusing.

Posted: 05 Mar 2018, 09:33
by Drugwash
It's a mystery. If all threads close gracefully and everything goes back to how it was before running the compiled script, reloading it should - theoretically - work just fine, as it worked before the reload. But it doesn't. In fact, I had a couple reloads without crash and then it started crashing. It's all apparently random, except for the addresses (instruction and memory) which are always the same for a given compiled script (or maybe for all builds of the script on a given machine).

I've had the very same compiled exe crash consistently on reload in the work folder, while a copy of it, with the same additional files (.ini), placed in C:\Windows\Temp reloaded many times without crash. Then I had the reverse, when another build of the script, after some small changes, would run fine on reload in the work folder and would crash on reload in Temp.

And then, the same script that worked fine in the work folder would crash on a 32bit Win7 machine.
Then, the very same script compiled on the Win7 machine with the very same AHK_H build, when it reloaded correctly on Win7 would crash on reload in XP.

As you probably noticed, fellow robodesign is having the same problem on an x64 Win10 machine with this script, where the 32bit build also crashes on reload. His build would crash on reload on my XP machine but would crash on start on the Win7 machine. He's been building with AutoHotkey.exe only, I tried both with the exe and the bin, and results were the same: random crashes on reload.

The script in question has a huge amount of keyboard and mouse hotkeys, timers, message hooks, four additional script threads, a serious amount of variables declared at start and then updated through ini file reads (and then IniWrites on exit, but not on straight reload), additional scripts and sound files included through compiler directives, a handful of files included through FileInstall, so it's quite hard to try and pinpoint any possible bug in it. But all this apart, running it uncompiled never crashes - not on start, not on reload.

Actually I just realized the problem was put in the wrong way: it doesn't crash during the reload operation, but during the start, in the autoexec section (where threads are created), after reload.
And after today's tests, other weird thing happened: while using a couple OutputDebug commands and file creation (the thread scripts retrieved from resources), the compiled script never crashed upon a few reloads. After turning off the debug features, it started crashing again!

After more small changes I thought I nailed it: no crash either in work folder or Temp folder, for more than ten subsequent reloads in each folder. But then it started crashing again, even on start. Very same build at the very same instruction address and memory address as in the screenshot at the top. And now, after a couple minutes of not running it, it worked fine on three subsequent reloads.

I just can't make heads or tails of this situation, and the fact that the process can't be run through a debugger is a show stopper. That's why I asked you in a previous related topic for a compiler option to skip on demand anti-debugging features for the currently selected script, in order to try and solve this mystery.

There may also be a bad GDI leak related to relaunching (and crashing) of the compiled script too many times. Seconds ago I tried to get a file context menu and all I got was its shadow, then text only on hovering its apparent place. Something like that, in XP, should be very bad. :shock: Fortunately I'm using Total Commander as file explorer so I could close and restart it; if it were Explorer the whole machine could've been brought to its knees.

Trying to #include <AhkThread> results in:
20180305162504.png (14.04 KiB) Viewed 2648 times
It only worked when AhkThread.ahk was placed in script's folder (or in its Lib subfolder, dunno exactly, put it in both places to be sure).
However, even without the #include, the main script still creates threads by calling ahkThread dynamically.

Re: ahkThread_Free, ahkTerminate, or both? Confusing.

Posted: 05 Mar 2018, 10:22
by guest3456
Drugwash wrote: Trying to #include <AhkThread> results in:
It only worked when AhkThread.ahk was placed in script's folder (or in its Lib subfolder, dunno exactly, put it in both places to be sure).
However, even without the #include, the main script still creates threads by calling ahkThread dynamically.

the <syntax> requires the file to be in a lib folder. otherwise use the .ahk syntax if its in the script's folder.

Re: ahkThread_Free, ahkTerminate, or both? Confusing.

Posted: 05 Mar 2018, 11:02
by Drugwash
Originally, that file resides in Compiler\Lib. Logically it should be picked up by the compiler at compile time. Maybe it is.
If you look a few replies above you see the syntax was suggested by HotkeyIt himself so I tried to follow it ad litteram.
It's a moot point though, since it still works without it. But thank you for pointing me to the documentation, I should keep that in mind (if it weren't so broken - my mind, that is).

Otherwise, any idea why a script could have such a weird behavior?

Re: ahkThread_Free, ahkTerminate, or both? Confusing.

Posted: 08 Mar 2018, 18:06
by HotKeyIt
AhkThread is saved in RESOURCES\LIB which should be picked up by #include <AhkThread> and it works fine for me:

Code: Select all

#Include <AhkThread>
%a%("MsgBox thread")
MsgBox main
I have found a bug for compiled script and fixed it, can you try latest release and let me know if it is working now.

Re: ahkThread_Free, ahkTerminate, or both? Confusing.

Posted: 09 Mar 2018, 04:57
by Drugwash
Installed the new version.
The include works fine in the uncompiled script, but the compiler just can't find the file, the error is still the same as above.
I even tried to place a copy of AhkThread.ahk in Compiler\Lib with changed extension (AhkThread.ah1u, since AHK_H scripts are registered in the system with that extension), to no avail.
I placed a copy of the test script with regular extension (.ahk instead of .ah1u) in the working folder, still no go.
I placed a copy of the test script in C:\Windows\Temp. No dice.

Looking through Ahk2Exe.ahk I noticed a few stray variables who once had GUI toggles (UseInclude, UseIncludeResource) and are still passed to AhkCompile() although they are not defined anywhere anymore. However, setting them to True doesn't change anything.
In registry there are also a few values not used anymore by current compiler but were once used by old compiler versions; could that affect the behavior?
HKEY_CURRENT_USER\Software\AutoHotkey\Ahk2Exe_H :
LastUseInclude, LastUseIncludeAutoHotkeyDll, LastUseIncludeAutoHotkeyMini, LastUseIncludeLib, LastUseIncludeResource
Old compilers made a mess in original AHK's values, it was impossible to use different AHK versions side by side.
I now deleted the orphaned values. No change whatsoever.

Regardless of what I tried, the compiler will throw the same error: can't find <AhkThread> in test script's folder.
Maybe it's a path problem. The compiler just doesn't look in Compiler\Lib. A hardcoded path somewhere in AutoHotkey.exe, maybe?

AHK_H is "installed" (if I may call it so) in C:\Program Files\AutoHotkeyH1.
Next to it is AHK_L in C:\Program Files\AutoHotkey.
In desperation I renamed AHK_L's folder and then renamed AHK_H's folder to AutoHotkey. Behavior was exactly the same: error.
I'm out of ideas. :(

P.S. You stil haven't fixed ResGet.ahk in Compiler\Lib. I've already reported recently that the size of the 'data' buffer may remain too large from a previous call, and not resizing and initializing it to zero can and will return badly formatted resources. Especially when an AHK script is retrieved, trying to run such script in a thread will immediately throw an error due to the leftovers.
The fix is a single line, as follows: