upload(input, inputtedMultipleFiles = 0) ; Upload to Imgur using it's API. { http := ComObjCreate("WinHttp.WinHttpRequest.5.1") img := ComObjCreate("WIA.ImageFile") img.LoadFile(input) ip := ComObjCreate("WIA.ImageProcess") data := img.filedata.binarydata http.Open("POST", "https://api.imgur.com/3/upload") http.SetRequestHeader("Authorization", "Client-ID " imgurClientID) http.Send(data) imgURL := http.ResponseText http := img := ip := data := input := inputtedMultipleFiles := "" If (%0% == 0) && clipURL Return imgURL }

Code that crashes AHK_L x32

Best Answer Lexikos , 18 August 2013 - 09:18 AM

EDIT: I'm sorry about the topic's title: I just figured out that I'm using AHK_L Unicode 32-bit
Fixed.


The thing is that the unmodified code by maestrith works fine for me, and my code (a function that I've created is based on the commands for API communication, taken from maestrith's code) crashes the process upon 3rd call. And the crash is always only upon 3rd call: first 2 calls go well.

What are the requirements for testing this function? I am not a user of imgur, and have no intention of becoming one. imgurClientID
and clipURL
are not defined. Unless they are declared global (i.e. super-global) outside the function (where I cannot see), they are always empty.
All of the basic elements of your script (functions, expressions, ComObjCreate, object syntax, etc.) are heavily used/tested. Any crash is likely to be in whichever libraries you've called, or caused by using them incorrectly. In those cases, the Issues forum is not the most appropriate place to get help.
Edit - Your code is missing this line from maestrith's original code:
http.SetRequestHeader("Content-Length",size)
However, maestrith's code never sets size.

