Weird COM behavior - msgbox causes crash Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Weird COM behavior - msgbox causes crash

Post by TheArkive » 23 Feb 2021, 08:50

The following code works, in regards to creating / destroying a COM obj.

Code: Select all

test := IWICImagingFactory.New()
; msgbox "Works, but ends with error on [ test.obj := '' ] "
ObjRelease(test.obj.ptr)
; msgbox "this causes an error"
test.obj := ""
; Msgbox "this doesn't cause an error"


class IWICImagingFactory {
    ptr := 0
    obj := 0
    CLSID := [0xcacaf262, 0x9370, 0x4615, 0xa1, 0x3b, 0x9f, 0x55, 0x39, 0xda, 0x4c, 0xa]
    IID   := "{ec5ec8a9-c395-4314-9c77-54d7a935ff70}"
    
    __New(inPtr:=0) {
        this.obj := ComObjCreate(this.CLSID_str(this.CLSID), this.IID)
    }
    __Delete() {
    }
    CLSID_str(inCLSID, out_str:="") { ; create CLSID str from [array,of,values].
        For i, item in inCLSID
            out_str .= ((i=2 Or i=3 Or i=4 Or i=6)?"-":"") Format("{:0" ((i=1)?8:(i<=3)?4:2) "X}",item)
        return "{" out_str "}"
    }
}
If I uncomment the last Msgbox it's fine. But if i uncomment any combo of the first 2, it ends in an error when trying test.obj := "".

Error Message:

Code: Select all

---------------------------
__test_v2.ahk
---------------------------
Critical Error:  Invalid memory read/write.

	Line#
	017: test := IWICImagingFactory.New()
	018: msgbox("Works, but ends with error on [ test.obj := '' ] ")
	019: ObjRelease(test.obj.ptr)
	020: msgbox("this causes an error")
--->	021: test.obj := ""
	025: {
	000: }
	026: {
	000: Super.__Init()
	026: this.ptr := 0
	027: this.obj := 0
	028: this.CLSID := [0xcacaf262, 0x9370, 0x4615, 0xa1, 0x3b, 0x9f, 0x55, 0x39, 0xda, 0x4c, 0xa]

The program is now unstable and will exit.
---------------------------
OK   
---------------------------


Here's a slightly different approach with a slightly different result in the error (though the same error message):

Code: Select all

test := IWICImagingFactory.New()
msgbox "Works, but ends with error on [ test.obj := '' ] "
ObjRelease(test.obj.ptr)
; msgbox "this causes an error"
; test.obj := ""
; Msgbox "this doesn't cause an error"


class IWICImagingFactory {
    ptr := 0
    obj := 0
    CLSID := [0xcacaf262, 0x9370, 0x4615, 0xa1, 0x3b, 0x9f, 0x55, 0x39, 0xda, 0x4c, 0xa]
    IID   := "{ec5ec8a9-c395-4314-9c77-54d7a935ff70}"
    
    __New(inPtr:=0) {
        this.obj := ComObjCreate(this.CLSID_str(this.CLSID), this.IID)
    }
    __Delete() {
    }
    CLSID_str(inCLSID, out_str:="") { ; create CLSID str from [array,of,values].
        For i, item in inCLSID
            out_str .= ((i=2 Or i=3 Or i=4 Or i=6)?"-":"") Format("{:0" ((i=1)?8:(i<=3)?4:2) "X}",item)
        return "{" out_str "}"
    }
}
This throws the same error as above, but on Exit.

If you comment out the msgbox then no error is thrown.
=================================================================================
Is this considered normal in general? Very occasionally I can run this code with one of the first 2 msgbox's and it will complete without error. But it seems a few sequential runs ensures errors eventually.

There seems to be a period of time I can wait to then run this code without error (with msgbox's), but again, after a few runs it will start to error again.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: Weird COM behavior - msgbox causes crash

Post by kczx3 » 23 Feb 2021, 13:57

Why are you manually releasing the pointer before destroying the object? If you stop doing that does it throw any errors?
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Weird COM behavior - msgbox causes crash

Post by TheArkive » 23 Feb 2021, 16:14

@kczx3
Oops, yah. :facepalm:

I thought one was supposed to ObjRelease() manually. I guess that's only for when adding references?

I'm still a bit new to COM. :P
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Weird COM behavior - msgbox causes crash  Topic is solved

Post by swagfag » 23 Feb 2021, 19:21

ComObject v2 wrote:If a wrapper object's VarType is VT_UNKNOWN (13) or VT_DISPATCH (9) .... Once assigned (if non-null), the pointer will be released automatically when the wrapper object is freed.
u first do ObjRelease(test.obj.ptr) which drops the refcount(1 -> 0) and thus the IUnknown::Release() actually frees the pointer.
then u invoke the comwrapper's destructor with test.obj := "" which itself calls IUnknown::Release() on a no longer valid pointer, resulting in double free undefined behavior. it cant know what uve previously done with the refcount, since uve circumvented the mechanism entirely by manipulating the refcount urself.

the error occurs on the line test.obj := "". whether u notice any obvious irregularities in how the script runs after that point is irrelevant
ObjRelease() can be used when u retrieve a naked pointer with QueryInterface / ComObjQuery for example
or if an API tells u the caller frees
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Weird COM behavior - msgbox causes crash

Post by lexikos » 24 Feb 2021, 03:07

In general, problems with a script are not related to v2 Development and should be posted in the AutoHotkey v2 Help forum. Bug reports should be posted in Bug Reports. I am moving the topic.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Weird COM behavior - msgbox causes crash

Post by TheArkive » 24 Feb 2021, 11:39

@swagfag
@lexikos
Thanks for the explanation, and sorry for posting in the wrong forum.
Post Reply

Return to “Ask for Help (v2)”