How to cause "Unable to flush stdout: Broken pipe" in Perl? [duplicate] - runtime-error

After upgrading to Perl 5.24.4 we repeatedly get this error in logs (without pointing the filename and line number):
Unable to flush stdout: Broken pipe
We have no idea what causes this error.
Is there any advice how to understand the cause of the error?

The error comes from perl.c, line 595:
PerlIO_printf(PerlIO_stderr(), "Unable to flush stdout: %s",
Strerror(errno));
This line is part of perl_destruct, which is called to shut down the perl interpreter at the end of the program.
As part of the global shutdown procedure, all still open filehandles are flushed (i.e. all buffered output is written out). The comment above says:
/* Need to flush since END blocks can produce output */
/* flush stdout separately, since we can identify it */
The error message is not listed in perldoc perldiag, which is arguably a documentation bug. It was probably overlooked because it's not a real warn or die call, it's effectively just print STDERR $message. It's not associated with a file name or line number because it only happens after your program stops running (i.e. after a call to exit or because execution fell off the end of the main script).

This is very general advice, but
use Carp::Always;
at the top of the script, or running with
perl -MCarp::Always the_script.pl arg1 arg2 ...
will get Perl to produce stack traces with every warning and error.

Broken pipe is the error string associated with system error EPIPE. One receives this error when writing to a closed pipe. Writing to a closed pipe usally results in the process being killed by a SIGPIPE, so it means the behaviour of SIGPIPE was changed from its default.
$ perl -e'
$SIG{PIPE} = "IGNORE";
print "foo\n"
or die("Can\x27t write to STDOUT: $!\n");
sleep(2);
close(STDOUT)
or die("Unable to flush STDOUT: $!\n");
' | perl -e'sleep(1)'
Unable to flush STDOUT: Broken pipe
As melpomene discovered, the error is automatically output if you write to a broken pipe in an END block.
$ perl -e'
$SIG{PIPE} = "IGNORE";
sleep(2);
END { print "foo\n"; }
' | perl -e'sleep(1)'
Unable to flush stdout: Broken pipe
This isn't necessarily a problem, although it could be a sign that a process is exiting prematurely.

Related

Trimmomatic-0.39 error message "Unknown option -baseout ..."

I have used Trimmomatic-0.39 few times already for trimming some sequencing data. This time I tried the option -baseout as stated in the manual but it does not recognise it as a valid option and the command does not run. If I run the command, as I usually I do with all the output files listed, it works though.
I type in the command line:
java -jar trimmomatic-0.39.jar PE -phred33 -trimlog trimmed_file18_log.log -baseout file18.fastq.gz file18-R1.fastq.gz file18-R2.fastq.gz ILLUMINACLIP:NexteraPE-PE.fa:2:30:10 MAXINFO:25:0.2 MINLEN:20
What I get back is:
Unknown option -baseout file18.fastq.gz
Usage:
PE [-version] [-threads <threads>] [-phred33|-phred64] [-trimlog <trimLogFile>] [-summary <statsSummaryFile>] [-quiet] [-validatePairs] [-basein <inputBase> | <inputFile1> <inputFile2>] [-baseout <outputBase> | <outputFile1P> <outputFile1U> <outputFile2P> <outputFile2U>] <trimmer1>...
or: .....
I get back the same error message even if I move the '-baseout file18.fastq.gz' option after '...jar PE' and before the list of all the other options.

Issue in executing a batch file using PeopleCode in Application engine program

I want to execute a batch file using People code in Application Engine Program. But The program have an issue returning Exec code as a non zero value (Value - 1).
Below is people code snippet below.
Global File &FileLog;
Global string &LogFileName, &Servername, &commandline;
Local string &Footer;
If &Servername = "PSNT" Then
&ScriptName = "D: && D:\psoft\PT854\appserv\prcs\RNBatchFile.bat";
End-If;
&commandline = &ScriptName;
/* Need to commit work or Exec will fail */
CommitWork();
&ExitCode = Exec("cmd.exe /c " | &commandline, %Exec_Synchronous + %FilePath_Absolute);
If &ExitCode <> 0 Then
MessageBox(0, "", 0, 0, ("Batch File Call Failed! Exit code returned by script was " | &ExitCode));
End-If;
Any help how to resolve this issue.
Best bet is to do a trace of the execution.
Thoughts:
Can you log on the the process scheduler you are running this on and execute the script OK?
Is the AE being scheduled or called at run-time?
You should not need to change directory as you are using a fully qualified path to the script.
you should not need to call "cmd /c" as this will create an additional shell for you application to run within, making debuging harder, etc.
Run a trace, and drop us the output. :) HTH
What about changing the working directory to D: inside of the script instead? You are invoking two commands and I'm wondering what the shell is returning to exec. I'm assuming you wrote your script to give the appropriate return code and that isn't the problem.
I couldn't tell from the question text, but are you looking for a negative result, such as -1? I think return codes are usually positive. 0 for success, some other positive number for failure. Negative numbers may be acceptable, but am wondering if Exec doesn't like negative numbers?
Perhaps the PeopleCode ChDir function still works as an alternative to two commands in one line? I haven't tried it for a LONG time.
Another alternative that gives you significant control over the process is to use java.lang.Runtime.exec from PeopleCode: http://jjmpsj.blogspot.com/2010/02/exec-processes-while-controlling-stdin.html.

