mIRC Homepage
Posted By: maroon Intermittent /hsave -i GPF crash - 02/08/22 11:45 PM
I'm encountering a GPF bug that I cannot replicate because it's intermittent, so I cannot create an example to make it happen on-demand. But I'm hoping someone else has been encountering this bug and can offer more clues that could help identify the fix.

I have 2 scripts accessing the same website via urlget. Both scripts use hashtables where each item added contains text up to 2kb in length.

One script access 1 url every half hour, updating a hash table that can reach up to 20mb or so, and hsaving it each half-hour right after accessing the url. Never seems to be a problem with that script.

The other script accesses a different url each half second or so, where each url is used to add another of those items to the hashtable, and it hsave's the hashtable at the end when finished, as well as every 400 items being added while in progress.

It's the hsave at one of the intervals of 400 that seems to be when the GPF happens. When the crash happens, there's almost always a mirc*.tm_ file whose timestamp matches when the crash happened, and the content is what would be from the 2nd script hsaving to disk. In case it matters, the hsaves are both using the -i switch.

For the latest crash, the disk write had what appears to be correctly written item=data lines, except for the very last disk write that contains unexpected content, so maybe the crash is due to writing data from someplace random that it shouldn't be.

The latest *.tm_ file contains 2385 valid item=string lines, but following the $crlf for the last completed line, the remaining bytes are the hex string:

0x43 0x05 0x20 0x0d 0x0a

In this case, the correct disk write would've begun with an itemname= beginning with '4'.

Since the item count wasn't a multiple of 400, this tells me that it didn't write the whole hashtable database. before crashing.

update: another crash had a different invalid string as the final line following the $crlf:

0x0a 0x2a 0x0d 0x0a

1502 valid item=string before the bad line, again not a multiple of 400

update: another crash. The final garbled line was the same 0x43 0x05 0x20 0x0d 0x0a as above. 1st time I remember the crash being the larger hashtable on the 30 minutes timer, after writing 3.7 of 18mb

edit: and what event reporter is saying
Faulting application name: mirc.exe, version:, time stamp: 0x62d559f7
Faulting module name: ntdll.dll, version: 6.1.7601.23391, time stamp: 0x56e9a630
Exception code: 0xc0000374
Fault offset: 0x000c3b03
Faulting process id: 0x26b0
Faulting application start time: 0x01d8a617020b3af1
Faulting application path: C:\mIRC\mirc.exe
Faulting module path: C:\Windows\SYSTEM32\ntdll.dll

Posted By: Khaled Re: Intermittent /hsave -i GPF crash - 03/08/22 09:13 AM
Thanks for your bug report. If you can provide a minimal script similar to the one that is causing the issue, ie. uses a similar size hash table, file sizes, identical switches for the commands/identifiers, etc., I will test it out here. It doesn't matter at this point if it doesn't reliably reproduce the issue for you, I just need a starting point that matches the sequence of steps/commands/identifiers/switches/options that you are using. It may be that the debugger will catch something not immediately visible in a release version.
Posted By: KindOne Re: Intermittent /hsave -i GPF crash - 09/08/22 10:44 AM
I've crudely modified a copy of maroon's script that is giving him the issue. I've had my modified version crash my copy of mIRC multiple times.

; 1, Download file: https://2ton.com.au/getprimes/20180312/dhparam/2048/3
; 2, Place file on a http server and rename as 'file'.
; 3, Replace %url below so you can download the file from your http server.
; 4, /client_crash_start 
; 5, Minimize mIRC and do stuff in another programs. 
; 6, Wait anywhere from 10 seconds - 60 minutes for the crash?

alias client_crash_start {
  set %y 0
  if (!$hget(testing)) { hmake testing 10000 }
  var %x 100
  while (%x) {
    .timer_ $+ %x -om 1 250 client_crash
    dec %x
alias client_crash {
  var %url =
  bset -t &header 1 Test: Header
  bset -t &body 1 foo1=bar1&foo2=bar2
  var %id = $urlget(%url,pb,&target,urlget.callback,&header,&body)
  if (%y == 200) {
    echo -ag *** hsave
    hsave -sim testing testing.ini
    set %y 0
  inc %y
alias urlget.callback {
  var %id = $1
  var %ID $urlget($1).target
  var %a 2tonDB-2022-07Jul-2048 $rand(11111111,99999999) 2048 589 . 55694
  tokenize 32 %a
  var  %a $remove($bvar(%ID,1-).text,$cr,$lf)
  var  %mime $regsubex(%a,/^(-+BEGIN DH PARAMETERS-+)([A-Za-z0-9+\/=]+)(-+END DH PARAMETERS-+)/,\2)
  ;echo -s  $scriptline : regsubex regml(0) $regml(0)
  ;echo -s  $scriptline : $len(%a) $left(%a,55)
  ;echo -s  $scriptline : $cb(-1).len $left($cb(-1),55)
  bset -t &v 1 %mime | noop decode %a $decode(&v,bm)
  var  %g $bvar(&v,$bvar(&v,0))
  var   %p $bvar(&v,10, $calc($3 //8) )
  var %p $regsubex(%p,/([0-9]+)\s*/g,$base(\t,10,16,2) )
  var  %table testing
  var  %item $+($3,-,$2,25,$base($4,10,10,4))
  var  %data %g %p
  var %a $hget(%table,item)
  hadd -sm %table %item %data
  .timer -om 1 250 client_crash
Posted By: Wims Re: Intermittent /hsave -i GPF crash - 09/08/22 01:29 PM
Hello, I've been trying to help maroon on this as well as Kindone.
I used a modified version of Kindone's script above which puts a /write to a file before and after the $urlget and /hsave -i call. It crashed after 30mins, the text file's last /write was 'after $urlget'.
maroon made the same observation using /write in his original script. Using Kindone's script, for me it means the crash occurs after the script execution, not during, and it does not seem to crash without $urlget.
Please test this in a release version of 7.69, not (or as well as) a debug version.
Posted By: Khaled Re: Intermittent /hsave -i GPF crash - 06/09/22 08:22 AM
Thanks to the above testers for their help in tracking down this issue.

I am posting the following mainly as documentation for future reference.

The testers were able to reproduce a heap corruption crash by running test scripts that called specific commands/identifiers in mIRC for ten minutes to an hour. Unfortunately, I could not reproduce the issue, despite:

Using the same configuration as them, ie. a clean copy of mIRC v7.69 release version, default settings, with the test script.
Testing on five different computers, including a cutting edge Ryzen, with Windows 10.
Testing on Windows XP, 7, Windows 11 22H2, Ubuntu Wine under VirtualBox.
Testing mIRC with full debugging, AppVerify, etc.
Running the script, and variations of it, for hours at a time.
Repeating the tests many times in different contexts.

An intermittent bug like this one usually involves threads and data races/race conditions but a code review did not show up anything. Testers were able to reproduce the issue with different combinations of commands/identifiers but it wasn't clear which was the cause. Private betas were released with code changes hoping to improve robustiness in several features without result. Unit tests that created multiple threads to try to force heap corruption/data races/race conditions did not reproduce the issue for me. Dump files, exception codes, fault offsets, etc. did little to help narrow down the cause.

The testers eventually determined that the issue began with v7.53. I also finally reproduced the issue once in a debug version of mIRC after several weeks of testing.

It turns out that the issue was due to a combination of changes, across several features, related to memory-handling that resulted in a data race/race condition window outside of the critical sections that were in place to prevent this.

The issue was resolved by making minor changes to how memory is handled in several features, including hash tables, regular expressions, INI files, binary variables, and file handling.

This fix is in the most recent beta.
© mIRC Discussion Forums