TCL issues -10007 error when using oo:class, 1 case and solution - syntax-error

This is both a (maybe) bug report, and a question and answers. You have TCL 8.6, on LINUX RHEL6 64 bits, and you see this cryptic message:
-10007
while executing
"oo::class create DlgClass {
method addInstDevBasedProc {} {
foreach inst_name [ my getInstsForPmExecute ] {
puts "Inst:$inst_name}"
..."
(file "moma.tcl" line 1)
What happened?
Well, it is all about a missing left brace in the puts "Inst:$inst_name}", right after the $ sign.This of course does not mean that other type of mistakes cannot yield the same error code. Unfortunately, I have issues with logging in to the news-group of TCL, and report the message, but wanted to spread the word.I suggest that TCK have a more meaningful error message for this, in future releases.

Related

Is it possible to enable exit on error behavior in an interactive Tcl shell?

I need to automate a huge interactive Tcl program using Tcl expect.
As I realized, this territory is really dangerous, as I need to extend the already existing mass of code, but I can't rely on errors actually causing the program to fail with a positive exit code as I could in a regular script.
This means I have to think about every possible thing that could go wrong and "expect" it.
What I currently do is use a "die" procedure instead of raising an error in my own code, that automatically exits. But this kind of error condition can not be catched, and makes it hard to detect errors especially in code not written by me, since ultimately, most library routines will be error-based.
Since I have access to the program's Tcl shell, is it possible to enable fail-on-error?
EDIT:
I am using Tcl 8.3, which is a severe limitation in terms of available tools.
Examples of errors I'd like to automatically exit on:
% puts $a(2)
can't read "a(2)": no such element in array
while evaluating {puts $a(2)}
%
% blublabla
invalid command name "blublabla"
while evaluating blublabla
%
As well as any other error that makes a normal script terminate.
These can bubble up from 10 levels deep within procedure calls.
I also tried redefining the global error command, but not all errors that can occur in Tcl use it. For instance, the above "command not found" error did not go through my custom error procedure.
Since I have access to the program's Tcl shell, is it possible to
enable fail-on-error?
Let me try to summarize in my words: You want to exit from an interactive Tcl shell upon error, rather than having the prompt offered again?
Update
I am using Tcl 8.3, which is a severe limitation in terms of available
tools [...] only source patches to the C code.
As you seem to be deep down in that rabbit hole, why not add another source patch?
--- tclMain.c 2002-03-26 03:26:58.000000000 +0100
+++ tclMain.c.mrcalvin 2019-10-23 22:49:14.000000000 +0200
## -328,6 +328,7 ##
Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
Tcl_WriteChars(errChannel, "\n", 1);
}
+ Tcl_Exit(1);
} else if (tsdPtr->tty) {
resultPtr = Tcl_GetObjResult(interp);
Tcl_GetStringFromObj(resultPtr, &length);
This is untested, the Tcl 8.3.5 sources don't compile for me. But this section of Tcl's internal are comparable to current sources, tested using my Tcl 8.6 source installation.
For the records
With a stock shell (tclsh), this is a little fiddly, I am afraid. The following might work for you (though, I can imagine cases where this might fail you). The idea is
to intercept writes to stderr (this is to where an interactive shell redirects error messages, before returning to the prompt).
to discriminate between arbitrary writes to stderr and error cases, one can use the global variable ::errorInfo as a sentinel.
Step 1: Define a channel interceptor
oo::class create Bouncer {
method initialize {handle mode} {
if {$mode ne "write"} {error "can't handle reading"}
return {finalize initialize write}
}
method finalize {handle} {
# NOOP
}
method write {handle bytes} {
if {[info exists ::errorInfo]} {
# This is an actual error;
# 1) Print the message (as usual), but to stdout
fconfigure stdout -translation binary
puts stdout $bytes
# 2) Call on [exit] to quit the Tcl process
exit 1
} else {
# Non-error write to stderr, proceed as usual
return $bytes
}
}
}
Step 2: Register the interceptor for stderr in interactive shells
if {[info exists ::tcl_interactive]} {
chan push stderr [Bouncer new]
}
Once registered, this will make your interactive shell behave like so:
% puts stderr "Goes, as usual!"
Goes, as usual!
% error "Bye, bye"
Bye, bye
Some remarks
You need to be careful about the Bouncer's write method, the error message has already been massaged for the character encoding (therefore, the fconfigure call).
You might want to put this into a Tcl package or Tcl module, to load the bouncer using package req.
I could imagine that your program writes to stderr and the errorInfo variable happens to be set (as a left-over), this will trigger an unintended exit.

Errors in October CMS installation via cPanel

I just installed October CMS on my hosting platform via cPanel's Softaculous utility. I do not believe installation method has anything to do with my errors but mentioning it just in case I am wrong.
October CMS Version: 1.0.458
Sever PHP Version: 7.3.3
After installing in the designated directory it is showing "HTTP 500" generic error so I checked the error log. Following error was being shown
"[28-Sep-2019 11:09:04 Etc/GMT] PHP Parse error: syntax error, unexpected '[', expecting ')' in /home/XYZ/public_html/XYZ/vendor/october/rain/src/Support/helpers.php on line 149"
There is absolutely no online resource which describes occurance of such an error and possible solution. So I opened the helper.php to look at line 149. The code on this line was,
$query = str_replace(['%', '?'], ['%%', '%s'], $query);
Now there is nothing seemingly wrong with this line but I thought may be the "str_replace" function is not able to understand the array arguments. So I removed the array arguments and wrote it two times like
$query = str_replace('%', '%%', $query);
$query = str_replace('?', '%s', $query);
Now the error on this line disappears but a new error appears on another line as follows
PHP Parse error: syntax error, unexpected '[' in /home/XYZ/public_html/XYZ/vendor/october/rain/src/Support/helpers.php on line 238
The code on this line is
function trans($id = null, $parameters = [], $domain = 'messages', $locale = null)
Now here I am not sure if removing brackets would make everything alright. Why should such strange errors appears? Can someone help?
Are you 100% sure the PHP version you're using is 7.3.3?
The short array syntax of using [ ... ] instead of array( ... ) was introduced in PHP 5.4 and the errors you are getting are the errors that will happen if you are using an older version of PHP. I'm not sure how cPanel Softaculous works, but perhaps somehow it set you up to use a different version of PHP then you expect.
I would try running phpinfo() to double check your PHP setup.

What is the perl6 equivalent of #INC, please?

I go
export PERL6LIB="/GitHub/perl6-Units/lib"
and then
echo $PERL6LIB
/GitHub/perl6-Units/lib
But when I run perl6 t/01-basic.t
use v6;
use Test;
plan 3;
lives-ok {
use Units <m>;
ok #Units::UNITS.elems > 0;
ok (0m).defined;
}
done-testing;
I still get an error
===SORRY!===
Could not find Units at line 8 in:
/Users/--me--/.perl6
/usr/local/Cellar/rakudo-star/2018.01/share/perl6/site
/usr/local/Cellar/rakudo-star/2018.01/share/perl6/vendor
/usr/local/Cellar/rakudo-star/2018.01/share/perl6
CompUnit::Repository::AbsolutePath<140707489084448>
CompUnit::Repository::NQP<140707463117264>
CompUnit::Repository::Perl5<140707463117304>
In Perl 5 I would have used print "#INC"; to see what paths are searched for the lib before the error is thrown. Using say flat $*REPO.repo-chain.map(*.loaded); either is before it loads or after it throws the exception.
Any help would be much appreciated - or maybe a hint on what to put in ~/.perl6 as I can't get a symlink to work either.
The error message itself is telling you what the library paths available are. You are failing to print them because you are expecting a run time action ( say ) to take place before a compile time error -- you could print out $*REPO at compile time, but again the exception is already showing you what you wanted.
$ PERL6LIB="/GitHub/perl6-Units/lib" perl6 -e 'BEGIN say $*REPO.repo-chain; use Foo;'
(file#/GitHub/perl6-Units/lib inst#/Users/ugexe/.perl6 inst#/Users/ugexe/.rakudobrew/moar-2018.08/install/share/perl6/site inst#/Users/ugexe/.rakudobrew/moar-2018.08/install/share/perl6/vendor inst#/Users/ugexe/.rakudobrew/moar-2018.08/install/share/perl6 ap# nqp# perl5#)
===SORRY!===
Could not find Foo at line 1 in:
/GitHub/perl6-Units/lib
/Users/ugexe/.perl6
/Users/ugexe/.rakudobrew/moar-2018.08/install/share/perl6/site
/Users/ugexe/.rakudobrew/moar-2018.08/install/share/perl6/vendor
/Users/ugexe/.rakudobrew/moar-2018.08/install/share/perl6
CompUnit::Repository::AbsolutePath<140337382425072>
CompUnit::Repository::NQP<140337350057496>
CompUnit::Repository::Perl5<140337350057536>
You can see /GitHub/perl6-Units/lib is showing up in the available paths, which is unlike your example. I'd question if your shell/env is actually setup correctly.

Ghostscript for PS integrity test: terminate at EOF, return error unless stack is empty

To test the integrity of PostScript files, I'd like to run Ghostscript in the following way:
Return 1 (or other error code) on error
Return 0 (success) at EOF if stack is empty
Return 1 (or other error code) otherwise
I could run gs in the background, and use a timeout to force termination if gs hangs with items left on the stack. Is there an easier solution?
Ghostscript won't hang if you send files as input (unless you write a program which enters an infinite loop or otherwise fails to reach a halting state). Having items on any of the stacks won't cause it to hang.
On the other hand, it won't give you an error if a PostScript program leaves operands on the operand stack (or dictionaries on the dictionary stack, clips on the clip stack or gstates on the graphics state stack). This is because that's not an error, and since PostScript interpreters normally run in a job server loop its not a problem either. Terminating the job returns control to the job server loop which does a save and restore round the total job, thereby clearing up anything left behind.
I'd suggest that if you really want to do this you need to adopt the same approach, you need to write a PostScript program which executes the PostScript program you want to 'test', then checks the operand stack (and other stacks if required) to see if anything is left. Note that you will want to execute the test program in a stopped context, as an error in the course of the program will clearly potentially leave stuff lying around.
Ghostscript returns 0 on a clean exit and a value less than 0 for errors, if I remember correctly. You would need to use signalerror in your test framework in order to raise an error if items are left at the end of a program.
[EDIT]
Anything supplied to Ghostscript on the command line by either -s or -d is defined in systemdict, so if we do -sInputFileName=/test.pdf then we will find in systemdict a key /InputFileName whose value is a string with the contents (/test.pdf). We can use that to pass the filename to our program.
The stopped operator takes an executable array as an argument, and returns either true or false depending on whether an error occurred while executing the array (3rd Edition PLRM, p 697).
So we need to run the program contained in the filename we've been given, and do it in a 'stopped' context. Something like this:
{InputFileName run} stopped
{
(Error occurred\n) print flush
%% Potentially check $error for more information.
}{
(program terminated normally\n) print flush
%% Here you could check the various stacks
} ifelse
The following, based 90% on KenS's answer, is 99% satisfactory:
Program checkIntegrity.ps:
{Script run} stopped
{
(\n===> Integrity test failed: ) print Script print ( has error\n\n) print
handleerror
(ignore this error which only serves to force a return value of 1) /syntaxerror signalerror
}{
% script passed, now check the stack
count dup 0 eq {
pop (\n===> Integrity test passed: ) print Script print ( terminated normally\n\n) print
} {
(\n===> Integrity test failed: ) print Script print ( left ) print
3 string cvs print ( item(s) on stack\n\n) print
Script /syntaxerror signalerror
} ifelse
} ifelse
quit
Execute with
gs -q -sScript=CodeToBeChecked.ps checkIntegrity.ps ; echo $?
For the last 1% of satisfaction I would need a replacement for
(blabla) /syntaxerror signalerror
It forces exit with return code 1, but is very verbous and distracts from the actual error in the checked script that is reported by handleerror. Therefore a cleaner way to exit(1) would be welcome.

mod_perl segmentation fault

HI,
I'm running an apache 2.2.3 on an Oracle64-bit (Red Hat clone) and I'm hitting a brick wall with an issue. I have a program which utilizes MIME::Lite to send mail through sendmail (I apologize, not sure what versions of sendmail or mod_perl I'm running, although I do believe the sendmail portion is irrelevant as you'll see in a moment)
On occasion, apache will segfault (11), and digging deep into the MIME::Lite module, I see it is on the following line:
open SENDMAIL, "|$sendmailcmd" or Carp::croak "open |$sendmailcmd: $!\n"; (this is in MIME::Lite)
Now, one would automatically suspect sendmail, but if I did the same line to use /bin/cat (as shown):
open SENDMAIL, "|/bin/cat"
apache still segfaults.
I attached an strace to the apache processes and see the following:
(when it does NOT crash)
12907 write(2, "SENDMAIL send_by_sendmail 1\n", 28) = 28
12907 write(2, "SENDMAIL /usr/lib/sendmail -t -o"..., 40) = 40
12907 pipe([24, 26]) = 0
12907 pipe([28, 29]) = 0
12907 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x2b4bcbbd75d0) = 13186
Note the "SENDMAIL sent_by_sendmail" are my comments. You can clearly see pipes opening. When it DOES crash, you'll see the following:
10805 write(2, "SENDMAIL send_by_sendmail (for y"..., 40) = 40
10805 --- SIGSEGV (Segmentation fault) # 0 (0) ---
Now notice it never pipes. I've tried GDB and it hasn't really shown me anything.
Finally, I wrote a simple program to run through mod_perl and regular cgi:
print header();
print "test";
open SENDMAIL, "|/bin/cat" or Carp::croak "open |sendmailcmd: $!\n";
print SENDMAIL "foodaddy";
close SENDMAIL;
print "test done <br/>";
Under mod_perl it has successfully crashed.
My analysis is telling me it has to do with it trying to open a file handle, the piping function returns either false or a corrupt file handle.
I also increased the file descriptor limit to 2048, no dice.
Does anyone have any thoughts as to where I should look? Any thoughts?
I appreciate the help
I just spent a long time tracking down a problem that started with identical symptoms. I eventually discovered that Test::More does not play well with mod_perl . Removing this module from my code appears to have solved the problem (so far!). I didn't follow this any deeper, but I suspect that the problem actually lies in Test::Builder.
I managed to treat perhaps only the symptoms, not the cause. I happened to have this issue when used global/package scope variables on the package level, used inside a perl object instance, as soon as I passed them as object properties instead, not as automatic default perl variables scoping, I stopped to experience perl segmentation fault suddenly.