Workflow to debug for a Perl programmer - perl

I am new to Perl and I have the following problem.
I have a log output and I have found where this log output comes from. I mean the subroutine in some module that prints it.
Now e.g. in Java via Eclipse I would use e.g. Call hierarchy and other utilities to see how/when/who calls the method and figure out how to reproduce what I need and debug.
How can I do this in Perl? Via e.g. grep? If I grep e.g. for the module name I get hundrends of lines ranging from use A require A C::B::A B::A C::B::A::some_routine C::B::A::some_other_routine etc.
On top of this I am worried that perhaps the routine I am interested in is not called directly but some script e.g. runs the module that is of interest to me via some obscure (to me due to my ignorance in Perl) manner.
So how would I go debug something in Perl in the most efficient way? What do you Perl gurus suggest for me to do and become more efficient?

Run the program under the Perl debugger:
perl -d scriptname arguments...
Set a breakpoint in the function you care about, and when the program stops at the breakpoint use the T debugger command to display a stack trace, which will show where the function was called from.
From your comments, I'm not sure this actually addresses what you're looking for. Maybe what you want is a cross-reference of the Perl application? See the FAQ How do I cross-reference my Perl programs?

Most of the time getting a stack trace (along with some debugging info) is a good start. One can use standard Carp module to generate stack traces:
use Carp;
print_to_log(Carp::longmess("We're here"));
Or there's an object-oriented module for that as well.

To get a dump of the call stack without modifying any code, you can use the perl command line to run your program under Carp::Always:
perl -MCarp::Always my_program.pl

Related

Perl: list the lines being run

I am debugging big perl program. To minimize debugging I would like only to debug the lines actually run.
Is there a tool which I can run my program under, that will give me a program only containing the lines actually being used (e.g. by commenting out the rest)?
You can use the Perl Debugger (http://perldoc.perl.org/perldebug.html).
Decent beginner's write up: http://www.thegeekstuff.com/2010/05/perl-debugger/
It sounds like you might want a coverage tool, like Devel::Cover, which indicates the lines which are being executed during a run of the code.
For example, where you currently execute your code as
perl yourprog args
instead you run
perl −MDevel::Cover yourprog args
cover
This will generate an HTML report showing the code which is actually executed.

how to read texts on the terminal inside perl script

Is there any way to capture the texts on termianl screen inside a perl script. I know there are some functions like system,exec,backticks but the problem is that they execute commands FROM the script.For ex:- in terminal i write cd/ (or) ls,and after that i run my perl script which will read what was written on termianl screen(in this case, scipt will capture cd/ (or) ls-whichever was given to termianl). I came with one solution that by passing the commands which you wrote on termianl as a command line arguments to the script,but any other way???
Like this maybe:
history | perl -ne 'print $_'
As I understand it, in a situation where you've typed some stuff into a terminal like this:
[tai#littlerobot ~] echo "Hello"
Hello
[tai#littlerobot ~] perl myscript.pl
You want myscript.pl to be able to access the echo "Hello" part, and possibly also the Hello that was that command's output.
Perl does not provide such a feature. No programming language does or can provide such a feature because the process in which your script/program runs has no intrinsic knowledge about what happened in the same terminal before it was run. The only way it could access this text would be if it could ask the currently running terminal, which will have some record of this information (i.e. the scrollback buffer), even if it cannot distinguish between which characters in the text were typed by you, and which are output. However, I know of no terminal that exposes that information via any kind of public API.
So if you want myscript.pl to be able to access that echo "Hello", you'll need to pass it to your script. Piping history to your script (as shown by Mark Setchell in his answer) is one technique. history is a shell built-in, so it has as much knowledge as your shell has (which is not quite the same knowledge as your terminal has). In particular it can give you a list of what commands have been typed in this shell session. However, it cannot tell you about the output generated by those commands. And it cannot tell you about other shell sessions, so doing this in Perl is fairly useless:
my #history = `tcsh -c history`;
The last thing you could try (though it would be incredibly complicated to do) would be to ask the X server (or Windows if running on that operating system) for a screen shot and then attempt to locate which rectangle the current terminal is running in and perform OCR on it. This would be fraught with problems though, such as dealing with overlapping windows.
So, in summary, you cannot do this. It's nothing to do with Perl. You cannot do this in any programming language.

Perl: console / command-line tool for interactive code evaluation and testing

Python offers an interactive interpreter allowing the evaluation of little code snippets by submitting a couple of lines of code to the console. I was wondering if a tool with similar functionality (e.g. including a history accessible with the arrow keys) also exists for Perl?
There seem to be all kinds of solutions out there, but I can't seem to find any good recommendations. I.e. lots of tools are mentioned, but I'm interested in which tools people actually use and why. So, do you have any good recommendations, excluding the standard perl debugging (perl -d -e 1)?
Here are some interesting pages I've had a look at:
a question in the official Perl FAQ
another Stackoverflow question, where the answer mostly is the perl debugger and several links are broken
Perl Console
Perl Shell
perl -d -e 1
Is perfectly suitable, I've been using it for years and years. But if you just can't,
then you can check out Devel::REPL
If your problem with perl -d -e 1 is that it lacks command line history, then you should install Term::ReadLine::Perl which the debugger will use when installed.
Even though this question has plenty of answers, I'll add my two cents on the topic. My approach to the problem is easy if you are a ViM user, but I guess it can be done from other editors as well:
Open your ViM, and type your code. You don't need to save it on any file.
:w !perl for evaluation (:w !COMMAND pipes the buffer to the process obtained by running COMMAND. In this case the mighty perl interpreter!)
Take a look at the output
This approach is good for any interpreted language, not just for Perl.
In the case of Perl it is extremely convenient when you are writing your own modules, since in my experience the perl interpreter will refuse to reload a module (even when loading was attempted and failed). On the minus side, you will loose all your context every time, so if you are doing some heavy or slow operation, you need to save some intermediate results (whilst the perl console approach preserves the previously computed data).
If you just need the evaluation of an expression - which is the other use case for a perl console program - another good alternative is seeing the evaluation out of a perl -e command. It's fast to launch, but you have to deal with escaping (for this thing the $'...' syntax of Bash does the job pretty well.
Just use to get history and arrows:
rlwrap perl -de1

How do I restrict Perl debugger output to lines in my own script?

I'm running the debugger in noninteractive mode, with the output written to a file. I want to print out each line of my Perl script as it executes, but only lines in the script itself. I don't want to see the library code (File::Basename, Exporter::import, etc.) that the script calls. This seems like the sort of thing that should be easy to do, but the documentation for perldebug only discusses limiting the depth for dumping structures. Is what I want possible, and if so, how?
Note that I'm executing my program as follows:
PERLDB_OPTS="LineInfo=temp.txt NonStop=1 AutoTrace=1 frame=2" perl -dS myprog.pl arg0 arg1
By default, Devel::DumpTrace doesn't step into system modules, and you can exercise fine control over what modules the debugger will step into (it's not easy, but it's possible). Something like
DUMPTRACE_FH=temp.txt perl -d:DumpTrace=quiet myprog.pl
would be similar to what you're apparently trying to do.
Devel::DumpTrace also does a lot more processing on each line -- figuring out variable values and including them in the output -- so it may be overkill and run a lot slower than perl -dS ...
(Crikey, that's now two plugs for Devel::DumpTrace this week!)
Are you talking about not wanting to step through functions outside of your own program? For that, you want to use n instead of s.
From perldebug:
s [expr] Single step. Executes until the beginning of another
statement, descending into subroutine calls. If an
expression is supplied that includes function calls, it too
will be single‐stepped.
n [expr] Next. Executes over subroutine calls, until the beginning
of the next statement. If an expression is supplied that
includes function calls, those functions will be executed
with stops before each statement.

How do I daemonize a perl script from within a perl script?

I have a perl script which calls another perl script using backticks. I want to instead call this script and have it daemonize. How do I go about doing this?
edit:
I dont care to communicate back with the process/daemon. I'll most likely just stick it in an sqlite3 table or something.
You refer to backticks, thus I suppose that you want to communicate with the daemon after it's started? Since daemons does not use STDOUT, you will have to think of some other way of passing information to and from it.
The Perl interprocess communication man page (perlipc) has several good examples of this, especially the section "Complete dissociation of child from parent".
The Proc::Daemon contains convenient functions for daemonizing a process.