You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by en...@apache.org on 2021/05/22 11:02:46 UTC

[netbeans] 01/02: Assure that debug process exits when debugging finishes.

This is an automated email from the ASF dual-hosted git repository.

entl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git

commit fd6921c496c53e51f8c451dee46887545c9d0ca7
Author: Martin Entlicher <ma...@oracle.com>
AuthorDate: Fri May 21 10:58:13 2021 +0200

    Assure that debug process exits when debugging finishes.
---
 .../modules/cpplite/debugger/CPPLiteDebugger.java  | 72 ++++++++++++++------
 .../cpplite/debugger/AbstractDebugTest.java        | 14 +++-
 .../modules/cpplite/debugger/BreakpointsTest.java  |  1 +
 .../debugger/{StepTest.java => ExitTest.java}      | 76 ++++++++++------------
 .../modules/cpplite/debugger/StepTest.java         |  3 +-
 5 files changed, 103 insertions(+), 63 deletions(-)

diff --git a/cpplite/cpplite.debugger/src/org/netbeans/modules/cpplite/debugger/CPPLiteDebugger.java b/cpplite/cpplite.debugger/src/org/netbeans/modules/cpplite/debugger/CPPLiteDebugger.java
index 8545d3f..0c41c83 100644
--- a/cpplite/cpplite.debugger/src/org/netbeans/modules/cpplite/debugger/CPPLiteDebugger.java
+++ b/cpplite/cpplite.debugger/src/org/netbeans/modules/cpplite/debugger/CPPLiteDebugger.java
@@ -36,6 +36,7 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -93,6 +94,7 @@ public final class CPPLiteDebugger {
     private final ThreadsCollector      threadsCollector = new ThreadsCollector(this);
     private volatile CPPThread          currentThread;
     private volatile CPPFrame           currentFrame;
+    private AtomicInteger               exitCode = new AtomicInteger();
 
     public CPPLiteDebugger(ContextProvider contextProvider) {
         this.contextProvider = contextProvider;
@@ -359,6 +361,13 @@ public final class CPPLiteDebugger {
     }
 
     void finish (boolean sendExit) {
+        finish(sendExit, 0);
+    }
+
+    private void finish (boolean sendExit, int exitCode) {
+        if (exitCode != 0) {
+            this.exitCode.set(exitCode);
+        }
         LOGGER.fine("CPPLiteDebugger.finish()");
         if (finished) {
             LOGGER.fine("finish(): already finished.");
@@ -462,29 +471,43 @@ public final class CPPLiteDebugger {
                         }
                         CPPThread thread = threadsCollector.get(threadId);
                         String reason = results.getConstValue("reason", "");
-                        switch (reason) {
-                            case "exited-normally":
-                                if ('*' == record.type()) {
-                                    finish(false);
+                        if (reason.startsWith("exited")) {
+                            if ('*' == record.type()) {
+                                int exitCode;
+                                if ("exited-normally".equals(reason)) {
+                                    exitCode = 0;
                                 } else {
-                                    threadsCollector.remove(threadId);
-                                }
-                                break;
-                            default:
-                                MITList topFrameList = (MITList) results.valueOf("frame");
-                                CPPFrame frame = topFrameList != null ? CPPFrame.create(thread, topFrameList) : null;
-                                thread.setTopFrame(frame);
-                                setSuspended(true, thread, frame);
-                                if (frame != null) {
-                                    Line currentLine = frame.location();
-                                    if (currentLine != null) {
-                                        Annotatable[] lines = new Annotatable[] {currentLine};
-                                        CPPLiteDebugger.this.currentLine = lines;
-                                        Utils.markCurrent(lines);
-                                        Utils.showLine(lines);
+                                    String exitCodeStr = results.getConstValue("exit-code", null);
+                                    if (exitCodeStr != null) {
+                                        if (exitCodeStr.startsWith("0x")) {
+                                            exitCode = Integer.parseInt(exitCodeStr, 16);
+                                        } else if (exitCodeStr.startsWith("0")) {
+                                            exitCode = Integer.parseInt(exitCodeStr, 8);
+                                        } else {
+                                            exitCode = Integer.parseInt(exitCodeStr);
+                                        }
+                                    } else {
+                                        exitCode = 0;
                                     }
                                 }
-                                break;
+                                finish(true, exitCode);
+                            } else {
+                                threadsCollector.remove(threadId);
+                            }
+                        } else {
+                            MITList topFrameList = (MITList) results.valueOf("frame");
+                            CPPFrame frame = topFrameList != null ? CPPFrame.create(thread, topFrameList) : null;
+                            thread.setTopFrame(frame);
+                            setSuspended(true, thread, frame);
+                            if (frame != null) {
+                                Line currentLine = frame.location();
+                                if (currentLine != null) {
+                                    Annotatable[] lines = new Annotatable[] {currentLine};
+                                    CPPLiteDebugger.this.currentLine = lines;
+                                    Utils.markCurrent(lines);
+                                    Utils.showLine(lines);
+                                }
+                            }
                         }
                         break;
                     case "running":
@@ -668,6 +691,7 @@ public final class CPPLiteDebugger {
             }
         });
         debugger.setDebuggee(debuggee);
+        AtomicInteger exitCode = debugger.exitCode;
 
         return Pair.of(es[0], new Process() {
             @Override
@@ -686,8 +710,14 @@ public final class CPPLiteDebugger {
             }
 
             @Override
+            public boolean isAlive() {
+                return debuggee.isAlive();
+            }
+
+            @Override
             public int waitFor() throws InterruptedException {
-                return debuggee.waitFor();
+                debuggee.waitFor();
+                return exitCode.get();
             }
 
             @Override
diff --git a/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/AbstractDebugTest.java b/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/AbstractDebugTest.java
index eb1e626..96c38b1 100644
--- a/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/AbstractDebugTest.java
+++ b/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/AbstractDebugTest.java
@@ -27,11 +27,13 @@ import junit.framework.Test;
 import org.netbeans.api.debugger.DebuggerEngine;
 import org.netbeans.junit.NbModuleSuite;
 import org.netbeans.junit.NbTestCase;
+import org.openide.util.Pair;
 
 public abstract class AbstractDebugTest extends NbTestCase {
 
     protected DebuggerEngine engine;
     protected CPPLiteDebugger debugger;
+    protected Process process;
 
     private final int[] suspendCount = new int[]{0};
     private final int[] resumeCount = new int[]{0};
@@ -51,7 +53,9 @@ public abstract class AbstractDebugTest extends NbTestCase {
     }
 
     protected final void startDebugging(String name, File wd) throws IOException {
-        engine = CPPLiteDebugger.startDebugging(new CPPLiteDebuggerConfig(Arrays.asList(new File(wd, name).getAbsolutePath()), wd, "gdb")).first();
+        Pair<DebuggerEngine, Process> engineProcess = CPPLiteDebugger.startDebugging(new CPPLiteDebuggerConfig(Arrays.asList(new File(wd, name).getAbsolutePath()), wd, "gdb"));
+        engine = engineProcess.first();
+        process = engineProcess.second();
         debugger = engine.lookupFirst(null, CPPLiteDebugger.class);
         debugger.addStateListener(new CPPLiteDebugger.StateListener() {
             @Override
@@ -99,6 +103,14 @@ public abstract class AbstractDebugTest extends NbTestCase {
         }
     }
 
+    protected boolean isAppProcessAlive() {
+        return process.isAlive();
+    }
+
+    protected final int waitAppProcessExit() throws InterruptedException {
+        return process.waitFor();
+    }
+
     protected final void assertStoppedAt(URI file, int line) {
         CPPFrame currentFrame = debugger.getCurrentFrame();
         assertNotNull(currentFrame);
diff --git a/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/BreakpointsTest.java b/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/BreakpointsTest.java
index d22f578..cf43cf9 100644
--- a/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/BreakpointsTest.java
+++ b/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/BreakpointsTest.java
@@ -135,6 +135,7 @@ public class BreakpointsTest extends AbstractDebugTest {
         waitResumed(6);
 
         engine.getActionsManager().doAction(ActionsManager.ACTION_KILL);
+        assertEquals(0, waitAppProcessExit());
     }
 
     public static Test suite() {
diff --git a/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/StepTest.java b/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/ExitTest.java
similarity index 54%
copy from cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/StepTest.java
copy to cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/ExitTest.java
index 307af7a..2d76f7b 100644
--- a/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/StepTest.java
+++ b/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/ExitTest.java
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.netbeans.modules.cpplite.debugger;
 
 import java.io.File;
@@ -24,10 +23,11 @@ import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import junit.framework.Test;
-
+import static junit.framework.TestCase.assertNotNull;
 import org.netbeans.api.debugger.ActionsManager;
 import org.netbeans.api.debugger.DebuggerManager;
 import org.netbeans.junit.NbModuleSuite;
+import static org.netbeans.modules.cpplite.debugger.AbstractDebugTest.compileCPP;
 import org.netbeans.modules.cpplite.debugger.breakpoints.CPPLiteBreakpoint;
 import org.openide.cookies.LineCookie;
 import org.openide.filesystems.FileObject;
@@ -35,64 +35,60 @@ import org.openide.filesystems.FileUtil;
 import org.openide.loaders.DataObject;
 
 /**
- * Tests C/C++ debugger stepping actions: step in, step out and step over.
  *
- * @author Jan Jancura
+ * @author Martin Entlicher
  */
-public class StepTest extends AbstractDebugTest {
+public class ExitTest extends AbstractDebugTest {
 
-    public StepTest (String s) {
-        super (s);
+    public ExitTest(String s) {
+        super(s);
     }
 
-    @Override
-    protected void setUp() throws Exception {
-        clearWorkDir();
+    public void testAppExit () throws Exception {
+        File wd = getWorkDir();
+        for (int exitCode = 0; exitCode <= 200; exitCode += 100) {
+            FileObject source = FileUtil.createData(FileUtil.toFileObject(wd), "mainExit" + exitCode + ".cpp");
+            try (OutputStream os = source.getOutputStream();
+                Writer w = new OutputStreamWriter(os)) {
+                w.append("int main(int argc, char** args) {\n" +
+                         "    int N = 100;\n" +
+                         "    return " + exitCode + ";\n" +
+                         "}");
+            }
+            compileCPP("mainExit" + exitCode, wd);
+            LineCookie lc = DataObject.find(source).getLookup().lookup(LineCookie.class);
+            assertNotNull(lc);
+            DebuggerManager.getDebuggerManager().addBreakpoint(CPPLiteBreakpoint.create(lc.getLineSet().getCurrent(4)));
+            startDebugging("mainExit" + exitCode, wd);
+            assertEquals(exitCode, waitAppProcessExit());
+        }
     }
 
-    public void testStepOver () throws Exception {
+    public void testAppKill () throws Exception {
         File wd = getWorkDir();
-        FileObject source = FileUtil.createData(FileUtil.toFileObject(wd), "main.cpp");
+        FileObject source = FileUtil.createData(FileUtil.toFileObject(wd), "mainKill.cpp");
         try (OutputStream os = source.getOutputStream();
             Writer w = new OutputStreamWriter(os)) {
-            w.append("#include <iostream>\n" +
-                     "\n" +
-                     "void test(void) {\n" +
-                     "    std::cerr << \"Hello, from err!\" << std::endl;\n" +
-                     "    std::cout << \"Hello, second time!\" << std::endl;\n" +
-                     "}\n" +
-                     "\n" +
-                     "int main(void) {\n" +
-                     "    int i = 42;\n" +
-                     "    std::cout << \"Hello, world!\" << std::endl;\n" +
-                     "    test();\n" +
-                     "    std::cout << \"Hello, second time!\" << std::endl;\n" +
+            w.append("int main(int argc, char** args) {\n" +
+                     "    for(;;);\n" +
                      "}");
         }
-        compileCPP("main", wd);
+        compileCPP("mainKill", wd);
         LineCookie lc = DataObject.find(source).getLookup().lookup(LineCookie.class);
         assertNotNull(lc);
         DebuggerManager.getDebuggerManager().addBreakpoint(CPPLiteBreakpoint.create(lc.getLineSet().getCurrent(4)));
-        startDebugging("main", wd);
-
-        waitSuspended(1);
-
-        assertStoppedAt(source.toURI(), 5);
-
-        engine.getActionsManager().doAction(ActionsManager.ACTION_STEP_OVER);
-
-        waitResumed(1);
-
-        waitSuspended(2);
-
-        assertStoppedAt(source.toURI(), 6);
-
+        startDebugging("mainKill", wd);
+        assertTrue(isAppProcessAlive());
+        Thread.sleep(10);
+        assertTrue(isAppProcessAlive());
         engine.getActionsManager().doAction(ActionsManager.ACTION_KILL);
+        assertEquals(0, waitAppProcessExit());
+        assertFalse(isAppProcessAlive());
     }
 
     public static Test suite() {
         return NbModuleSuite.emptyConfiguration()
-                            .addTest(StepTest.class)
+                            .addTest(ExitTest.class)
                             .enableModules(".*", ".*")
                             .gui(false)
                             .suite();
diff --git a/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/StepTest.java b/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/StepTest.java
index 307af7a..7283499 100644
--- a/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/StepTest.java
+++ b/cpplite/cpplite.debugger/test/unit/src/org/netbeans/modules/cpplite/debugger/StepTest.java
@@ -87,7 +87,8 @@ public class StepTest extends AbstractDebugTest {
 
         assertStoppedAt(source.toURI(), 6);
 
-        engine.getActionsManager().doAction(ActionsManager.ACTION_KILL);
+        engine.getActionsManager().doAction(ActionsManager.ACTION_CONTINUE);
+        assertEquals(0, waitAppProcessExit());
     }
 
     public static Test suite() {

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists