This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 75120

Summary: Terminate Process is failing
Product: cnd Reporter: _ gordonp <gordonp>
Component: -- Other --Assignee: _ gordonp <gordonp>
Status: CLOSED FIXED    
Severity: blocker CC: nikmolchanov
Priority: P2    
Version: 5.x   
Hardware: All   
OS: All   
Issue Type: DEFECT Exception Reporter:
Attachments: Proposed patch I

Description _ gordonp 2006-04-17 16:57:08 UTC
If I go to the Runtime tab and select a running process and select the
Terminate Process from the context menu, th tab is updated to say the process
is terminated but a ps command shows the process still running.

This is (at least) a problem on Solaris. It should be checked on Linux and
Windows as well.
Comment 1 alexandrov 2006-09-08 11:50:57 UTC
Exit IDE also can not terminate the process inspite of "Exit IDE" dialog which
tells to user that exiting IDE will terminate all running processes.

This bug is reproducible for all OSs.  
Comment 2 _ gordonp 2006-10-31 23:41:16 UTC
Reassigning to Vladimir.Its partially fixed (works on Solaris) but not well
enough tested to even be called a complete Solaris fix. It doesn't work on
Windows and hasn't been tested on Linux (although I'd be inclined to expect
it to work on Linux as reliably as it does on Solaris).
Comment 3 soldatov 2006-11-14 17:15:33 UTC
I repeated these steps on all platforms:
- create file with 'scanf()'. For example:
-----------------------------------------------------

#include <stdlib.h>
#include <stdio.h>


int
main(int argc, char** argv) {
    char s[30];
    scanf("%s", s);
    return (EXIT_SUCCESS);
}


-----------------------------------------------------

- run project
- open Runtime tab
==> '<No process Running>' in process tab
Comment 4 Vladimir Voskresensky 2006-11-15 13:54:37 UTC
On SuSe Linux the provided program is terminated OK through Runtime tab or by
closing IDE. No hang process.
Comment 5 _ gordonp 2006-11-15 14:55:55 UTC
The run-project changes I made are affecting this in some cases. If I change
console type (a new property) to Output window then (on Solaris) the proc is
correctly terminated. If I set console type to external and terminal type (the
other new property) to gnome-terminal (or Default on a system which has
gnome-terminal) then it fails. Not only that, but gnome-terminal -e returns
immediately (ie, it looks like it forks with the child opening a new window
and running the app while the parent returns immediately).
Comment 6 soldatov 2006-11-15 15:50:15 UTC
Thanks. If I change console type to Output window then I can see process in
Runtime tab. And I can terminate process on JDS3 (linux).
Comment 7 Vladimir Voskresensky 2006-11-15 15:55:56 UTC
on SuSe, when "Console Type" is Output Window => process remains in system after
terminating in Runtime tab.
Comment 8 Nikolay Molchanov 2006-11-16 21:33:55 UTC
I think we can use something similar to what we use in gdb-lite module, to
make sure the process is terminated. We send a signal, using external utility
"kill". Here is a method from GdbProxyCL.java, which kills external terminal:

    /**
     * Closes External Program I/O Window (external terminal)
     */
    private void closeExternalProgramIOWindow() {
        if (externalTerminalPID != null) {
            // Kill external terminal
            String cmd = SH_CMD_KILL + externalTerminalPID;
            externalTerminalPID = null;
            gdbProxy.gdbProxyML.executeExternalCommand(cmd, DIR_TMP, 0);
        }
    }

The main problem here is to get PID (process ID of gnome-terminal, xterm, ...
- whatever was used to create external terminal). It seems relatively easy 
to implement on Unix (again, there is a working code in gdb-lite module), 
but it could be more tricky on Windows. The idea is that shell script, which
starts the program, can get PID and save it in a temporary file. IDE will read
this temporary file, get PID, send kill, and remove temporary file. 
The risk is to send kill too late, when the process has already gone, and 
this PID now belongs to another process, but this is very unlikely to happen 
because this PID cannot be used by another process immediately - it will be 
used when the round is over (OS achieved maximum PID and started from the 
beginning).
Also there could be some alternative solutions. For example, shell script, 
which starts the program, can create a unique temporary file (name is passed 
by IDE) and check its existence every second. When user asks to terminate 
this job, IDE removes this temporary file. Script will notice it, kill the 
program and exits.

