debugging on stdout

M

mike

I have a perl script which talks to mplayer and stepping through it in
emacs' cperl-db it executes flawlessly; but running "./script video" it
does everything except one crucial step and I'm having a hard time
visualizing what could be the matter.

so is there a way to invoke the perl script such as can be done in bash or
csh (csh -xvf ./script.csh) which would allow me to see what's going on at
full speed?

thanks.

--
 
T

Tim Greer

mike said:
I have a perl script which talks to mplayer and stepping through it in
emacs' cperl-db it executes flawlessly; but running "./script video"
it does everything except one crucial step and I'm having a hard time
visualizing what could be the matter.

so is there a way to invoke the perl script such as can be done in
bash or csh (csh -xvf ./script.csh) which would allow me to see what's
going on at full speed?

thanks.

You're going to need to post the relevant code, and provide some details
about the issue, instead of just posting an example of how you run it.
Also, what is the crucial step it's missing? What are you trying to
view/see what's "going on" (what is that?)
 
M

mike

You're going to need to post the relevant code, and provide some details
about the issue, instead of just posting an example of how you run it.
Also, what is the crucial step it's missing? What are you trying to
view/see what's "going on" (what is that?)


$video = $ARGV[0];
$vid_resume = vid_position_file($video);
if (-e $vid_resume) {
$pid = open2(*reader, *writer, "gmplayer-bin -slave -quiet -ss `cat $vid_resume` $video");


$vid_resume returns a valid filename (with valid contents, in this case
"255.1" and nothing more) and its contents are meant to skip to a specific
position in the video when it starts playing.

a) in emacs cperl-db buffer, I load "./script.pl /path/to/video/x" then
"n" line by line and it kicks off mplayer running $video and advanced to
position $vid_resume (iow everything as I expect).

b) "% ./script.pl /path/to/video/x" brings up mplayer stopped, with $video
loaded (I hit "play" and the expected video is there and running, and
incidentally starts at time 0).

so two scenarios, same script, same video, same $vid_resume file but
different outcomes.

I looked through some of what Ben refers to but tbh I'm going in circles
and aren't getting any closer to understanding what's the matter.

ideally (in b)) I'd like to see what mplayer is saying (I removed "-quiet"
but ostensibly because of how it's being run its output seems lost since I
don't see it in the terminal window).


--
 
M

mike

thanks for the help and suggestions.

This feels like a race condition of some sort, but I can't see where it
might be. What does your script do next? Can you use ps to examine what
arguments actually get passed to the gmplayer-bin process? What happens
if you take the temporary file out of the equation and just supply a
literal string to mplayer? What happens if you use ordinary mplayer
rather than gmplayer-bin? Can you give us a minimal *complete* script
that reliably fails on your machine? Is there anything else different
between the two environments: different environment vars, different
shells, &c.? Does the program still succeed if you single-step in the
debugger (run it with perl -d) rather than using Emacs?


$video = $ARGV[0];
$vid_resume = vid_position_file($video);
if (-e $vid_resume) {
$pid = open2(*reader, *writer, "gmplayer-bin -slave -quiet -ss `cat $vid_resume` $video") || die "Unable to open $1: $!";

--> what follows:

unlink $vid_resume;
}
# else {
# $pid = open2(*reader, *writer, "gmplayer-bin -slave -quiet $video") || die "Unable to open $1: $!";
# }
# new position will be recorded here:
open(POS_FH, "> $vid_resume") || die "Unable to open $1: $!";
}
## otherwise bring up mplayer unloaded:
#else {
# $pid = open2(*reader, *writer, 'gmplayer-bin -slave -quiet') || die "Unable to open $1: $!";
#}

clear_mplayer();
 
M

mike

I found the problem if you want to skip reading the rest.

that "clear_mplayer()" is not supposed to be by itself (it's not needed
for the else in if/else since there's no "Starting..." to chk for in
unloaded mplayer).

