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

Fix #5279 Leaking java debug process #5281

Merged
merged 1 commit into from
Aug 2, 2019

Conversation

tom-shan
Copy link
Contributor

When start debugging using vscode java-debug extension,
the debug process will remain in OS process list and
never be killed by theia process if the page is reloaded.

When terminate plugin server, kill all child processes
of plugin-host process.

Signed-off-by: tom-shan [email protected]

@tom-shan tom-shan requested review from benoitf and evidolob as code owners May 28, 2019 11:02
@tom-shan tom-shan changed the title fix leaking java debug process Fix #5279 Leaking java debug process May 28, 2019
@tom-shan
Copy link
Contributor Author

fix #5279

@tom-shan tom-shan force-pushed the debug-session branch 3 times, most recently from cdadffd to 534fb55 Compare May 31, 2019 10:57
@tom-shan
Copy link
Contributor Author

tom-shan commented Jun 1, 2019

@benoitf @evidolob @akosyakov Would you mind reviewing this PR?

@@ -120,13 +121,22 @@ export class HostedPluginProcess implements ServerPluginRunner {
}
});
const hostedPluginManager = rpc.getProxy(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT);
this.killChildProcesses(cp.pid);
Copy link
Member

Choose a reason for hiding this comment

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

it should go in then case after after plugin got unloaded

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@akosyakov
Copy link
Member

akosyakov commented Jun 3, 2019

I don't think it is really resolves the issue. Usually child process should observe parent process and if it exist then exit as well. Killing child processes from a parent process does not guarantee that it will happens always, e.g. if a parent process crashes it won't have a chance of doing it. I'm pretty sure that vscode java debug extension already has this logic, otherwise it won't work in VS Code as well. It bothers me why debug process exits only when a main server process dies. It seems that propagation of parent process id is done bogusly.

@tom-shan
Copy link
Contributor Author

tom-shan commented Jun 3, 2019

I have tested these two extensions in vscode(1.34.0) and got the similar results.
If I kill the extension host process in the background, then the java process will be killed later. But the java debug process will remain in the background even when I have exited the vscode.
If I click Start Debug, the debug console will show the same error.
image

@akosyakov
Copy link
Member

@tom-shan you are right, just got the same

@akosyakov
Copy link
Member

akosyakov commented Jun 3, 2019

It probably solves #4590
but we have to revert #5257 (@amiramw sorry, but it caused issue which were discussed on the PR)
and look into proper solution where plugins are unloaded from fronted and initializes on reconnection again (i am going to look into it later this week)

@amiramw
Copy link
Member

amiramw commented Jun 3, 2019

Will this problem happen also when two clients connect together? Like two different browsers.
Is this scenario expected to work in general with the plugins mechanism?

@akosyakov
Copy link
Member

Will this problem happen also when two clients connect together? Like two different browsers.
Is this scenario expected to work in general with the plugins mechanism?

I don't think it is related to the plugin system. When 2 users connect to the same backend they cannot expect to run anything on the same ports. Regarding debugging there is an issue to make debug session shared by default. That each client for the same workspace see all running debug sessions.

@tom-shan
Copy link
Contributor Author

Hi @akosyakov, it seems like no other questions, could you help merge this PR?