Comment 9 Vladimir Voskresensky 2006-11-16 21:57:31 UTC
Thanks, Nik.
I'm trying this way now.

I changed stdouterr.sh (used for running everything):
if [ -n "$1" ]
then
        echo $$
	exec "$@" >&2
fi
you can see echo $$ => I read first line to extract PID.
what about Windows?
what is the alternative for stdouterr.bat file?

Then I kill process when it is terminated using:
    private static void killProcess(int pID) {
        if (pID == 0) {
            return;
        }
        String cmdline = getKillCommand(pID);
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(cmdline);
            if (process != null) {
                try {
                    process.waitFor();
                } catch (InterruptedException ex) {
                    destroyProcess(process);
                }
            }
        } catch (IOException ex) {
            destroyProcess(process);
        }     
    }
    
    private static String getKillCommand(int pID) {
        String cmdline = null;
        // TODO: need correct kill utility
        // "tskill pID" for XP Home and XP Pro
        // "taskkill /PID pID" for XP Pro        
        if (Utilities.isWindows()) {
            if (Utilities.getOperatingSystem() == Utilities.OS_WINNT) {
                cmdline = "kill " + pID;
            } else {
                cmdline = "kill " + pID;
            }
        } else {
            cmdline = "kill " + pID;            
        }
        return cmdline;
    }
    
    private static void destroyProcess(Process process) {
        if (process == null) {
            return;
        }
        process.destroy();
        int rc = -1;
        while (rc < 0) {
            try {
                rc = process.waitFor();
            } catch (InterruptedException ex1) {
            }
        }        
    }
Comment 10 _ gordonp 2006-11-17 00:39:42 UTC
> what about Windows?

Have you considered using stdouterr.sh on Windows? We require Cygwin in cnd 1.0
so users are guaranteed to have sh (which is bash in Cygwin).
Comment 11 Vladimir Voskresensky 2006-11-20 17:12:35 UTC
Created attachment 36147 [details]
Proposed patch I
Comment 12 Vladimir Voskresensky 2006-11-20 18:26:32 UTC
the patch doesn't work for external terminal on windows, because it redirects
everything in shell script which doesn't support passed "start" commands.
Comment 13 Vladimir Voskresensky 2006-11-21 00:58:45 UTC
We now have two different ways to run projects:
- in output window
- in external terminal
and execution process is slightly different for this cases.

What is done:
- the main idea to send "kill" command to executed process
- we need PID of the process => it is printed as "echo $$ >&2" in stdouterr.sh
and NativeExecution.OutputReaderThread class reads the first line to catch this
PID and remember for run user's process in NB (it is Thread object)
- when user's process is interrupted => we get InterruptedExeption and
ThreadDeath execptions and should kill external process. We do it using
remembered PID.

proposed fix works fine on:
- Linux (SuSe 10) in both OW and ExtTerm
- Solaris 10 in both OW and ExtTerm

To work on Windows I had to make changes to obtains PID
- as we require to have cygwin to build/run/debug in cnd => I changed
stdouterr.bat file to call "sh stdouterr.sh" and pass all params to it.
- this cause some problems, because in our code some parts convert
arguments/paths/params to have Windows like path separators, but as now
everything is passed to batch file which redirects to shell file => we need Unix
like values.
- I made some necessary changes and on Windows everything works for OutputWindow

remains problems are with external terminal on Windows, because "start" is not
valid command for shell scripts 

Comment 14 _ gordonp 2006-11-28 19:52:08 UTC
*** Issue 89783 has been marked as a duplicate of this issue. ***
Comment 15 _ gordonp 2007-06-30 02:15:31 UTC
Fixed by passing the temp file on the command line. It was previously sent as an env var and
the Windows "start" command was not passing it on.
Comment 16 dnikitin 2007-11-02 18:06:19 UTC
There is no Runtime tab in NB 6.0