Debugger not stopping at breakpoints

Help
2012-09-06
2013-05-20
  • I have been using the EPIC Perl debugger in Eclipse for about 9 months now on one machine. I am now installing Eclipse Juno on a new machine (Windows 7 64 bit)  and am experiencing some problems with the debugger.

    Basically, if I set a breakpoint in a file that is in the same directory as the script being debugged, then the debugger stops there. But if I set a breakpoint in a file that is in a different directory, then the debugger does not stop there.

    I have read several posts about debugger problems, and have tried all the proposed fixes, but none of them solved the problem. In particular:

    - I installed PadWalker with 'ppm install PadWalker'.
    - I have upgraded Cwd using cpanp (ppm wouldn't upgrade it).
    - The script being debugged starts with the following statement:
       use lib "../../IIPerlUtils";
       where '../../IIPerlUtils' is the path where the problematic file resides (relative path w.r.t. the script being debugged).
    - I have restarted Eclipse after the above changes.
    - The Perl Include path for the project where the script being debugged resides has the following entries in it:
         C:\Users\desiletsa\Documents\eclipse_workspace\IIPerlUtils
         C:/Users/desiletsa/Documents/eclipse_workspace/IIPerlUtils
       Which are the forward and backslash versions of the directory where the problematic file resides

    I don't know what else to do. Does anyone have other suggestions?

    Thx.

     
  • Oh, forgot to mention. I also edited Cwd.pm to replace

        if (*{$DynaLoader::{boot_DynaLoader}}{CODE}) {

    with:

    if (eval { defined &DynaLoader::boot_DynaLoader; }) {

    in the _win32_cwd() sub.

     
  • Jan Ploski
    Jan Ploski
    2012-09-06

    I'd start by trying to eliminate the "use lib" factor. Does it work when you create a new project with modules in some directory (added to @INC path in project properties) and just "use" these modules from a script? If so, proceed from there and make the working example increasingly complex and similar to your real case until it stops working. Then you'll have it narrowed down to the relevant difference.

    The breakpoint ignored problems occur when the paths reported by the debugged Perl interpreter do not match the paths expected for files by EPIC, even after best efforts at canonicalization. So if you want to go after the root cause, you can try comparing paths displayed in Properties of the file with skipped breakpoints and paths that appear in the "Debugger console (experimental)" (after enabling it in EPIC Preferences) when stepping into that module.

     
  • Thx jploski,

    I tried your suggestion. Here is a very simple recipe for reproducing the bug.

    I created a Perl project in Eclipse called DebuggerIssue.

    The file structure of the project is as follows:

    DebuggerIssue
    |_ reproduce_bug.pl
    |_ PackageInBaseDirectory.pm
    |_ Subdirectory
        |_ PackageInSubDirectory.pm

    Here is the content of each of the files:

    === StartOf: reproduce_bug.pl
    use strict;
    use warnings;

    use PackageInBaseDirectory;
    print PackageInBaseDirectory::hello()."\n";

    use PackageInSubDirectory;
    print PackageInSubDirectory::hello()."\n";
    === EndOf: reproduce_bug.pl

    === StartOf: PackageInBaseDirectory.pm
    use strict;
    use warnings;

    package PackageInBaseDirectory;

    sub hello {
    return "Return value of PackageInBaseDirectory::hello().";
    }

    1;
    === EndOf: PackageInBaseDirectory.pm

    === StartOf: PackageInSubDirectory.pm
    use strict;
    use warnings;

    package PackageInSubDirectory;

    sub hello {
    return "Return value of PackageInSubDirectory::hello().";
    }

    1;
    === StartOf: PackageInSubDirectory.pm

    I put this in the Perl Include Path for the project:

    ./Subdirectory

    I put a break point on the print statements in each of PackageInBaseDirectory::hello() and PackageInSubDirectory::hello().

    When I run the script in the debugger, it stops at the breakpoint in PackageInBaseDirectory::hello(), but not at the one in PackageInSubDirectory::hello().

     
  • Jan Ploski
    Jan Ploski
    2012-09-06

    1. Have you tried adding "Subdirectory" rather than "./Subdirectory" in project's Perl Include Path? (it doesn't matter on my machine, but who knows…)

    2. What path does it show under "Location" when you right-click PackageInSubDirectory.pm and go to Properties?

    3. After enabling "Debugger console (experimental)" in EPIC Preferences, start a debugging session and step into PackageInSubDirectory::hello manually. What paths appear in the debugger console then (debugger console's content is shown in Console view when you click the "perl -d" item in the Debug view)?

     
  • Hi jploski,

    Thanks again.

    Indeed, if I add "Subdirectory" instead of "./Subdirectory" in the project's Perl Include Path, it works. Weird.

    Also, if I comment out all the "use lib" statements in my original program, then the debugger stops at the breakpoints, even for packages that are not in the same directory as the script being run. That's a bit of a pain, because I have LOTS of libs to include, and whenever I run the script outside of Eclipse, I would have to specify all of those as -I options at the command line (which is why I put them as 'use lib' statement in the script itself in the first place).

    Any suggestion on how I could get the debugger to work properly, while keeping the use lib statements?

    THx.

    Alain

     
  • Jan Ploski
    Jan Ploski
    2012-09-06

    I cannot reproduce it under Linux - even with "use lib '../something'" and a distinct working directory for the script it hits the breakpoints in the module. So I suspect some Windows-specific path translation problem, difficult to reproduce and debug for me. In any case, use lib does indeed seem problematic as it influences how the module paths are reported back to EPIC. So I would advise against it, if it is under your control. To avoid the many -I options, maybe you can just set the environment variable PERL5LIB? Or organize your project so that all needed packages live under a common root directory (this is my usual setup - with just one or two entries in the @INC path)?

     
  • I understand the difficulty for you to reproduce the bug. THanks a lot for your insightful answers. It gives me several leads to investigate. If I find a good solution to the problem, I'll report it here.

     
  • After some fiddling, I can confirm that on Windows, with ActiveState, breakpoints work if I specify the include directories using the PERL5LIB environment variable instead of 'use lib' instructions inside the scripts.

    Unfortunately for me, I really do need to employ 'use lib' instructions, because I have two versions of the same system on my machine: the PRODUCTION version which is being used by end users, and the TESTING version, which is a version I am about to put into production, but that I first want to test on the exact same machine where it will eventually run as the production version.

    Obviously those two systems cannot use the same PERL5LIB. So what I do is that I let each script define the include libs as pathes relative to itself, with 'use lib' instructions. That way, I can put the PRODUCTION and TESTING sources and librairies in different parts of the file system, and the include pathes of each system will remain in their respective spaces.

    In the end, I was able to find a way to specify the include pathes with 'use lib', while not confusing the Perl debugger. Here's the code for this below:

    # This needs to be put inside a BEGIN{} block so include pathes will be set before compilation starts
    BEGIN {
        use File::Spec::Functions;
        use File::Basename;
        my $current_script_dir = File::Basename::dirname(File::Spec::Functions::rel2abs($0));
        # Assume that the root of all libraries is two levels up from the directory of the 
        # script being run.
        my $all_libs_root = File::Spec->canonpath("$current_script_dir/../..");
        # Make sure the path is absolute, because relative pathes seem to confuse 
        # the debugger.
        $all_libs_root = File::Spec->rel2abs($all_libs_root);
        # For some reason, the Perl debugger needs the include pathes to use the '/' instead of '\',
        # even if it runs on windows
        $all_libs_root =~ s/\\/\//g;
        my $subdirectories = 
            [
                'Subdirectory1',
                'Subdirectory2',
                etc...
            ];
        foreach my $a_subdirectory (@$subdirectories)  {
            unshift(@INC, "$all_projects_root/$a_subdirectory");    
        }
    };
    

    Again, thanks jploski for your excellent advice. Could never have cracked it without your help.

    Alain

     
  • Jan Ploski
    Jan Ploski
    2012-09-07

    Thanks for posting your solution here. It will be a good future reference for users with similar strict requirements!