unlink $vid_resume;
}
# else {
# $pid = open2(*reader, *writer, "gmplayer-bin -slave -quiet $video") || die "Unable to open $1: $!";
# }
--> clear_mplayer();
# new position will be recorded here:
open(POS_FH, "> $vid_resume") || die "Unable to open $1: $!";
}

--> is where it was originally.


but in messing around I had those lines reversed:

# new position will be recorded here:
open(POS_FH, "> $vid_resume") || die "Unable to open $1: $!";
--> clear_mplayer();


for some reason 'open POS_FH' appears to be overwriting $vid_resume (with
its -ss value), even though it follows two instructions - unlink (which
isn't causing the problem because I tried it commented) and the cat in
open2. so open2(... -ss ) is reading an empty file.

when I put the lines back where they were in an earlier incarnation, the
sleep in clear_mplayer ostensibly ensured 'open POS_FH' hadn't written a
new $vid_resume before cat read from it. and the script runs from cmd
line same as it does stepping through in cperl-db.

thanks - I probably never would've noticed this without posting.




thanks for the help and suggestions.

This feels like a race condition of some sort, but I can't see where it
might be. What does your script do next? Can you use ps to examine what
arguments actually get passed to the gmplayer-bin process? What happens
if you take the temporary file out of the equation and just supply a
literal string to mplayer? What happens if you use ordinary mplayer
rather than gmplayer-bin? Can you give us a minimal *complete* script
that reliably fails on your machine? Is there anything else different
between the two environments: different environment vars, different
shells, &c.? Does the program still succeed if you single-step in the
debugger (run it with perl -d) rather than using Emacs?


$video = $ARGV[0];
$vid_resume = vid_position_file($video);
if (-e $vid_resume) {
$pid = open2(*reader, *writer, "gmplayer-bin -slave -quiet -ss `cat $vid_resume` $video") || die "Unable to open $1: $!";

--> what follows:

unlink $vid_resume;
}
# else {
# $pid = open2(*reader, *writer, "gmplayer-bin -slave -quiet $video") || die "Unable to open $1: $!";
# }
# new position will be recorded here:
open(POS_FH, "> $vid_resume") || die "Unable to open $1: $!";
}
## otherwise bring up mplayer unloaded:
#else {
# $pid = open2(*reader, *writer, 'gmplayer-bin -slave -quiet') || die "Unable to open $1: $!";
#}

clear_mplayer();

.
.
.

sub clear_mplayer {

# ps'ing too fast is missing the "L" ("pages locked in memory"):
sleep 5;

my $video_pid = $pid; $video_pid++;
my $running = `/bin/ps ax`;

if ($running =~ /$video_pid\s+pts\/[0-9]+\s+(S|R)?L/) {
writer->autoflush();
while (! /Starting playback/) {
$_ = <reader>;
}
return 1;
}
else {
return 0;
}
}

-------------

1. once that sequence finishes the prog goes onto to other tasks and
everything from this point on works as expected

2. the rest of the if/else is only commented while I've been looking at
this problem (ensure either invocation uses the same one)

3. the problem isn't unlink - I ran with it commented and no change

4. I don't know what "writer->autoflush();" does but it was in the code I
lifted from a web page so left it in (in or out doesn't seem to impact
this -ss problem)

5. mplayer whether started with a vid arg or not appears to start with two
consecutive pids where the second indicates that a video is loaded or
running - to guarantee I can find mplayer's responses to my queries I
throw away everything up to "Starting..."; to guarantee I'll find
"Starting..." I don't look for it until the "L" in ps shows up.

-------------


wrt some of your easier suggestions:

- I tried plain mplayer, replacing cat with the pathname, added path to
g/mplayer bins and at best the video comes up running but ostensibly
ignoring -ss and at worst just comes up with video loaded but not
running.

- I ordinarily use csh but tried bash and sh, same behavior.

- I did notice a couple times in the past couple days that a specific
invocation repeated would seem to start ok (don't recall if it was using
-ss) and at other times came up with the video stopped; I thought "that
can't be, I must've not been paying attn to how I started it."

