vscode-shell-command icon indicating copy to clipboard operation
vscode-shell-command copied to clipboard

Enable dependent input variable usage for compound launch configurations

Open MarcelKoller opened this issue 1 year ago • 14 comments

Is there any way to use dependent input variables in a compound launch config? I'll try to explain the issue with a simplified launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "gdb",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/bin/${input:selectApplication}",
            "cwd": "${workspaceFolder}/build/bin/",
            "MIMode": "gdb",
        },
        {
            "name": "python",
            "type": "debugpy",
            "request": "launch",
            "program": "${workspaceFolder}/build/python/${input:selectPython}",
            "args": [
                "${input:pythonArgs}",
            ],
        },
    ],
    "compounds": [
        {
            "name": "Python & gdb",
            "configurations": [
                "gdb",
                "python"
            ]
        }
    ],
    "inputs": [
        {
            "id": "selectApplication",
            "type": "command",
            "command": "shellCommand.execute",
            "args": {
                "command": "find . -type f -executable | grep -v test$ | sort -f",
                "cwd": "${workspaceFolder}/build/bin",
                "description": "Select the app to debug"
            },
        },
        {
            "id": "selectPython",
            "type": "command",
            "command": "shellCommand.execute",
            "args": {
                "command": "find . -type f -executable | sort -f",
                "cwd": "${workspaceFolder}/build/python",
                "description": "Select the python target to debug"
            },
        },
        {
            "id": "pythonArgs",
            "type": "command",
            "command": "shellCommand.execute",
            "args": {
                "command": "${input:selectPython} --someArgs",
                "cwd": "${workspaceFolder}/build/python",
                "description": "Select something"
            },
        },
    ]
}

When I launch Python & gdb I get promted (in this order) selectPython, selectApplication and finally pythonArgs which doesn't offer to select anything because ${input:selectPython} seems to be resolved to "nothing". The standalone python launch target works. So it seems like the value of ${input:selectPython} is "forgotten" because there was a switch to another launch configuration - at least that's my assumption. Any ideas how this could be fixed or worked around?

MarcelKoller avatar Aug 01 '24 14:08 MarcelKoller

I think this should work. This is effectively "Dependent Input Variables Usage example:" from the readme.

MarcelRobitaille avatar Aug 01 '24 17:08 MarcelRobitaille

That's what I thought, too. Really strange! It seems like now all of a sudden it is indeed working. So, I guess it was just some strange hiccup... Edit: Now it doesn't work anymore (without any change). Can there be a race condition or something else making this unstable?

MarcelKoller avatar Aug 02 '24 10:08 MarcelKoller

Can you please make a reproducible example that does not require a folder of python binaries? Maybe just echo the input instead of executing it?

MarcelRobitaille avatar Aug 03 '24 07:08 MarcelRobitaille

I tried, but sadly I could not yet manage to create another setup where the compound configuration starts with the user input for "python", is "interrupted" by "gdb" and then continues with "python". I guess that is why I also do not see any issue with that. AFAIK you cannot set the order of the launch targets as they are just started in parallel. With my original configuration, "python" always starts first and that seems to sometimes be a problem for the resolution of the input variables. As I said, I suspect some sort of race condition because of the parallel execution. Any idea how I can create a reproducible setup for that?

MarcelKoller avatar Aug 05 '24 06:08 MarcelKoller

I have a suspicion. Could you please check if it's reproducible on my branch test_95?

MarcelRobitaille avatar Sep 23 '24 21:09 MarcelRobitaille

If this still occurs in the next release, please re-open this issue.

MarcelRobitaille avatar Sep 30 '24 08:09 MarcelRobitaille

Please try 1.12.0

MarcelRobitaille avatar Sep 30 '24 20:09 MarcelRobitaille

Hi @MarcelRobitaille! Thanks for the update! Sorry for the late response - I was on vacation. I tried 1.12.4 and now it is at least easier to reproduce. I still get prompted in the same order as in my original post. Now, if I wait too long (~1s) after the penultimate dropdown selection (selectApplication), I get the error The command for input 'pythonArgs' returned empty result. If I select faster, it can be resolved and everything works fine.

Edit: Seems like I don't have the permission to re-open this issue.

MarcelKoller avatar Oct 07 '24 11:10 MarcelKoller

That's very strange that it depends on timing. Is it possible that the command outputs nothing?

MarcelRobitaille avatar Oct 07 '24 11:10 MarcelRobitaille

So indeed, the issue seems to be that ${input:selectPython} in pythonArgs seems to be resolved to an empty string, even though it was previously set after launching the python configuration. When I replace ${input:selectPython} in pythonArgs with an empty string, I get the same error. And when I replace it with the hard-coded value that would be applied after launching the python configuration it works even after a longer pause. So, to me it looks like it's really a timing problem or the "context switches" by alternately getting inputs for two configurations causes that the input is no longer resolvable.

