Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add attach to local runspace. #875

Merged
merged 11 commits into from Mar 13, 2019

Conversation

adamdriscoll
Copy link
Contributor

Adds support for attaching to a local runspace. This extends the existing support for attaching to a runspace in a remote process. This enables debugging for modules that create additional runspaces such as ThreadJob, PoshRSJob and UnivesalDashboard.

@adamdriscoll
Copy link
Contributor Author

Not seeing this test failure locally. I am seeing other failures that aren't listed in AppVeyor that seem unrelated to my PR.

@@ -21,5 +21,7 @@ public class AttachRequestArguments
public string ProcessId { get; set; }

public int RunspaceId { get; set; }

public string LocalRunspaceId { get; set; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just asking but ... do we really need two different fields for runspace id?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW if it would be more convenient if RunspaceId was a string, we change the type I think. We'd just update the VSCode debug attach code to stringify the runspace id number.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. I can make that change. That's pretty much the reason I added another field was that I didn't wanna mess with RunspaceId's type but I'm happy to adjust that to eliminate the new property.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I was curious how this affects existing launch.json files. Is there something we need to do to ensure that they get upgraded in some way or will a number just work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried this. Seems to still work. It complains in the launch.json that the number should be a string but the attaching still works.

{
runspaceId = attachParams.RunspaceId > 0 ? attachParams.RunspaceId : 1;
}
else if (int.TryParse(attachParams.LocalRunspaceId, out int localRunspaceId))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we could int.TryParse() on a string typed RunspaceId. In the normal "attach" case we'd just set it to "1". Your new debug config would set it to whatever the user picks from the runspace id pick list.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sweet. Works for me. I will update these PRs sometime this weekend.

@@ -417,16 +417,18 @@ protected void Stop()
return;
}

await _editorSession.PowerShellContext.ExecuteScriptStringAsync(
if (attachParams.ProcessId != "current") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't need this if because the outer if tries to parse the ProcessId as an integer (L411):

if (processIdIsSet && int.TryParse(attachParams.ProcessId, out int processId) && (processId > 0))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Updated the PR.

int runspaceId = 1;
if (int.TryParse(attachParams.RunspaceId, out runspaceId))
{
runspaceId = runspaceId > 0 ? runspaceId : 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would maybe factor this into the if

if (!int.TryParse(attachParams.RunspaceId, out runspaceId) || runspaceId <= 0)
{
    Logger.Write(
        LogLevel.Error,
        $"Attach request failed, '{attachParams.RunspaceId}' is an invalid value for the processId.");

    await requestContext.SendErrorAsync(
        "A positive integer must be specified for the RunspaceId field.");

    return;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Copy link
Member

@TylerLeonhardt TylerLeonhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! Just some general comments and questions.

var psCommand = new PSCommand();
psCommand.AddCommand("Get-Runspace");

var runspaces = await editorSession.PowerShellContext.ExecuteCommandAsync<PSObject>(psCommand);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you replace var with the type since this is a tad more complicated than new Blah()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, instead of PSObject you should be able to do System.Management.Automation.Runspaces.Runspace and then you don't have to use dynamic below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

{
var runspaceResponses = new List<GetRunspaceResponse>();

if (this.editorSession.PowerShellContext.LocalPowerShellVersion.Version.Major >= 5)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was Get-Runspace added in 5?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a really good question. I just took that check from the process picker but I'm not sure when Debug-Runspace\Get-Runspace was added. I can try and find out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well looks like that answers our question :)

TylerLeonhardt and others added 3 commits March 11, 2019 14:35
It's neat that we can just commit a suggestion.

Co-Authored-By: adamdriscoll <adamdriscoll@users.noreply.github.com>
Copy link
Member

@TylerLeonhardt TylerLeonhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I'm excited for this code path to see more usage. It's a very nice feature of the extension.

@TylerLeonhardt
Copy link
Member

TylerLeonhardt commented Mar 12, 2019

@adamdriscoll if you couldn't tell already, that test is flaky... I've been meaning to fix it, but I haven't had the time. I will address it as soon as I can.

restarted build.

Copy link
Member

@TylerLeonhardt TylerLeonhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a couple nits really. Basically looks good.

@@ -1222,17 +1222,27 @@ public static string GetDecoratedSymbolName(SymbolReference symbolReference)
}

protected async Task HandleGetRunspaceRequestAsync(
object noParams,
object processId,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have to be object? Or can we turn it into a string?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. Changed to a string.

@@ -1246,6 +1256,12 @@ public static string GetDecoratedSymbolName(SymbolReference symbolReference)
});
}
}

if (processId != null && processId.ToString() != "current") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you do this comparison a couple times, maybe do a:

bool isCurrentProcess = processId != null && processId.ToString() != "current";

and use that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me. Done.

Copy link
Member

@TylerLeonhardt TylerLeonhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Excited to get this in!

@TylerLeonhardt TylerLeonhardt merged commit 13d8f8a into PowerShell:master Mar 13, 2019
TylerLeonhardt pushed a commit to TylerLeonhardt/PowerShellEditorServices that referenced this pull request Mar 18, 2019
* Add attach to local runspace.

* Remove comment.

* Use single runspaceId property.

* Remove unnecessary processId check.

* Factored if.

* Update src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

It's neat that we can just commit a suggestion.

Co-Authored-By: adamdriscoll <adamdriscoll@users.noreply.github.com>

* Use runspace rather than dynamic.

* Accept process ID for GetRunspaceRequest.

* Clean up.
TylerLeonhardt pushed a commit that referenced this pull request Mar 20, 2019
* Add attach to local runspace.

* Remove comment.

* Use single runspaceId property.

* Remove unnecessary processId check.

* Factored if.

* Update src/PowerShellEditorServices.Protocol/Server/DebugAdapter.cs

It's neat that we can just commit a suggestion.

Co-Authored-By: adamdriscoll <adamdriscoll@users.noreply.github.com>

* Use runspace rather than dynamic.

* Accept process ID for GetRunspaceRequest.

* Clean up.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants