FTYPE crashes TCC v23.00.30-34

Mar 18, 2010
55
0
#1
On my Windows 10 system, (Version 6.3.17134), using TCC v23.00.30 or v23.00.34, entering the FTYPE command causes an application crash. Neither cmd.exe or TCC LE 14.00.9 x64 have any trouble with this. But TCC, once the command is entered, after rapidly blatting out everything that the lesser shells do, pauses for about 3 seconds, if there is only 1 console tab, then the window wholly vanishes. The Task Manager process entries vanish at the same time. With more than 1 console tab, only the TCC and Console Window Host entries vanish.

If the FTYPE output is redirected to NUL, the vanishing still happens but with noticeably less delay.

After redirecting TCC LE's FTYPE output to a file, then TYPEing that from TCC v23, no crash occurs.

In case it will help reproduce or illuminate this problem, I have attached the output from FTYPE produced by TCC LE.
 
Dec 17, 2009
36
0
Germany
#4
FTYPE in TCC 24.00.31 under Windows 7 runs normally, no problems apparent in both 32 and 64 bit environments.

Maybe this is another another weird "feature" of the Windows 10 console?
 
#6
I don't know if it's germane to this thread, but I tried (with a DO loop) to see how long the output lines of FTYPE got. TCC kept hanging ... uninterruptible, and using all of one CPU. I trimmer it down a bit. On Win10/64, with this command
Code:
do l in /p ftype ( echo "%l" )
TCC hangs after echoing
Code:
brmfile="PrintBrmUI.exe" /import /file:""
The next line would/should be (probably with empty strings for the variables)
Code:
"CABFolder=C:\Windows\Explorer.exe /idlist,%I,%L"
which doesn't look too bad to me.

The same happens on Win7/32 where the last line echoed is
Code:
"Autoruns.Logfile.1="C:\Users\vefatica\Desktop\Autoruns\autoruns.exe" """
and the next one that would be echoed is
Code:
"batfile=c:\windows\system32\cmd.exe /c %L %*"
which also doesn't look all that bad.

It may be only a coincidence, but brmfile is the last of the b's and Autoruns.Logfile.1 is the last of the a's.

It seems that anything that puts TCC into an uninterruptible, full CPU state should be investigated.
 
#7
OK, I know what's happpening in my last post. It's choking on the output containing "%L" because I had used "l" as DO's variable. Should that variable loop be detected?
 
Mar 18, 2010
55
0
#8
(Thanks, Vince, for your effort on this.)

In a fresh TC session, after attaching the Visual Studio debugger to the TCC.EXE process, then running 'ftype' as the first command, I get this diagnostic info:
Unhandled exception at 0x00007FFD02CB780C (takecmd.dll) in tcc.exe: Stack cookie instrumentation code detected a stack-based buffer overrun. occurred

I think it has to be something about the whole stream being output by FTYPE because, after capturing the same output from TCC LE, then converting it (via regex substitution) to long series of FTYPE <whatever> commands and running that sequence as a .btm, no crash occurs. Likewise after inserting '@echo off' atop it all.
 
Mar 18, 2010
55
0
#9
Above exception address was for TCC v23.00.34.

For TCC v24.00.32, the exception info is:
Unhandled exception at 0x00007FFCFEC3C8FC (takecmd.dll) in tcc.exe: Stack cookie instrumentation code detected a stack-based buffer overrun. occurred
 

rconn

Administrator
Staff member
May 14, 2008
10,848
97
#10
OK, I know what's happpening in my last post. It's choking on the output containing "%L" because I had used "l" as DO's variable. Should that variable loop be detected?
Not sure what you want here - you want TCC to prevent you from using L as a DO variable? Or you want TCC to prevent you from referencing a DO variable within the DO loop? (And that's not a variable loop, because it's being expanded in multiple places.)
 

rconn

Administrator
Staff member
May 14, 2008
10,848
97
#11
Above exception address was for TCC v23.00.34.

For TCC v24.00.32, the exception info is:
Unhandled exception at 0x00007FFCFEC3C8FC (takecmd.dll) in tcc.exe: Stack cookie instrumentation code detected a stack-based buffer overrun. occurred
Not reproducible here.

After looking through the code, the only way I can see that could happen is if you either have an overly long type name (>128 characters) or an overly long command argument (> 4095 characters).
 
#12
As demonstrated thusly:
Code:
[C:\Work]
> alias max=perl -e "while($_=<>){if($_>$big) {$big=$_;}} print $big,chr(10);"

[C:\Work]
> cmd /c ftype | perl -n -e "($w,$c)=split('=');print length($w),chr(10);" | max
41

[C:\Work]
> cmd /c ftype | perl -n -e "($w,$c)=split('=');print length($c),chr(10);" | max
167
, neither the filetype name or the associated command meets those "overly long" criteria.

TCC v18.00.32 also has no trouble with this.

I think there are some useful clues already apparent in this thread:
1. The problem is not apparent until after the entries have all been emitted. This is consistent with the exception info mentioning detection of a stack buffer overrun. That must be happening upon a subroutine return.
2. TCC v18 and TCC LE v14 are untroubled by my set of ftype entries. Some affected code must have changed, or possibly the stack-based buffer overrun detection instrumentation was not emplaced in earlier versions.
3. The problem is content dependent, as shown by the same program working on other systems (including one of mine.)
4. The exception is generated within TCC.exe, obviously within a loop which does successive ftype entry outputs.
5. The problem occurs without interaction with console window. (Redirecting to NUL does not avoid it.)

If I had a semi-convenient way to produce subsets of the whole set of ftype entries, I could reasonably derive a usable repro case. If I write scripts to save and restore the ftype entries, and can produce a minimal repro case (using the ftype restore with a file I would send), are you (Rex) willing to fix this?
 
#13
Correcting an error from last post:
Code:
[C:\Tmp\Ftypes]
> cmd /c ftype | perl -n -e "s/^^[^^=]=//;print length($_),chr(10);" | max
275
This shows the length in characters of the longest command. (The split on '=' is wrong when the command contains '='.)

I ran a telling experiment this hour. It went like this:
1. Set screen dimensions to 2 high X very wide.
2. Run ftype /p while hitting space just the right number of times, as follows.
3. If hit space up to, but not including when a certain filetype name is output, then hit escape to quite ftype, no exception occurs.
4. If hit space up to and including just when the certain filetype name is output, then hit escape, the exception does occur.

The certain filetype entry reads:
Code:
Perl6="C:\Apps\Rakudo\bin\moar.exe" --execname="perl6" --libpath="C:\Apps\Rakudo\share\nqp\lib" --libpath="C:\Apps\Rakudo\share\nqp\lib" --libpath="C:\Apps\Rakudo\share/perl6/lib" --libpath="C:\Apps\Rakudo\share/perl6/runtime" C:\Apps\Rakudo\share\perl6\runtime\perl6.moarvm
(That is one, 275 character line.)

Interestingly, (and as shown earlier in this thread), just entering 'ftype Perl6' does not induce the exception.

At any rate, I suspect that getting that Perl6 filetype entry to be emitted may be enough.

However, I note one strangeness with that entry in my registry, (beyond it's having the longest command.) For some reason, the registry path for it is 'HKEY_CLASSES_ROOT\Perl6\SHELL\OPEN\COMMAND', with the last 3 keys in uppercase. This appears to be distinct from all other such entries where the last 3 keys are in lowercase. I do not know if this is relevant.
 
#14
More clues:
1. Changing the registry key path to 'Perl6\shell\open\command' does not cure the exception throwing.
2. Changing the value associated with that key to '.' does cure the exception throwing.
3. Removing one of the --libpath=... arguments is also enough to cure the exception throwing.

I will be using #3 above since one of the --libpath arguments was redundant and hence useless.

Code:
This value induces the exception:
123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123456789r123456789s123456789t123456789u123456789v123456789w123456789x123456789y
and  entering
   cmd /c ftype | perl -n -e "s/^^[^^=]=//;print length($_),chr(10);" | max
prints
   257
, while striking the trailing 'y' from the value cures the exception and makes the length check print 256.
I think it is fair to say, at this point, that the looping variant of running ftype does not like command values longer than 256.
 
#16
I can confirm that. Adding a few hundred characters to TCC.Batch's shell\open\command causes FTYPE to crash TCC.
I had (not very carefuly) just thrown in a bunch of characters and saw a crash.
Today I looked more carefully. Here, v24 crashes when the output string reaches exactly 512 characters (not counting a terminating NULL, CR or LF) and after FTYPE's output has finished. v23 crashes earlier. I'll take Larry's word for it being at 256 characters.
 
#17
I find that in both TCC 23 and TCC 24, the following is just sufficient to make 'ftype' fail:
Code:
ftype /u Booger=123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123456789r123456789s123456789t123456789u123456789v123456789w123456789x123456789
Any fewer characters will allow 'ftype' to complete normally. The above is 249 characters for the command part, 6 characters for the filetype name part, and one character for the '='.
If I delete the above (Booger ...), and enter
Code:
ftype /u Yang=123456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789k123456789l123456789m123456789n123456789o123456789p123456789q123456789r123456789s123456789t123456789u123456789v123456789w123456789x123456789y1
, I again am just at the threshold of ftype failure, with a 251 character command, a 4 character filetype name, and a 1 character '='.
It is noteworthy that the total output in both cases, not counting the newline (or a terminating 0), is 256 characters.

I'm not sure what's going on here, but from the evidence it seems reasonable to suspect that the buffer overrun occurs during the process of assembling the filetype name and associated command into a buffer for output.
 
#18
I'm on Win7/32 and I really must go to 512 characters before FTYPE will crash TCC. The first of these won't do it and the second will.
Code:
v:\> ftype /u Booger=%@repeat[x,504]

v:\> ftype /u Booger=%@repeat[x,505]
On Win10/64, it's 256, as you say.