so there must be something to this race condition thing; I don't know
anything about the open2 alternative you mentioned but will see if I can
manage using that instead and see what happens.


--

--
 
T

Tim Greer

mike said:
when I put the lines back where they were in an earlier incarnation,
the sleep in clear_mplayer ostensibly ensured 'open POS_FH' hadn't
written a new $vid_resume before cat read from it.  and the script
runs from cmd line same as it does stepping through in cperl-db.

Sorry I didn't read the entire thread, but I'm curious, what is the
specific purpose of sleep? Do you want to actually wait for something
specific, such as allowing time for something to complete (hopefully),
or for other reasons? If you want to ensure something completed, I'd
check the position against the size of the file (or data) remaining and
try and track how much has been read/output, and once it's complete
(once it's sent all of its data), then close/clear. If you mean
something else, then I might just have to read the thread to make a
better suggestion (even for that previous one, really).
 
T

Tim McDaniel

I would avoid using Open2 directly in favour of IPC::Run, which has a
much cleaner interface and is more portable to systems like Win32.

One review says <http://cpanratings.perl.org/dist/IPC-Run>

In words of the author of IPC::Run
I would personally recommend IPC::Cmd rather than IPC::Run right now.
It seems more stable and well-supported.
It's not obsolete -- still works for many people, even with test
failures -- but IPC::Cmd seems to be more actively maintained.

My review:
It works well and is easy to use but I do not like its interface.

Roberto - 2007-01-31 06:48:19

Is there a reason to go for IPC::Run instead of IPC::Cmd?
 
M

mike

I appreciate your time and great perl tips, thanks.

I will ask you again: why on earth are you keeping the offset in a file
at all? Just keep it in a variable.

unless you mean keep it in a var only while the script is running, I have
stacks of instructional videos and using respectively named text files
allows me to have mplayer automatically seek to the position I last left
off at when I reload a vid that has such a file (and obv if it doesn't my
script creates one for it). there's a 15s loop which repeatedly updates
that file w/current vid position while the video remains loaded or
running.

to give credit, I got the idea from a very handy mplayer-resume php script
where I learned one can 'talk' to mplayer. but after using his script
briefly felt it was too limited so made my own.

You shouldn't need to mess about with ps: just read from mplayer's
output until it gets to "Starting...".


obv I'm just sort of fumbling through this but how I have it now is, my
script needs both video filename and current time position and to get
either of them (at various places) I do:

$video = vid_filename_query();
and/or
print SEEK_FH vid_position_query();


# -------------------
# ask mplayer current vid's filename and return it (never includes its path):
sub vid_filename_query {
writer->print("pausing_keep get_file_name\n");
$_ = <reader>;
/ANS_FILENAME=\'(.*)\'/;
return $1;
}

# ask mplayer where current vid is positioned (return val is "seconds"):
sub vid_position_query {
writer->print("pausing_keep get_time_pos\n");
$_ = <reader>;
/ANS_TIME_POSITION=(.*)/;
return $1;
}
# -------------------


"pages locked in memory" for mplayer's pid (or "Starting..." for that
matter) appear only once a video is loaded. until that happens mplayer
ignores or fails to respond to the specific things I ask it (obv "get_*"
would be meaningless if no video is loaded; and mplayer may be accepting a
meaningless instruction and simply dropping it, I don't know).

but as you can see by my writer/<reader> combos, if I try one when no
video is loaded, and mplayer is not going to respond, then <reader> hangs
waiting for something that isn't coming.

so I test for ps "L" (coincidental to "Starting...") to inform my script
whether or not mplayer is going to respond before sending it an
instruction (and since ps "L" is valid whether vid is running or just
loaded but stopped, I only need to do this pid chk once/video).

so whether or not I just use <reader> to scan up to "Starting...", I can't
know it won't hang not finding it if I don't first test for ps "L". imm :)


--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top