I thought you could just analytically define what in that function might cause a crash.
So here is the full list of steps to reproduce the crash.
1. Get GDIp.ahk library.
2. Run my script. It already contains imgurClientID.
To take 1 screenshot 3 PrintScreen hits are required: first hit, move cursor a bit, second hit to lock the recorded area, third hit to take&upload the screenshot.
First 2 screenshots get normally taken and uploaded. But 3rd one causes the script to crash.
And just for the comparison: maestrith's code doesn't cause a crash to me and my old code (which uses the same GDI+ commands that my current code does [but it works with a different hosting and requires the hosting's utility to work]) is also not crashy for me at all.
And yeah, adding http.SetRequestHeader("Content-Length",size) didn't affect anything: the code still crashes script's process.
p.s.: I'll try to ask for help in GDI+ forum topic, but the thing is that the very same gdip calls worked just fine until I modified the 'upload' part in my script.

When I initially ran your script, it indefinitely waited for the image to exist. The image was never going to exist, because the path it was trying to save to is invalid:
%USERPROFILE%\AppData\Local\Temp\20130818190301.png
Why are you reading environment variables from the registry? Your script doesn't have #NoEnv, so you can just use %Temp%
. Alternatively, you could use EnvGet or the built-in %A_Temp%
. I used Temp := A_Temp
.
I also had to set optimizePNG := 0. I suggest checking for optipng.exe before attempting to run it.
After that, the script crashed on the fourth screenshot. eventvwr/Application log shows me:
Faulting application name: AutoHotkey.exe, version: 1.1.12.0, time stamp: 0x520b5bb2
Faulting module name: gdiplus.DLL_unloaded, version: 0.0.0.0, time stamp: 0x515bb50aException code: 0xc0000005Fault offset: 0x704d562eFaulting process id: 0xe10Faulting application start time: 0x01ce9bf2beb51aabFaulting application path: C:\Program Files (x86)\AutoHotkey\AutoHotkey.exeFaulting module path: gdiplus.DLLReport Id: 70cab3f4-07e6-11e3-aca5-005056c00008
The exception code means Access Violation. Since it occurred in gdiplus.dll, I presume one of your GDI+ pointers is invalid or your script is corrupting memory used by GDI+. What this also means to me is that the code in your first post really has nothing to do with the crash.
As far as I'm concerned, this is a problem in your script and not AutoHotkey. I am not interested in debugging it further.

Why is that path invalid?When I initially ran your script, it indefinitely waited for the image to exist. The image was never going to exist, because the path it was trying to save to is invalid:
%USERPROFILE%\AppData\Local\Temp\20130818190301.png
I didn't know the other way to get the path of windows' built-in %Temp% var so I had to use RegRead to do that.Why are you reading environment variables from the registry? Your script doesn't have #NoEnv, so you can just use
%Temp%
. Alternatively, you could use EnvGet or the built-in%A_Temp%
. I usedTemp := A_Temp
.
Thanks for the tip about using just %Temp%.
And no, using %A_Temp% doesn't suit me because %A_Temp% != %Temp%.
Thanks for that good idea.I also had to set optimizePNG := 0. I suggest checking for optipng.exe before attempting to run it.
I did so too and it still crashes on 3rd time.After that, the script crashed on the fourth screenshot.
Thanks for your help, Lexikos. I'm not that good with GDI+, so I'll ask for help there.eventvwr/Application log shows me:
The exception code means Access Violation. Since it occurred in gdiplus.dll, I presume one of your GDI+ pointers is invalid or your script is corrupting memory used by GDI+. What this also means to me is that the code in your first post really has nothing to do with the crash.
As far as I'm concerned, this is a problem in your script and not AutoHotkey. I am not interested in debugging it further.

Seems like guest3456 was right about the reason of the script's crash: in my script I had multiple Gdip_Startup() (first of really got into the code by my mistake) and Gdip_Shutdown() calls.
Seems like these are not a very reliable functions: they may work or they may not work for some unknown reasons (even if they get called properly).
My previous script works perfectly fine with multiple calls of Gdip_Startup() & Gdip_Shutdown(), but that code - doesn't work that well.
After fixing my script's code so that it now calls for them only once (which would probably cause memory leakages, since if I kill (not quit, but kill) the script - the 'OnExit' subroutine won't get executed, and that AFAIU will lead a memory leakage) - the script doesn't crash anymore.
It now shows a different error:
http.Send(data)The server returned an invalid or unrecognized response.
EDIT: seems like it was a two-times error, it doesn't show up anymore.

And no, using %A_Temp% doesn't suit me because %A_Temp% != %Temp%.
It is, unless TMP is set and not equal to TEMP, or both TMP and TEMP are unset. Even if it returns a different directory to %TEMP%, why would that matter as long as it returns a directory suitable for storing temporary files?
The GetTempPath function checks for the existence of environment variables in the following order and uses the first path found:
- The path specified by the TMP environment variable.
- The path specified by the TEMP environment variable.
- The path specified by the USERPROFILE environment variable.
- The Windows directory.
Source: GetTempPath function
Why is that path invalid?
AutoHotkey does not expand environment variables in strings, and % is not valid in a path.
After fixing my script's code so that it now calls for them only once (which would probably cause memory leakages, since if I kill (not quit, but kill) the script - the 'OnExit' subroutine won't get executed, and that AFAIU will lead a memory leakage)
You were already calling Gdip_Startup() when the script starts, but not calling Gdip_Shutdown() on exit. Subsequent calls only increment a counter. I believe you need to call Gdip_Shutdown() exactly the same number of times to unload GDI+. Your crashing probably came from calling Gdip_Shutdown() too many times - i.e. you called it when pressing PrintScreen the third time, but never called Gdip_Startup() after that, since the auto-execute section only executes once.
Failing to call Gdip_Shutdown() won't leak memory. Memory is reclaimed by the OS when the process terminates.