parentProcess.disconnect();
const parentPid = parentProcess.pid;
if (isWindows) {
cp.spawn('taskkill', ['/F', '/T', '/PID', parentPid.toString()]);
Copy link
Contributor

Choose a reason for hiding this comment

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

I had a very similar issue in one of my downstream projects. A few remarks on the PR:

  • Instead of doing taskkill on Windows and kill on *nix, just use tree-kill:
require('tree-kill')(yourPID);
  • You have to get the process tree on Windows as well. Not just in the else branch.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your recommendation, I will try to use this new npm package.

Copy link
Contributor

Choose a reason for hiding this comment

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

@tom-shan, please ping if you are done, I'll try to find time for the verification. Thanks!

@akosyakov
Copy link
Member

akosyakov commented Jul 26, 2019

@tom-shan sorry, we still had not time to test this PR on different platforms

@kittaakos could we rebase, test it as it is and merge? or you will prefer to use tree-kill

Could you verify on windows please?

In order to test one can install nodejs vscode extensions (https://marketplace.visualstudio.com/items?itemName=ms-vscode.node-debug + https://marketplace.visualstudio.com/items?itemName=ms-vscode.node-debug2) instead of native (@theia/debug-nodejs) and then kill the backend close the window during debugging and verify that processes are gone. You will need to wait a bit because of #5257.

@akosyakov akosyakov added debug issues that related to debug functionality vscode issues related to VSCode compatibility labels Jul 26, 2019
@tom-shan
Copy link
Contributor Author

@kittaakos @akosyakov Please have a review.

@kittaakos
Copy link
Contributor

Please have a review.

Sorry for the confusion, @tom-shan. I think what you did for the non-Windows version was the right way: you have to kill the children of the process you want to terminate, then the process. Something like this:

private killChildProcesses(parentPid: number): void {
    psTree(parentPid, (_, children) {
        for (const { PID } of children) {
            kill(PID);
        }
        kill(parentPid);
    });
}

@tom-shan
Copy link
Contributor Author

But according to https://github.com/pkrumins/node-tree-kill/blob/master/index.js#L47-L56, it will kill child processes first.
BTW, https://www.npmjs.com/package/terminate may be a better choice?

@kittaakos
Copy link
Contributor

@tom-shan
Copy link
Contributor Author

Got it. So we can use 'terminate' instead, because it has the right killing order and you can refer to https://github.com/dwyl/terminate/blob/master/handlePsTreeCallback.js#L17

@kittaakos
Copy link
Contributor

we can use 'terminate'

I have not used it yet, but if you want to use terminate, add it, I will verify.

@tom-shan tom-shan force-pushed the debug-session branch 2 times, most recently from 89ca646 to 66e5127 Compare July 29, 2019 15:46
@tom-shan
Copy link
Contributor Author

I'm done.

@kittaakos
Copy link
Contributor

I am verifying this on Windows.

@akosyakov
Copy link
Member

@kittaakos
Copy link
Contributor

I tried to verify it on Windows in the electron example app. It did not work. I did the followings:

  • Removed @theia/java and @theia/java-debug from both the browser and electron package.json files.
  • Rebuilt the extensions without Theia Java.
  • Downloaded the two Java VS Code extensions.
root INFO unzipping the plugin ProxyPluginDeployerEntry {
  deployer:
   PluginVsCodeFileHandler {
     unpackedFolder: 'C:\\Users\\KITTAA~1\\AppData\\Local\\Temp\\vscode-unpacked' },
  delegate:
   PluginDeployerEntryImpl {
     originId: 'local-dir:../../plugins',
     pluginId: 'redhat.java-0.47.0.vsix',
     map: Map {},
     changes: [],
     acceptedTypes: [],
     currentPath:
      'C:\\Users\\kittaakos\\dev\\theia\\plugins\\redhat.java-0.47.0.vsix',
     initPath:
      'C:\\Users\\kittaakos\\dev\\theia\\plugins\\redhat.java-0.47.0.vsix',
     resolved: true,
     resolvedByName: 'LocalDirectoryPluginDeployerResolver' },
  deployerName: 'PluginVsCodeFileHandler' }
root INFO unzipping the plugin ProxyPluginDeployerEntry {
  deployer:
   PluginVsCodeFileHandler {
     unpackedFolder: 'C:\\Users\\KITTAA~1\\AppData\\Local\\Temp\\vscode-unpacked' },
  delegate:
   PluginDeployerEntryImpl {
     originId: 'local-dir:../../plugins',
     pluginId: 'vscjava.vscode-java-debug-0.20.0.vsix',
     map: Map {},
     changes: [],
     acceptedTypes: [],
     currentPath:
      'C:\\Users\\kittaakos\\dev\\theia\\plugins\\vscjava.vscode-java-debug-0.20.0.vsix',
     initPath:
      'C:\\Users\\kittaakos\\dev\\theia\\plugins\\vscjava.vscode-java-debug-0.20.0.vsix',
     resolved: true,
     resolvedByName: 'LocalDirectoryPluginDeployerResolver' },
  deployerName: 'PluginVsCodeFileHandler' }
root INFO PluginTheiaDirectoryHandler: accepting plugin with path C:\Users\KITTAA~1\AppData\Local\Temp\vscode-unpacked\r
edhat.java-0.47.0.vsix
root INFO Resolved "redhat.java-0.47.0.vsix" to a VS Code extension "[email protected]" with engines: { vscode: '^1.36.0' }
root INFO PluginTheiaDirectoryHandler: accepting plugin with path C:\Users\KITTAA~1\AppData\Local\Temp\vscode-unpacked\v
scjava.vscode-java-debug-0.20.0.vsix
root INFO Resolved "vscjava.vscode-java-debug-0.20.0.vsix" to a VS Code extension "[email protected]" with engine
s: { vscode: '^1.32.0' }
root INFO Deploying backend plugin "[email protected]" from "C:\Users\KITTAA~1\AppData\Local\Temp\vscode-unpacked\redhat.java-
0.47.0.vsix\extension\dist\extension"
root INFO Deploying backend plugin "[email protected]" from "C:\Users\KITTAA~1\AppData\Local\Temp\vscode-unpacked
\vscjava.vscode-java-debug-0.20.0.vsix\extension\dist\extension"
root INFO [nsfw-watcher: 2572] Started watching: c:\Users\kittaakos\dev\spring-petclinic\.vscode\launch.json
root INFO [nsfw-watcher: 2572] Started watching: c:\Users\kittaakos\dev\spring-petclinic\.vscode\settings.json
root INFO Started watching the git repository: file:///c%3A/Users/kittaakos/dev/spring-petclinic
  • Waited for the LS to start and build.
root INFO [hosted-plugin: 3152] PLUGIN_HOST(3152): PluginManagerExtImpl/init()
PLUGIN_HOST(3152): initializing([email protected] with C:\Users\kittaakos\dev\theia\packages\plugin-ext-vscode\lib\node/plugin
-vscode-init.js)
PLUGIN_HOST(3152): initializing([email protected] with C:\Users\kittaakos\dev\theia\packages\plugin-ext-vscode\li
b\node/plugin-vscode-init.js)
Debugger contribution has been registered: java
root INFO [hosted-plugin: 3152] PLUGIN_HOST(3152): PluginManagerExtImpl/loadPlugin(C:\Users\KITTAA~1\AppData\Local\Temp\
vscode-unpacked\redhat.java-0.47.0.vsix\extension\dist\extension)
root INFO [hosted-plugin: 3152] { message:
   'Starting Java server with: C:\\PROGRA~1\\Java\\JDK18~1.0_1\\bin\\java -Declipse.application=org.eclipse.jdt.ls.core.
id1 -Dosgi.bundles.defaultStartLevel=4 -Declipse.product=org.eclipse.jdt.ls.core.product -Dfile.encoding=UTF-8 -DwatchPa
rentProcess=false -noverify -Xmx1G -XX:+UseG1GC -XX:+UseStringDeduplication -jar C:\\Users\\KITTAA~1\\AppData\\Local\\Te
mp\\vscode-unpacked\\redhat.java-0.47.0.vsix\\extension\\server\\plugins\\org.eclipse.equinox.launcher_1.5.500.v20190715
-1310.jar -configuration C:\\Users\\KITTAA~1\\AppData\\Local\\Temp\\vscode-unpacked\\redhat.java-0.47.0.vsix\\extension\
\server\\config_win -data C:\\Users\\kittaakos\\AppData\\Roaming\\.theia\\workspace-storage\\b57d6bdc8a5ce6f798acacd19bf
4aa59\\redhat.java\\jdt_ws',
  level: 'info',
  timestamp: '2019-07-31 09:39:52.756' }
  • Started the Debug (Launch)-PetClinicApplication<spring-petclinic> launch configuiration.
  • Had an error:
root INFO [hosted-plugin: 3152] PLUGIN_HOST(3152): PluginManagerExtImpl/loadPlugin(C:\Users\KITTAA~1\AppData\Local\Temp\
vscode-unpacked\vscjava.vscode-java-debug-0.20.0.vsix\extension\dist\extension)
root INFO [hosted-plugin: 3152] Debug configuration provider has been registered: java
root INFO [hosted-plugin: 3152] Cannot update debug settings. { Error: No delegateCommandHandler for vscode.java.updateD
ebugSettings
    at C:\Users\KITTAA~1\AppData\Local\Temp\vscode-unpacked\redhat.java-0.47.0.vsix\extension\dist\extension.js:1:13690
    at C:\Users\KITTAA~1\AppData\Local\Temp\vscode-unpacked\redhat.java-0.47.0.vsix\extension\dist\extension.js:1:13984
    at Immediate.k.size.setImmediate (C:\Users\KITTAA~1\AppData\Local\Temp\vscode-unpacked\redhat.java-0.47.0.vsix\exten
sion\dist\extension.js:1:14345)
    at runCallback (timers.js:696:18)
    at tryOnImmediate (timers.js:667:5)
    at processImmediate (timers.js:649:5) code: -32601, data: undefined }
root ERROR Error starting the debug session Error: It is not possible to provide debug adapter executable.
    at DebugExtImpl.<anonymous> (C:\Users\kittaakos\dev\theia\packages\plugin-ext\lib\plugin\node\debug\debug.js:501:39)
    at step (C:\Users\kittaakos\dev\theia\packages\plugin-ext\lib\plugin\node\debug\debug.js:32:23)
    at Object.next (C:\Users\kittaakos\dev\theia\packages\plugin-ext\lib\plugin\node\debug\debug.js:13:53)
    at fulfilled (C:\Users\kittaakos\dev\theia\packages\plugin-ext\lib\plugin\node\debug\debug.js:4:58)
    at process._tickCallback (internal/process/next_tick.js:68:7)

Screen Shot 2019-07-31 at 09 48 58

@akosyakov
Copy link
Member

@kittaakos Please try with node.js vscode extensions, they are in the better state.

In order to test one can install nodejs vscode extensions (https://marketplace.visualstudio.com/items?itemName=ms-vscode.node-debug + https://marketplace.visualstudio.com/items?itemName=ms-vscode.node-debug2) instead of native (@theia/debug-nodejs) and then kill the backend close the window during debugging and verify that processes are gone. You will need to wait a bit because of #5257.

@marcdumais-work
Copy link
Contributor

please don't forget to check licenses of new dependencies: https://github.com/theia-ide/theia/wiki/Registering-CQs#wip---new-ecd-theia-intellectual-property-clearance-approach-experimental

cc @marcdumais-work

+1

terminate is licensed under GPL v2.0 and so is not appropriate for an Eclipse Foundation project such as Theia.

@tom-shan
Copy link
Contributor Author

OK, I will refactor this PR without terminate.

@tom-shan
Copy link
Contributor Author

@kittaakos Please verify it again.

@kittaakos
Copy link
Contributor

Please try with node.js vscode extensions

@akosyakov, how can I make sure it is a fix for the leaking Java process?

When start debugging using vscode java-debug extension,
the debug process will remain in OS process list and
never be killed by theia process if the page is reloaded.

When terminate plugin server, kill all child processes
of plugin-host process.

Signed-off-by: tom-shan <[email protected]>
@tom-shan
Copy link
Contributor Author

I tried to verify it on Windows in the electron example app. It did not work. I did the followings:

I have tested with two vscode extensions: java 0.44.0 and java-debug 0.15.0 in Ubuntu and have the
same error of root ERROR Error starting the debug session Error: It is not possible to provide debug adapter executable.

@kittaakos
Copy link
Contributor

have the
same error of

Thanks for the note, @tom-shan.

Locally, I have rebased your code from the HEAD of Theia's master. Maybe, it was fixed.
If no, I will check with the exact same version you provided in the original issue description. Very solid steps, by the way 👍🎖

@tom-shan
Copy link
Contributor Author

tom-shan commented Jul 31, 2019

If still have the same error, you can try with another repo which is much simpler and the debug session is started successfully.

@tom-shan
Copy link
Contributor Author

tom-shan commented Aug 1, 2019

@kittaakos After the extra process of cleaning some data(~/.theia and /tmp/vscode-unpacked), the error of root ERROR Error starting the debug session Error: It is not possible to provide debug adapter executable is gone and the debug session can be started successfully in my vm.

@kittaakos kittaakos self-requested a review August 2, 2019 06:56
Copy link
Contributor

@kittaakos kittaakos left a comment

Choose a reason for hiding this comment

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

I have verified it on Windows in electron. It worked. I started several Java debug processes, and when I refreshed the browser window, all Java processes were terminated. 👍 Thank you for your help on this, @tom-shan!

screencast 2019-08-02 08-52-59

@kittaakos
Copy link
Contributor

Are we good license-wise for this PR, @marcdumais-work? Thanks!

@marcdumais-work
Copy link
Contributor

Are we good license-wise for this PR, @marcdumais-work? Thanks!

LGTM - the latest version of this PR adds no new dependency (ps-tree was already pulled from @theia/plugin-dev.

@kittaakos
Copy link
Contributor

LGTM

Thank you for your help!

@kittaakos kittaakos merged commit 49f80ff into eclipse-theia:master Aug 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
debug issues that related to debug functionality vscode issues related to VSCode compatibility
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants