How to debug a perl program starting from a specific line? - perl

Environment: Linux CentOS 7 #HPC
Interface: command interface, no GUI
My PERL scripts have a logic error. It does not go through in a "foreach" loop. I use debugger command below:
perl -d /scripts_location/perlscripts.pl
However, it is run step by step. My scripts have almost thousand lines. Here is my questions:
How to debug my scripts from specific line?
How to figure out the loop cannot be run? And why the loop cannot be run?
Is there any resource to show debugger skills in a whole process?
I searched online. Most of them explain the commands. But few introduce the debug from the very beginning. I mean that first a simple program is given, set breakpoint or other label in the program, check output or trace error, and so on. After viewing websites, I am unable to know how to start debugging using PERL debugger. I used to debugging my program using output at specific lines to check the output is correct or not. However, current logic error cannot be figured out in this way.
Any further suggestion and help would be highly appreciated.

After starting the debugger, you can tell it to continue until it reaches a given line, e.g.
c 124
To figure out why a foreach loop isn't entered, check the loop's list before entering it. You can tell the debugger to evaluate the expression like this:
x #values
if the loop is something like foreach my $value (#values). It will probably tell you
empty array
To discover why the array is emtpy, you can try to "watch" the array
w #values
and then run the script with r. It will stop once any watched value changes.
Use h to view the help.

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.

Set arbitrary breakpoint in debugger

I have been using the perl interactive debugger (basically perl -d script)
I have a script that has quite a lot of modules imported and I need to debug a problem.
What I do is start the debugger and go over lines, stepping into where necessary.
But this is tedious as I need to step into many lines of code and function calls.
Question: Let's say that after going over the lines of code I eventually step into function A::B::C::foo() of some module where is the problem I am debugging.
Is there a way to set a break point in that function in the beginning of the debugging session so that I jump there directly instead of going over the code line by line until I reach there?
I know that I can add a break point in the same file my debugger is currently but how can I add a breakpoint in a line that is outside of the debugger's scope at this point (to some arbitrary file/module that eventually the debugger would have reached)?
Note:
Just to clarify: It is not like A::B::C::foo() is in line X of the script. It is eventually called after going down the call chain of a lot other functions in many modules
You can set a breakpoint to a subroutine with the documented b sub syntax. In this case, just use
b A::B::C::foo
c
You may set a break point by defining file name and then line number
b YourModule.pm:line_number
where line number is inside the module function you want to break at.
You can even put a breakpoint on a sub that hasn't been loaded/defined yet using the postpone option:
b postpone Name::Of::Sub::Yet::To::Be::Created

Is it possible to figure out which if statements are being fufilled in matlab

I have a lot of if statements throughout my code and was wondering if there is anyway in Matlab to see which if statements are being used when I run my code. I know I could put variables throughout my code and see which ones are being triggered, but I was wondering if there is an easier way. Maybe a built in MATLAB function or something.
Thanks
Type profile viewer in the command line of matlab and execute your code from there. There you can see in the profile report how many times each line is called as well as how long it takes executing the line of code.
More information:
http://www.mathworks.nl/help/matlab/ref/profile.html
http://www.mathworks.nl/help/matlab/matlab_prog/profiling-for-improving-performance.html
To answer precesely to your question, there is a command to log every line the execution is going through. And if you're familiar with unix-like platform, it is the same command: echo. See the Matlab help of echo to see how you can use it. For example, echo on all sets echoing on for all function files.
Besides that, I advise you two things better than analysing the output of echoing a whole script:
look at every warning in the code editor, and apply meaningful corrections.
use the profiler of matlab, as stated in the answer from EJG89, it is indeed a powerful tool!

back ticks not working in perl

Got stuck with one problem in our live server.
Have script (perl) which runs almost 15 to 18 hrs a day. it creates 100+ sub process every day . One place it has command (product command which we run in command line solaris box) which is being triggerred with back ticks inside perl code.
It looks like the back ticks command gets skipped or failed randomly.
for eg. if i need to run for 50 customers 2 or 3 gets failed randomly.
I do not see the evidence that the command has been triggerred in anywhere.
since its live server we can't even try making much in code change until we are sure about the problem.
here is the code..
my $comm = "inventory -noX customer1"; #sample command i have given here
my $newLogFile = "To capture command output here we have path whre the file gets created");
my $piddy = `$comm 2>&1 > $newLogFile`;
Is it because of the back ticks it happens I am really not sure :(.
Also tried various analysis like memory/CPU/diskspace/Adding librtld_db.so in LD_LIBRARY_PATH etc....but no luck...Also the perl is in 64 bit ...what else Can i? :(
I suspect you are not checking for errors (and perl doesn't make that easy to do correctly for backticks).
Consider using IPC::System::Simple's capture in place of your backticks/qx.
As its doc says, "If there's an error, it will die with a detailed description of what went wrong."
It shouldn't fail just because of backticks, however because it is spawning a new process, that process may be periodically subject to failure due to system conditions (eg. sysLoad). Backticks are really a "fire and forget" method and should never be used for anything critical in a production environment. As previously suggested, there are far more detailed ways to manage spawning external processes.
If the command's output is being lost due to buffering, you might try turning off buffering, but keep an eye on it for performance degradation (it's usually not significant).
Buffering can be turned off for an entire script by adding this near the top:
$|=1;
When calling external commands, I'm using system of IPC::System::Simple or open3 of IPC::Open3.

have perl debugger not stop at first statement

I'm trying to find a way to start a perl process up under the debugger, but have in just start running automatically without stopping at the first statement and having me enter 'c' to start it. This module is run by a larger system and I need to be able to periodically (based on external conditions) interrupt the program via interrupt signal, examine some data structures and have it continue.
Obviously, I can have the supervising program start my process using "perl -d myProcess", but how to get it to just run without the initial break. Anybody know how to get this to happen?
Much Thanks.
Thanks. That was a big hint. I see several options including "NonStop".
It looks like using the line PERLDB_OPTS="NonStop" perl -d myprog.pl & does the trick. Then I just kill -INT <pid> and fg it to get it up in the debugger. After I 'c' to continue executing and bg it so it will continue.
You can also add this config option to the .perldb file. The format of the config file is a bit unusual and not so well documented, so here goes
DB::parse_options("NonStop=1");
Other useful options:
DB::parse_options("dumpDepth=3");
DB::parse_options("PrintRet=0");
$DB::deep = 1000;