richterger / Perl-LanguageServer

Language Server for Perl
Other
222 stars 53 forks source link

`Could not load source` even though in current working directory and @INC #100

Closed nametable closed 3 years ago

nametable commented 3 years ago

I am trying to figure out why my source code is not being found by the debugger. Either I am making a mistake or there is a bug in the debugger.

My directory structure looks like so

. (/home/logan/Documents/testing/debug-test)
├── Lib
│   └── TestLib.pm
└── main.pl

main.pl

use strict;
print "Hello World from main.pl\n";
use Cwd qw(cwd);
print "cwd=" . cwd . "\n";
require 'Lib/TestLib.pm';
TestLib::doStuff();

TestLib.pm

package TestLib;
sub doStuff {
    print "I am doing stuff\n";
}
1;

.vscode/settings.json

{
    "perl.perlInc": ["./"]
}

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "perl",
            "request": "launch",
            "name": "Perl-Debug",
            "program": "${workspaceFolder}/${relativeFile}",
            "stopOnEntry": true,
            "reloadModules": true,
            "cwd": "/home/logan/Documents/testing/debug-test"
        }
    ]
}

When I start the Perl Debugger in VSCode, it starts as usual from the top of main.pl but when I step into TestLib::doStuff(); I get brought to a new tab named TestLib.pm which says:

Could not load source 'Lib/TestLib.pm': Unknow perlmethod _dapreq_source at /usr/share/perl5/site_perl/Perl/LanguageServer.pm line 222.
.

This result does not make sense to me since the launch cwd is specified and the perl.perlInc path is set to include ./. If I continue the execution, it finishes and outputs what is expected:

Hello World from main.pl
cwd=/home/logan/Documents/testing/debug-test
I am doing stuff

There must be some sort of path issue. Does someone know if this is a configuration issue, or a bug in the extension?

dseynhae commented 3 years ago

The local directory has been removed from the search path in Perl 5.26, for security purposes. Although I can reproduce the problem as described (Using Perl5.30.3), the problem goes away if we use the recommended approach to find information in the same directory as the Perl program (FindBin):

main.pl

use strict;
print "Hello World from main.pl\n";
use Cwd qw(cwd);
print "cwd=" . cwd . "\n";
use FindBin;
use lib "$FindBin::Bin";
require 'Lib/TestLib.pm';
TestLib::doStuff();

With this code, everything works as expected (including the step into for the TestLib::doStuff(); You don't have to remove theperl.perlInc` setting, but I wouldn't include the "local" directory in there, the Perl coding style guidelines have recommended against this for quite a long time...

I don't expect Perl::LanguageServer to support the original syntax, but it is a bug. However, as a developer, I would recommend "wont_fix".

hoehrmann commented 3 years ago

It seems the module simply cannot handle relative paths in %INC. Struggled earlier today with a launch.json configuration that had env: "PERL5OPT=-Ilib ..." and could not find files either, but using absolute paths made it work in the debugger.

richterger commented 3 years ago

It is not defined what the current working directory is, at the start of a perl program. So Perl::LanguageServer makes no assumtion about it. To solve your problem, you can set the directory via cwd configurationm parameter during debugging. Which you already did, but it is is broken in 2.2 and will be fixed in 2.3. Even better is to set the perl include path. In your settings.json do something like:

    "perl.perlInc": [
        "/path/a/lib",
        "/path/b/lib",
        "/path/c/lib",
    ],

Include path works for syntax check and inside of debugger. perl.perlInc should be an absolute path.

cwd parameter is fixed in af895ae91ae825aef363125ad4b87ccabb4b020f

peterdragon commented 1 year ago

Adding this just before an old CGI script's main block and after the other 'use' statements made it work for me:

use FindBin;
use lib "$FindBin::Bin/..";

This script is in a sub-directory below the code root directory hence /.. If I put these lines up above the other use lib and use Module statements, then it didn't work. Below them and it did. I could not figure out why.

I am leaving this comment in case anyone else comes across this and is looking for a solution.