Oh, I've changed the default path of %TEMP% and %TMP% EnvVars in Windows to "R:\Temp", so probably that's why it works fine for me.AutoHotkey does not expand environment variables in strings, and % is not valid in a path.
So, as far as I understand - I'll have to use GetTempPath() to get the correct path of %TEMP% Windows' EnvVar, right?
Nope, the issue was a bit different: each 1st PrintScreen hit was calling Gdip_Startup(). I just wrongly added another Gdip_Startup() call on startup: comment it out (the whole first block that starts with "If !pToken := Gdip_Startup()") and there would be as many gdip_shutdown()'s as gdip_startup()'s, but the script would still crash upon 3rd call.You were already calling Gdip_Startup() when the script starts, but not calling Gdip_Shutdown() on exit. Subsequent calls only increment a counter. I believe you need to call Gdip_Shutdown() exactly the same number of times to unload GDI+. Your crashing probably came from calling Gdip_Shutdown() too many times - i.e. you called it when pressing PrintScreen the third time, but never called Gdip_Startup() after that, since the auto-execute section only executes once.
The very same gdip-related code works perfectly fine in my old script, who also called gdip_startup() every time the drawing started and called gdip_shutdown every time it was time to clear the drawing. No crashes. Works stable.
The only part that I've changed is actually the communication with the server: earlier I used a different pic-hosting and I used their util and the script was just automatizing the button clicks in that util. And now the script uses a different pic-hosting and uses ComObjs to communicate with that server using their API.
That's what was really strange and that confused me so much, that I didn't thing that GDI+ could be the reason of the crash and that's why I've created this topic.
Oh, good to know that I don't need to worry about that. [That also actually means, that I can remove Gdip_Shutdown() from my script at all, since the OS will nurse me anywaysFailing to call Gdip_Shutdown() won't leak memory. Memory is reclaimed by the OS when the process terminates.

Thanks for your help, Lexikos.
img.imageResizerActiveClass{cursor:nw-resize !important;outline:1px dashed black !important;} img.imageResizerChangedClass{z-index:300 !important;max-width:none !important;max-height:none !important;} img.imageResizerBoxClass{margin:auto; z-index:99999 !important; position:fixed; top:0; left:0; right:0; bottom:0; border:1px solid white; outline:1px solid black;}
Edited by iDrug, 20 August 2013 - 08:40 PM.

Just for the protocol:
Seems like guest3456 was right about the reason of the script's crash: in my script I had multiple Gdip_Startup() (first of really got into the code by my mistake) and Gdip_Shutdown() calls.
Seems like these are not a very reliable functions: they may work or they may not work for some unknown reasons (even if they get called properly).
My previous script works perfectly fine with multiple calls of Gdip_Startup() & Gdip_Shutdown(), but that code - doesn't work that well.
you should not claim that functions are unreliable when you are using them incorrectly. if it worked correctly in previous scripts, you got lucky. you are using it wrong so your previous script is badly coded as well. i have not seen one example yet where it was necessary to have multiple, SIMULTANEOUS, Gdip_Startup() calls needed
for now, its probably best for you to assume that any errors you encounter are due to YOUR CODE, and not due to AHK or GDI+ or any other library that you are working with. you prematurely posted this thread in this forum as if there was a bug with AHK itself, and now you are accusing GDI+ of the problem of being unreliable
your thread should be in the "Support" section where you are asking other people for help: "What am I doing wrong?" instead of accusing everything else of being broken
apologies if i'm being harsh but the truth is the truth

There were no simultaneous Gdip_Startup() calls in my both scripts (one that works fine and one that was crashy). The block that starts with "If !pToken := Gdip_Startup()" got into my code just when I was uploading it to show it to you, my local version didn't have that block, but the crash still appeared. Please, do disregard that block.i have not seen one example yet where it was necessary to have multiple, SIMULTANEOUS, Gdip_Startup() calls needed
I assumed that from the beginning: the topic's name says that my code is crashing AHK process. My code. Not gdi+ or ahk.for now, its probably best for you to assume that any errors you encounter are due to YOUR CODE, and not due to AHK or GDI+ or any other library that you are working with. you prematurely posted this thread in this forum as if there was a bug with AHK itself, and now you are accusing GDI+ of the problem of being unreliable
No offense taken: since the crash is now resolved - I agree that it's time to ask in "Support" section, that's why I even marked this topic as "solved".your thread should be in the "Support" section where you are asking other people for help: "What am I doing wrong?" instead of accusing everything else of being broken
apologies if i'm being harsh but the truth is the truth