How do I break out of an R command

I'm simply trying to break out of an R session when I've accidentally entered an incorrect command. Consider this captured text from the the R session:
json2["]
+ ""
+ "
Error: unexpected string constant in:
"""
""
I accidentally typed json["] and the R interpreter sees this as an incomplete command, and it then cycles me through the line continuation prompt, which is a plus '+" symbol, which is not what I want or need.
I then have to try and complete this invalid command to regain control of the console. What I want is a set of keystrokes to break out of this process, similar to a ctrl-c in a terminal session.

Iterating through !DumpHeap output to read value at memory offset

I'm trying to come up with a WinDbg command line expression that takes the output of the !DumpHeap command and for each address, reads a 64-bit value from offset 0x08 after the address. I think this is possible (not sure about it) but every attempt I made so far fails with some error.
I searched a lot but most WinDbg articles show simple examples which I can try but my attempts fail.
I have a process dump of an ASP.NET worker process. The process has some memory growth but there's no clear offender so I'm trying to list a number of objects that appear many times in memory. I'm using sos.dll for the managed debugging WinDbg extensions.
Here's what I'm trying to do
.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{r #$t0=poi(myaddress+0x8);!do #$t0;.echo ************* myaddress}
Note, that the above command must be on a single line - I only added a line break for better readability here.
For the above line, WinDbg prints this error: Couldn't resolve error at 'myaddress+0x8);!do #$t0;.echo ************* 00000001003cb870'.
I'm trying to iterate through all addresses returned by !DumpHeap - each address should go into the myaddress variable. Then, for each address, I'm trying to set the $t0 user register to the value read from myaddress+0x8. The !do (!DumpObject) command would then dump the object at that address.
If I run only (again, on one line in WinDbg):
.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{!do myaddress;.echo ************* myaddress}
I get a list of object dumps but this is one level higher than what I need. I want to drill down one level deeper and dump a particular member of these top-level objects that I'm iterating through.
Is this possible or am I on the wrong track with this?
After further searching, I found that I was using the wrong syntax. According to question and to MSDN, variable names must be surrounded by spaces or must be enclosed in ${...} to work. After I used the ${} enclosure, my script started working.
For future reference, here's how to run the script (keep it on one line in WinDbg):
.foreach(myaddress {!dumpheap -short -mt 000007fe998adea8})
{r #$t0=poi(${myaddress}+0x8);!do #$t0;.echo ************* myaddress}
yes you need space around the aliases
.foreach ( place { .shell -ci "!DumpHeap -stat" sed 1,3d | awk "{print
$1 }" } ) { .foreach (plays { !DumpHeap -short -mt place } ) { r $t0 =
poi( plays + 8 ) ; !do #$t0 ; .echo
========================================= } }

OCaml: unexpected exception with Unix.getlogin when stdin redirected

I found out the next issue in this simple code:
let () =
print_endline "Hello";
print_endline (Unix.getlogin ())
Running in the normal case, with ./a.out gives:
Hello
ricardo
But running like ./a.out </dev/null makes Unix.getlogin fail:
Hello
Fatal error: exception Unix.Unix_error(20, "getlogin", "")
Any idea why this happens?
Redirecting the input of a program overrides its controlling terminal. Without a controlling terminal, there is no login to be found:
$ tty
/dev/pts/2
$ tty < /dev/null
not a tty
You can, however, still find a user's name (perhaps) by getting the user's id (getuid) and looking up his passwd entry (related docs) (getpwuid), then finding his username in it.
Depending on your application:
if you don't really care about the value returned by "getlogin", you can do something like:
try
Unix.getlogin ()
with _ -> Sys.getenv "USER"
you will probably get something better than getuid, since it will also work for programs with Set-User-ID flags (sudo/su).
if you really care about the value returned by "getlogin", i.e. you really want to know who is logged in, you should just fail when getlogin fails. Any other solution will give you only an approximation of the correct result.

Resources