MarcelKoller avatar Oct 07 '24 12:10 MarcelKoller

I don't see how there could possibly be a race condition here. The empty result is checked immediately after the command is executed, before any UI prompt stuff.

Can you please tell me the order in which the inputs are prompted, what you select each time, and how long you wait each time?

I just checked your profile because I noticed you're also Marcel. We're pretty close. I'm in Augsburg :smile:

MarcelRobitaille avatar Oct 11 '24 19:10 MarcelRobitaille

Oh! Then we are indeed close! Been to Augsburg a couple of months ago. It seems pretty nice there 😄

Here is the updated configuration. Actually I missed debugFlag (which was only recently added in our setup) which is where the error comes up.

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "gdb",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/bin/${input:selectApplication}",
            "cwd": "${workspaceFolder}/build/bin/",
            "MIMode": "gdb",
        },
        {
            "name": "python",
            "type": "debugpy",
            "request": "launch",
            "program": "${workspaceFolder}/build/python/${input:selectPython}",
            "args": [
                "${input:debugFlag}",
                "${input:pythonArgs}",
            ],
        },
    ],
    "compounds": [
        {
            "name": "Python & gdb",
            "configurations": [
                "gdb",
                "python"
            ]
        }
    ],
    "inputs": [
        {
            "id": "selectApplication",
            "type": "command",
            "command": "shellCommand.execute",
            "args": {
                "command": "find . -type f -executable | grep -v test$ | sort -f",
                "cwd": "${workspaceFolder}/build/bin",
                "description": "Select the app to debug"
            },
        },
        {
            "id": "selectPython",
            "type": "command",
            "command": "shellCommand.execute",
            "args": {
                "command": "find . -type f -executable | sort -f",
                "cwd": "${workspaceFolder}/build/python",
                "description": "Select the python target to debug"
            },
        },
        {
            "id": "pythonArgs",
            "type": "command",
            "command": "shellCommand.execute",
            "args": {
                "command": "${input:selectPython} --someArgs",
                "cwd": "${workspaceFolder}/build/python",
                "description": "Select something"
            },
        },
        {
            "id": "debugFlag",
            "type": "pickString",
            "description": "Do you want to set the debug flag?",
            "options": [
                {
                    "label": "Yes",
                    "value": "--debug_flag",
                },
                {
                    "label": "No",
                    "value": "",
                }
            ],
            "default": "--debug_flag"
        },
    ]
}

Here are the two patterns depending on selection speed (only debugFlag matters here):

selectPython -> selectApplication -> debugFlag ("fast selection") -> pythonArgs -> debug sessions successfully started selectPython -> selectApplication ->debugFlag ("slow selection") -> "The command for input 'pythonArgs' returned empty result."

It seems like once gdb is fully started (which only depends on selectApplication), the previously selected selectPython which is needed again for pythonArgs is gone. So, if the selection of debugFlag takes longer than ~0.5s, it's already too long. When I start the two debug session independently, there is no issue - no matter how long I waited in between.

I just tried to make gdb wait until debugFlag was selected by adding a dummy pickString input to the gdb config and this way it works no matter the timing! So the started debug session does indeed interfere with the inputs of the other debug session. I hope that helps...?

MarcelKoller avatar Oct 14 '24 06:10 MarcelKoller

Does it show in the log the exact command that is run for pythonArgs?

MarcelRobitaille avatar Oct 14 '24 16:10 MarcelRobitaille

Sorry, I'm unable to locate the logs. Shouldn't they be available via the dropdown menu in the output tab?

MarcelKoller avatar Oct 16 '24 05:10 MarcelKoller

@MarcelKoller Sorry, I was confused about something. Nevermind.

Do you know how to run VSCode extensions from source? If so, could you please try this branch: task/95?

MarcelRobitaille avatar Nov 07 '24 20:11 MarcelRobitaille

No, I haven't done that before. Sadly, within the last weeks there were some changes in our project that require that the "Python debug session" is started (or rather running) before the "application debug session" is started. AFAIK it's not (easily) possible to control this using compound launch targets, right? So it seems as of now I won't be able to use this configuration even if your proposed fix would solve the issue 😒

MarcelKoller avatar Nov 08 '24 08:11 MarcelKoller

AFAIK it's not (easily) possible to control this using compound launch targets, right?

Could you do something using preLaunchTask and/or dependsOn?

So it seems as of now I won't be able to use this configuration even if your proposed fix would solve the issue

Would you mind testing it anyway? I would like to fix this bug.

MarcelRobitaille avatar Nov 08 '24 09:11 MarcelRobitaille

I suspect it's fixed in 1.13.0. If not, please re-open.

MarcelRobitaille avatar Nov 09 '24 11:11 MarcelRobitaille

Thanks a lot! It indeed seems to be fixed! I hope I will manage to adapt our setup to eventually make use of it again.

MarcelKoller avatar Nov 11 '24 06:11 MarcelKoller