Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

TPIPE.EXE crashes on Ctrl-C

May
12,845
164
TPIPE.EXE always crashes on Ctrl-C.

This was first reported five years ago ... and again during the v21 beta ... something to do with textpipeengine.dll and a console ctrl handler. Did you ever mention it to the developers? ... get a response?

FWIW,

Problem signature:
Problem Event Name: APPCRASH
Application Name: TPIPE.EXE
Application Version: 0.0.0.0
Application Timestamp: 597cd960
Fault Module Name: KERNELBASE.dll
Fault Module Version: 6.1.7601.17932
Fault Module Timestamp: 503275ba
Exception Code: 0eedfade
Exception Offset: 0000d3cf
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 1033

Read our privacy statement online:
http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409

If the online privacy statement is not available, please read our privacy statement offline:
C:\Windows\system32\en-US\erofflps.txt
---------------------------
Error
---------------------------
Runtime error 217 at 00011AEC
---------------------------
OK
---------------------------
 
(Subtitle: aliases and line continuations?)

My problem occurs when /output is not specified. Then, TPIPE starts a new TCC to TYPE a tmp-file containing the output (question: Why doesn't TPIPE.EXE just exit after starting that TCC?).

I've had some success with this alias.
Code:
v:\> alias ctpipe
tpipe /output=%temp\ctpipe.tmp %$ & type %temp\ctpipe.tmp

Somewhat to my surprise, it works here.
Code:
echo %@execarray[l,ctpipe /input=h:\temp\ksyr.tmp ^
   /grep=3,0,0,1,0,0,0,0,"right.*left" ^
   /replace=4,1,0,1,0,0,0,0,0,".*([0-9][0-9]:[0-9][0-9]).*td.(-*[0-9]*)..td..td.*[0-9]*..td.$","$1  $2" ^
   /head=0,0,24] > NUL
After that pleasant surprise, I was disappointed that it failed here, with TPIPE getting a raw '^' as a parameter:
Code:
ctpipe /input=h:\temp\forecast.tmp ^
   /grep=3,0,0,1,0,0,0,0,"High: \d+|Low: [-]*\d+" ^
   /simple=16 ^
   /replace=4,0,0,0,0,0,0,0,0," &",\n ^
   /replace=4,1,0,0,0,1,0,0,0,"High.*$|Low.*$",$0\n ^
   /simple=12 ^
   /replace=0,1,0,1,0,0,0,0,0,"Low: ","Low:  "

I fixed that with parentheses; this one works:
Code:
(ctpipe /input=h:\temp\forecast.tmp ^
   /grep=3,0,0,1,0,0,0,0,"High: \d+|Low: [-]*\d+" ^
   /simple=16 ^
   /replace=4,0,0,0,0,0,0,0,0," &",\n ^
   /replace=4,1,0,0,0,1,0,0,0,"High.*$|Low.*$",$0\n ^
   /simple=12 ^
   /replace=0,1,0,1,0,0,0,0,0,"Low: ","Low:  ")

So what's going on in the failing case; why aren't the line continuations honored?
 
Here's a simplification of that behavior. Why isn't the line continuation honored in the "zztest.btm" example?
upload_2017-8-2_20-34-53.png
 
Back to the original problem, TPIPE.EXE crashing. The text processing itself is very fast. It's console output that I want to interrupt (especially when testing with a big (real thing) file).

Can't TPIPE.EXE do this?

If it's going to start a TCC to TYPE a temp file ...
Just before starting that TCC ...
Add a console ctrl handler that does nothing but return TRUE ...

That will prevent textpipeengine's handler from being called and allow processing to continue. The TCC doing the outout will exit because of the signal, and TPIPE.EXE will terminate normally.

I can Ctrl-C out of TPIPE console output with no crash after injecting this DLL into TPIPE.EXE.

Code:
#include <windows.h>

BOOL WINAPI CtrlHandler ( DWORD dwSignal )
{
   return TRUE;
}

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved )
{
   if ( dwReason == DLL_PROCESS_ATTACH )
       SetConsoleCtrlHandler(CtrlHandler, TRUE);
   return TRUE;
}
 
Or, under the same circumstances, just tell TPIPE.EXE to ignore Ctrl-C. Injecting this DLL also works.

Code:
#include <windows.h>

BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpvReserved )
{
   if ( dwReason == DLL_PROCESS_ATTACH )
       SetConsoleCtrlHandler(NULL, TRUE);
   return TRUE;
}
 
TPIPE.EXE is already doing the same thing (and always has been).
When does it do that? Does the handler return TRUE? Why do you suppose my rather heavy-handed method works while that fails?
 
When does it do that? Does the handler return TRUE? Why do you suppose my rather heavy-handed method works while that fails?
Experiment has shown me that if I put ExitProcess() in the handler routine, I get the (same) crash.
 

Similar threads

Back
Top