richterger / Perl-LanguageServer

Language Server for Perl
Other
224 stars 51 forks source link

vscode debugger works at first, but then... goes blank? #118

Closed tangledhelix closed 2 years ago

tangledhelix commented 2 years ago

I've spent a few hours tonight working on making vscode debug work with my Catalyst application. After a while I arrived at this launch.json, which works... a little bit...

    "version": "0.2.0",
    "configurations": [
        {
            "type": "perl",
            "request": "launch",
            "name": "Perl Debug-local Catalyst server",
            "program": "${workspaceRoot}/gums/script/gums_server.pl",
            "exec": "/Users/dan/perl5/perlbrew/perls/perl-5.35.6/bin/perl",
            "cwd": "${workspaceRoot}/gums/",
            "env": {
                "DBIC_TRACE": 0,
                "CATALYST_DEBUG": 0,
                "PERL_UNBUFFERED": 1
            },
            "stopOnEntry": true,
            "reloadModules": true
        }
    ]

The key turned out to be stopOnEntry - if set true, then when I run the app things are working at first. If I step into or over things, I can watch one step at a time as values change in the variables pane, and so on, just like you would expect.

However, if I then click the "play/continue" button, all of the debug panels go blank. My Catalyst server is still running, and the debugger is still running, but all of the information disappears.

The problem is that Catalyst is a sprawling monster, so stepping into/over things from the start until I get to my actual code is just not an option. The only useful case would be setting breakpoints in my own code.

Are there more prerequisites for this to work that I don't know about? A post I read online suggested that use strict is required. I went through my app and added use strict in the few files that weren't already using it, but that didn't change anything. Would use strict need to be in use in the dozens/hundreds of modules imported by Catalyst?

Here's a screenshot just after I start, and have stepped into/over a few lines of code. You can see that the variables pane and the call stack have contents.

Screen Shot 2021-11-28 at 2 42 18 AM

But if I then press "continue", my program goes on and happily runs, and works, but you can see the variables and call stack panes have been emptied. Nothing ever populates there again unless I start over.

Screen Shot 2021-11-28 at 2 43 14 AM

And this is only if stopOnEntry is true. If that's set to false, then I never see variables/call stack.

tangledhelix commented 2 years ago

I have some additional information to add, though I don't understand what it means exactly.

I stepped through the code in VScode until I ran into this error:

Could not load source '(eval 240)[/Users/dan/perl5/perlbrew/perls/perl-5.35.6/lib/site_perl/5.35.6/Eval/Closure.pm:149]': Unknown perlmethod _dapreq_source at /Users/dan/perl5/perlbrew/perls/perl-5.35.6/lib/site_perl/5.35.6/Perl/LanguageServer.pm line 286.
.

Now knowing I should focus on the first call to Eval::Closure, I next loaded the code in the CLI debugger (perl -d) and stepped until the first time I saw Eval::Closure. That was here:

Moose::Util::TypeConstraints::find_type_constraint(/Users/dan/perl5/perlbrew/perls/perl-5.35.6/lib/site_perl/5.35.6/darwin-2level/Moose/Util/TypeConstraints.pm:302):
302:            return unless $REGISTRY->has_type_constraint($type);
  DB<1>
Moose::Meta::TypeConstraint::Registry::has_type_constraint(/Users/dan/perl5/perlbrew/perls/perl-5.35.6/lib/site_perl/5.35.6/darwin-2level/Moose/Meta/TypeConstraint/Registry.pm:34):
34:     my ($self, $type_name) = @_;
  DB<1>
Moose::Meta::TypeConstraint::Registry::has_type_constraint(/Users/dan/perl5/perlbrew/perls/perl-5.35.6/lib/site_perl/5.35.6/darwin-2level/Moose/Meta/TypeConstraint/Registry.pm:35):
35:     ($type_name and exists $self->type_constraints->{$type_name}) ? 1 : 0
  DB<1>
Eval::Closure::Sandbox_39::CODE(0x127322660)((eval 45)[/Users/dan/perl5/perlbrew/perls/perl-5.35.6/lib/site_perl/5.35.6/Eval/Closure.pm:149]:4):
4:  if (@_ > 1) {
  DB<1>
Eval::Closure::Sandbox_39::CODE(0x127322660)((eval 45)[/Users/dan/perl5/perlbrew/perls/perl-5.35.6/lib/site_perl/5.35.6/Eval/Closure.pm:149]:7):
7:  $_[0]->{"type_constraints"};
  DB<1>

Eval::Closure's purpose is to handle dynamic code generation via string evals. So my assumption is that the language server isn't able to handle the case where dynamic code generation is going on?

Any ideas, or is this a dead end? I'm not sure whether I should keep chasing this...

phimmi commented 2 years ago

I'm not sure what you are exactly trying to do, so i try to sum it up what you are expecting.

You have started your server with the debugger. It is running properly and you can do whatever you want to do, but you want to see live variable changes on the run. This is not possible.

You have to place breakpoints where you wanna inspect the programm and can now step forward, step into methods, step out of a method block and so on. My workflow is setting multiple breakpoints and have a look what changed in between. When i don't know what exactly happened, I am stepping thru step by step, line by line.

tangledhelix commented 2 years ago

Using breakpoints is working, but only if I set one in code ($DB::single=1;). Using the breakpoints in the gutter doesn't work. I'll just have to get accustomed to that.