replace()ing a crash
- Posted by Graeme May 26, 2021
- 1067 views
Recently got a hard exit with the 4.1.0 interpreter on win10 migrating an old program from 3.1.1 which I eventually tracked down to a function called replace().
The program was nothing too fancy, just renaming and sorting a bunch of media files, removing filename tags etc.
It was working ok but then suddenly started exiting without any warning or output. After inserting a heap of log and flush to file debug markers and retrying a bunch of times I eventually found the culprit.
I replaced (heh) replace() with this:
function replace2(sequence s,object o1,object o2) for x=1 to length(s) do if equal(s[x],o1) then s[x]=o2 end if end for return s end function
and the crash stopped.
"Oh", thinks I, "There's a problem in 4.1 with this replace() function", and continued with what I was doing.
But then later on I looked a bit further and discovered that this replace() func was actually one of my own that I had in a library from years ago :facepalm:
The original looks like this:
global function replace(object s,object before,object after) if atom(s) then return replace({s},before,after) end if for x=1 to length(s) do if equal(s[x],before) then s[x]=after end if end for return s end function
Obviously the only difference is that it handles the possibility of someone passing an atom as the haystack via recursion and guarantees a sequence as the return. The nature of that call means the depth can never be greater than two.... if atom(s) then use {s}
This is moot anyway because I got no problem once I used replace2() so it can't have been passing an atom as the first argument or replace2() would have stopped with a type error.
This lead me to believe the the crash could possibly be related to some rare set of circumstances involving passing a sequence as type object for an argument (in this case the first argument) as against passing it as type sequence.
So just when I thought this was all over, I find this:
-- Signature: -- <built-in> function replace(sequence target, object replacement, integer start, integer stop=start) -- -- Description: -- replaces a slice in a sequence by an object. -- -- Parameters: -- # ##target## : the sequence in which replacement will be done. -- # ##replacement## : an object, the item to replace with. -- # ##start## : an integer, the starting index of the slice to replace. -- # ##stop## : an integer, the stopping index of the slice to replace. -- -- Returns: -- A **sequence**, which is made of ##target## with the ##start..stop## slice -- removed and replaced by ##replacement##, which is spliced in.
So apparently 4.1 does have a func called "replace()" after all. I'm assuming it would(should?) not have come into play as the global func in my library would have overridden this built-in anyway. Or would it? Not totally up to speed on all the rules involving this stuff. Pretty sure that regardless I shouldn't have ended up with a hard exit.
.
There isn't really any more useful info I can add here. When the crash stopped I renamed and sorted the media files (which was the job at hand), so I don't have the original input from when I found the problem, and the program itself is a bunch of old spaghetti anyway.
This is just a morsel of a possible clue if anyone else is trying to track down a similar issue in the future.
Graeme.