mIRC Homepage

COM memory leak bug

Posted By: westor

COM memory leak bug - 08/06/22 11:43 PM

Long time to use mirc, but hi,

I'm facing a COM memory leak that resulting mirc to increase the RAM usage when using the following code, it seems mirc doesn't free the memory somewhere there correctly, i cannot reproduce it by using a smaller code rather just this.

To reproduce it run: /timer[BUG] 100 10 check_bug https://screenrant.com/feed/ and check when this timer halts the mirc memory under task manager, and you will see that something there isn't being freed correctly, code tested under clean portable mirc 7.68 version.

Code
alias check_bug {
  ; /check_bug <LINK>

  var %com1 = rss1_ $+ $rand(1,10000000000) $+ $ticks
  var %com2 = rss2_ $+ $rand(1,10000000000) $+ $ticks
  var %com3 = rss3_ $+ $rand(1,10000000000) $+ $ticks
  var %itemcol = itemcol_ $+ $rand(1,10000000000) $+ $ticks

  .comopen %com1 MSXML2.DOMDocument.6.0

  if (!$com(%com1)) || ($comerr) { echo -tag Unable to create an instance of MSXML2.DOMDocument.6.0 COM! | goto end }
  if (!$com(%com1, async, 4, bool, false)) || ($comerr) { echo -tag Unable to set async property! | goto end }
  if (!$com(%com1, load, 1, bstr*, $1)) || ($comerr) { echo -tag Unable to load XML from source! | goto end }
  if (!$com(%com1, selectnodes, 1, bstr*, /rss/channel/item, dispatch* %itemcol)) || ($comerr) { echo -tag Unable to select nodes /rss/channel/item COM! | goto end }

  var %t = $comval(%itemcol,0)

  if (!%t) { echo -tag There was NOT any RSS Feed items founded! | goto end }

  if (%t > 10) { var %t = 10 }

  var %i = 1
  while (%i <= %t) {
    if (!$com(%itemcol, item, 1, uint, %i, dispatch* %com2)) || ($comerr) { echo -tag Cannot dispatch XML for individual item to new object! | goto end }

    if (!$com(%com2)) { goto next_item }

    .comclose %com2 $com(%com2, childnodes, 3, dispatch* %com3)

    if (!$com(%com3)) { goto next_item }

    var %n = $comval(%com3,0)
    var %c = 1

    while (%c <= %n) {
      if ($comval(%com3,%c,tagName) == title) { var %title = $comval(%com3,%c,text) }
      if ($comval(%com3,%c,tagName) == link) { 
        var %link = $comval(%com3,%c,text)

        ;if (%title) && (%link) { echo -tag %link %title }
      }

      inc %c
    }

    .comclose %com3

    :next_item
    inc %i
  }

  :error
  if ($error) { reseterror }

  :end

  if ($com(%com1)) { .comclose $v1 }
  if ($com(%com2)) { .comclose $v1 }
  if ($com(%com3)) { .comclose $v1 }
  if ($com(%itemcol)) { .comclose $v1 }
}

Posted By: Khaled

Re: COM memory leak bug - 22/06/22 04:23 PM

Thanks for your bug report. This is due to a change made in v7.62 to fix this issue.

Unfortunately, I cannot seem to find a way that fixes that issue without the change.

On the other hand, I have checked all thirty of my $com() test scripts and they all work correctly in v7.61 and do not crash, so it is just the script in the previous bug report that crashes.

The difficulty with $com() scripts is that it is easy for a script to cause an issue, such as a crash, if it uses incorrect parameters, since these are passed to the COM interface.

I rarely use $com(), so I have no idea if $com() in the previous bug report is being called correctly. Can someone here who has experience with it verify if it is using a valid set of $com() calls? If it isn't, that could be the reason why it is crashing and I can revert the change.

I also noticed that even with the fix, the script in the previous bug report still doesn't return any results - so that could indicate it is being called incorrectly.
Posted By: Khaled

Re: COM memory leak bug - 24/06/22 02:02 PM

I thought I had found a fix that would resolve the issue for the older bug report, and the current one, but it turns out that the fix still results in a memory leak.

After googling for "querySelectorAll", which is the cause of the crash in the older bug report, I came across a similar bug report in PowerShell and several posts on Stack Overflow, where using this call was resulting a crash.

As far as I can tell, there is something specific to "querySelectorAll" that is causing applications to crash when it is called in a specific context, and there does not seem to be a way to prevent this.

Because of this, I am going to revert the fix for the older bug report, which will reinstate the correct memory handling behaviour for all other $comval() calls, but this does mean that using "querySelectorAll" in the way it is used in the older script will still result in a crash.

This change will be in the next beta.
Posted By: Wims

Re: COM memory leak bug - 24/06/22 06:36 PM

I had checked the documentation when you mentioned checking if it's valid.

In the original report by kap with "queryselectorall", he is passing the string "table" as a parameter, queryselectorall is expecting css selector to be found in the string, which there aren't any there. The documentation says that if no selector can be found, an exception is raised.

Could it be the exception that you can't seem to catch? As far as I know we should be able to pass incorrect parameter like that and mIRC should handle it, this is assuming objects are never themselves crashing.
Posted By: Khaled

Re: COM memory leak bug - 24/06/22 07:10 PM

Quote
Could it be the exception that you can't seem to catch? As far as I know we should be able to pass incorrect parameter like that and mIRC should handle it, this is assuming objects are never themselves crashing.

Thanks for looking this up. Yes, incorrect parameters are caught by Invoke, however this particular issue results in heap corruption in the COM object, at which point the application is forcibly closed. It sounds very much like the issue described in the PowerShell bug report.
Posted By: Talon

Re: COM memory leak bug - 25/06/22 03:37 AM

There is a css selector in the example, it's table.

A selector has multiple potential string formats, of which, any element tagname can be referenced: "html, a, body, table, div" etc... There's special characters like '.' and '#', where something like .myclass would reference ANY element with a classname of "myclass", and #someuniqueid would reference ANY element with an id of "someuniqueid", you can also combine these options as well, like div.myclass or table.myclass which would reference any (div/table) that also happen to have the class of "myclass". There's tons of special characters like * or + or ~ even a comma (,) to define more than one match criteria...

In short, table by itself is a perfectly fine css selector. The code is valid, the crash is the fault of the com object itself, much like the powershell github example provided by khaled.

Here's a link to a fairly nice cheat sheet in forming selectors.
https://www.freecodecamp.org/news/css-selectors-cheat-sheet/
© 2022 mIRC Discussion Forums