How to suspend a DSF debug session?

classic Classic list List threaded Threaded
6 messages Options
S A
Reply | Threaded
Open this post in threaded view
|

How to suspend a DSF debug session?

S A
Hi all,

I'm trying to use DSF instead of the old CDI debugger, so far I've managed to trigger debug executions with a custom launch. But I'm having trouble with suspending the debug session from product/test code.

Here is roughly the code at which I've arrived (note that its part of a test):

            IAdaptable context = DebugUITools.getDebugContext();
            IDMContext dmc = context.getAdapter(IDMContext.class);
            DsfSession mi = DsfSession.getSession(dmc.getSessionId());
            IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);
            DsfServicesTracker tracker = new DsfServicesTracker(Activator.getDefault().getBundle().getBundleContext(), mi.getId());
            IRunControl runControl = tracker.getService(IRunControl.class);
            // wait up to 30 seconds for IRunControl.canSuspend() to return true
            ImmediateRequestMonitor suspendRequestMonitor = new ImmediateRequestMonitor(null);
            runControl.suspend(executionContext, suspendRequestMonitor);
            assertTrue("Failed to suspend CDT DSF debug launch", suspendRequestMonitor.isSuccess());
            // wait up to 30 seconds for IRunControl.isSuspended() to return true
            // the wait for suspend times out

I'm seeing this in the error log:

!MESSAGE Request for monitor: 'RequestMonitor (com.verigy.itee.utm.test.debug.TestUtmDebuggerProxy$1@2fddae92): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

Unfortunately I don't know how to continue debugging the DSF code (to find out what the problem is), I see e.g.  "55-exec-interrupt --thread 1" is written to some output stream in AbstractMIControl.TxThread.run(). The respective error stream doesn't contain anything, no lines are read in: AbstractMIControl.ErrorThread. I found bug 509812 (which was fixed in 2017), but nothing else. I also tried increasing the timeout in GDBRunControl_7_0_NS.MonitorSuspendJob.TIMEOUT_DEFAULT_VALUE to 30 seconds, still the same results.

CDT is version 9.6.

GDB version should be: GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7

I'm using IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to true.

The debug execution context is at:

(gdb[0].proc[52864].threadGroup[i1],gdb[0].proc[52864].OSthread[1]).thread[1]

I've added some outputs for writing and reading in AbstractMIControl, here is what I see (it seems fine to me):

[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)
[Mon Mar 09 14:32:10 CET 2020] Wrote: 66-exec-interrupt --thread 1

[Mon Mar 09 14:32:10 CET 2020] Read: 66^done
[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)

!ENTRY org.eclipse.cdt.dsf 4 10005 2020-03-09 14:32:20.502
!MESSAGE Request for monitor: 'RequestMonitor (org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor@331190c1): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

There is only 1 "exec-interrupt" command in the output.

Note that I have no experience with GDB itself, I'm not a C/C++ developer.

Best regards and thanks,
Simeon

_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
S A
Reply | Threaded
Open this post in threaded view
|

Fwd: How to suspend a DSF debug session?

S A
Hi,

to answer my own question, I've noticed our product uses .gdbinit with the following lines:

handle SIGSTOP nostop
handle SIGSTOP noprint

When combined with IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to "true", apparently the CDI/DSF debuggers are unable to suspend.

Our debugger based on DSF unfortunately suspends (all threads) on attach launch, which is not the case for the old implementation based on CDI. We are trying to use ATTR_DEBUGGER_NON_STOP to prevent this. Is there a way to not suspend all threads on attach, that does not involve using ATTR_DEBUGGER_NON_STOP (note that this is not improved by setting ATTR_DEBUGGER_STOP_AT_MAIN to "false")? We can maybe resort to a job that resumes the launch after its started, but it would be great if there is no suspend in the first place.

Best regards,
Simeon

---------- Forwarded message ---------
From: S A <[hidden email]>
Date: Mon, 9 Mar 2020 at 15:36
Subject: How to suspend a DSF debug session?
To: <[hidden email]>


Hi all,

I'm trying to use DSF instead of the old CDI debugger, so far I've managed to trigger debug executions with a custom launch. But I'm having trouble with suspending the debug session from product/test code.

Here is roughly the code at which I've arrived (note that its part of a test):

            IAdaptable context = DebugUITools.getDebugContext();
            IDMContext dmc = context.getAdapter(IDMContext.class);
            DsfSession mi = DsfSession.getSession(dmc.getSessionId());
            IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);
            DsfServicesTracker tracker = new DsfServicesTracker(Activator.getDefault().getBundle().getBundleContext(), mi.getId());
            IRunControl runControl = tracker.getService(IRunControl.class);
            // wait up to 30 seconds for IRunControl.canSuspend() to return true
            ImmediateRequestMonitor suspendRequestMonitor = new ImmediateRequestMonitor(null);
            runControl.suspend(executionContext, suspendRequestMonitor);
            assertTrue("Failed to suspend CDT DSF debug launch", suspendRequestMonitor.isSuccess());
            // wait up to 30 seconds for IRunControl.isSuspended() to return true
            // the wait for suspend times out

I'm seeing this in the error log:

!MESSAGE Request for monitor: 'RequestMonitor (com.verigy.itee.utm.test.debug.TestUtmDebuggerProxy$1@2fddae92): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

Unfortunately I don't know how to continue debugging the DSF code (to find out what the problem is), I see e.g.  "55-exec-interrupt --thread 1" is written to some output stream in AbstractMIControl.TxThread.run(). The respective error stream doesn't contain anything, no lines are read in: AbstractMIControl.ErrorThread. I found bug 509812 (which was fixed in 2017), but nothing else. I also tried increasing the timeout in GDBRunControl_7_0_NS.MonitorSuspendJob.TIMEOUT_DEFAULT_VALUE to 30 seconds, still the same results.

CDT is version 9.6.

GDB version should be: GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7

I'm using IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to true.

The debug execution context is at:

(gdb[0].proc[52864].threadGroup[i1],gdb[0].proc[52864].OSthread[1]).thread[1]

I've added some outputs for writing and reading in AbstractMIControl, here is what I see (it seems fine to me):

[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)
[Mon Mar 09 14:32:10 CET 2020] Wrote: 66-exec-interrupt --thread 1

[Mon Mar 09 14:32:10 CET 2020] Read: 66^done
[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)

!ENTRY org.eclipse.cdt.dsf 4 10005 2020-03-09 14:32:20.502
!MESSAGE Request for monitor: 'RequestMonitor (org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor@331190c1): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

There is only 1 "exec-interrupt" command in the output.

Note that I have no experience with GDB itself, I'm not a C/C++ developer.

Best regards and thanks,
Simeon

_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: How to suspend a DSF debug session?

Jonah Graham
Hi Simeon,

I am unsure how much you have simplified your test case. Have you hid the async nature of the code?

It appears to me based on what you have provided that you are running outside of the DSF Executor thread, but trying to interact with objects "owned" by the executor thread. i.e. to create a tracker, get a service or call suspend you need to be in the executor thread.

I would expect code that is trying to suspend the target to look like (sorry for indentation loss in email):

IAdaptable context = DebugUITools.getDebugContext();
IDMContext dmc = context.getAdapter(IDMContext.class);
DsfSession mi = DsfSession.getSession(dmc.getSessionId());
IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);

Query<Object> query = new Query<Object>() {
@Override
protected void execute(DataRequestMonitor<Object> rm) {
DsfServicesTracker tracker = new DsfServicesTracker(
Activator.getDefault().getBundle().getBundleContext(), mi.getId());
try {
IRunControl runControl = tracker.getService(IRunControl.class);
runControl.suspend(executionContext, rm);
} finally {
tracker.dispose();
}
}
};

try {
mi.getExecutor().execute(query);
Object result = query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
//  probably don't catch in tests
}
// your target has now suspended.


Now, what I am seeing that doesn't make sense is that there is no *stopped message in your log. With an MI trace you should be able to reproduce outside of Eclipse.

Some other notes that may help:
- You can turn on tracing so you don't have to instrument AbstractMIControl. You can use either the standard tracing in Eclipse (org.eclipse.cdt.dsf.gdb/debug = true) or use the console in your target eclipse (https://wiki.eclipse.org/CDT/User/NewIn92#Hide_gdb_traces_by_default)
- Non-stop has a more complete (and complex) service that extends IRunControl - you can use IMultiRunControl to suspend/resume/control/query multiple threads.
- As for suspending or not in all-stop, I don't know all the ins and outs of that decision, but https://bugs.eclipse.org/bugs/show_bug.cgi?id=333284#c19 indicates that it is a possible future feature that nobody worked on. Are you writing your own extension to DSF-GDB? If so, you could change the launch sequence by overriding org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.attachDebuggerToProcess(IProcessDMContext, String, DataRequestMonitor<IDMContext>)

HTH,
Jonah
~~~
Jonah Graham
Kichwa Coders
www.kichwacoders.com


On Tue, 10 Mar 2020 at 08:36, S A <[hidden email]> wrote:
Hi,

to answer my own question, I've noticed our product uses .gdbinit with the following lines:

handle SIGSTOP nostop
handle SIGSTOP noprint

When combined with IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to "true", apparently the CDI/DSF debuggers are unable to suspend.

Our debugger based on DSF unfortunately suspends (all threads) on attach launch, which is not the case for the old implementation based on CDI. We are trying to use ATTR_DEBUGGER_NON_STOP to prevent this. Is there a way to not suspend all threads on attach, that does not involve using ATTR_DEBUGGER_NON_STOP (note that this is not improved by setting ATTR_DEBUGGER_STOP_AT_MAIN to "false")? We can maybe resort to a job that resumes the launch after its started, but it would be great if there is no suspend in the first place.

Best regards,
Simeon

---------- Forwarded message ---------
From: S A <[hidden email]>
Date: Mon, 9 Mar 2020 at 15:36
Subject: How to suspend a DSF debug session?
To: <[hidden email]>


Hi all,

I'm trying to use DSF instead of the old CDI debugger, so far I've managed to trigger debug executions with a custom launch. But I'm having trouble with suspending the debug session from product/test code.

Here is roughly the code at which I've arrived (note that its part of a test):

            IAdaptable context = DebugUITools.getDebugContext();
            IDMContext dmc = context.getAdapter(IDMContext.class);
            DsfSession mi = DsfSession.getSession(dmc.getSessionId());
            IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);
            DsfServicesTracker tracker = new DsfServicesTracker(Activator.getDefault().getBundle().getBundleContext(), mi.getId());
            IRunControl runControl = tracker.getService(IRunControl.class);
            // wait up to 30 seconds for IRunControl.canSuspend() to return true
            ImmediateRequestMonitor suspendRequestMonitor = new ImmediateRequestMonitor(null);
            runControl.suspend(executionContext, suspendRequestMonitor);
            assertTrue("Failed to suspend CDT DSF debug launch", suspendRequestMonitor.isSuccess());
            // wait up to 30 seconds for IRunControl.isSuspended() to return true
            // the wait for suspend times out

I'm seeing this in the error log:

!MESSAGE Request for monitor: 'RequestMonitor (com.verigy.itee.utm.test.debug.TestUtmDebuggerProxy$1@2fddae92): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

Unfortunately I don't know how to continue debugging the DSF code (to find out what the problem is), I see e.g.  "55-exec-interrupt --thread 1" is written to some output stream in AbstractMIControl.TxThread.run(). The respective error stream doesn't contain anything, no lines are read in: AbstractMIControl.ErrorThread. I found bug 509812 (which was fixed in 2017), but nothing else. I also tried increasing the timeout in GDBRunControl_7_0_NS.MonitorSuspendJob.TIMEOUT_DEFAULT_VALUE to 30 seconds, still the same results.

CDT is version 9.6.

GDB version should be: GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7

I'm using IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to true.

The debug execution context is at:

(gdb[0].proc[52864].threadGroup[i1],gdb[0].proc[52864].OSthread[1]).thread[1]

I've added some outputs for writing and reading in AbstractMIControl, here is what I see (it seems fine to me):

[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)
[Mon Mar 09 14:32:10 CET 2020] Wrote: 66-exec-interrupt --thread 1

[Mon Mar 09 14:32:10 CET 2020] Read: 66^done
[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)

!ENTRY org.eclipse.cdt.dsf 4 10005 2020-03-09 14:32:20.502
!MESSAGE Request for monitor: 'RequestMonitor (org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor@331190c1): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

There is only 1 "exec-interrupt" command in the output.

Note that I have no experience with GDB itself, I'm not a C/C++ developer.

Best regards and thanks,
Simeon
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev

_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
S A
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: How to suspend a DSF debug session?

S A
Hi Jonah,

> Are you writing your own extension to DSF-GDB? If so, you could change the launch sequence by overriding org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.attachDebuggerToProcess(IProcessDMContext, String, DataRequestMonitor<IDMContext>)

is there a somewhat elegant way of overwriting the steps from this method? I see that in org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory.createProcessesService(DsfSession) different GDBProcesses objects are created for different GDB versions. Do I actually have to go over all of them and copy tons of code just to add 1 resume step to each attach sequence?

I do see that our old CDI debugger started the launch with a "resume=true" parameter, so I guess I'll have to change the launch sequence as you suggest. But the code in question doesn't seem to be written with overriding the sequence in mind.

Best regards and thanks,
Simeon



On Tue, 10 Mar 2020 at 21:08, Jonah Graham <[hidden email]> wrote:
Hi Simeon,

I am unsure how much you have simplified your test case. Have you hid the async nature of the code?

It appears to me based on what you have provided that you are running outside of the DSF Executor thread, but trying to interact with objects "owned" by the executor thread. i.e. to create a tracker, get a service or call suspend you need to be in the executor thread.

I would expect code that is trying to suspend the target to look like (sorry for indentation loss in email):

IAdaptable context = DebugUITools.getDebugContext();
IDMContext dmc = context.getAdapter(IDMContext.class);
DsfSession mi = DsfSession.getSession(dmc.getSessionId());
IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);

Query<Object> query = new Query<Object>() {
@Override
protected void execute(DataRequestMonitor<Object> rm) {
DsfServicesTracker tracker = new DsfServicesTracker(
Activator.getDefault().getBundle().getBundleContext(), mi.getId());
try {
IRunControl runControl = tracker.getService(IRunControl.class);
runControl.suspend(executionContext, rm);
} finally {
tracker.dispose();
}
}
};

try {
mi.getExecutor().execute(query);
Object result = query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
//  probably don't catch in tests
}
// your target has now suspended.


Now, what I am seeing that doesn't make sense is that there is no *stopped message in your log. With an MI trace you should be able to reproduce outside of Eclipse.

Some other notes that may help:
- You can turn on tracing so you don't have to instrument AbstractMIControl. You can use either the standard tracing in Eclipse (org.eclipse.cdt.dsf.gdb/debug = true) or use the console in your target eclipse (https://wiki.eclipse.org/CDT/User/NewIn92#Hide_gdb_traces_by_default)
- Non-stop has a more complete (and complex) service that extends IRunControl - you can use IMultiRunControl to suspend/resume/control/query multiple threads.
- As for suspending or not in all-stop, I don't know all the ins and outs of that decision, but https://bugs.eclipse.org/bugs/show_bug.cgi?id=333284#c19 indicates that it is a possible future feature that nobody worked on. Are you writing your own extension to DSF-GDB? If so, you could change the launch sequence by overriding org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.attachDebuggerToProcess(IProcessDMContext, String, DataRequestMonitor<IDMContext>)

HTH,
Jonah
~~~
Jonah Graham
Kichwa Coders
www.kichwacoders.com


On Tue, 10 Mar 2020 at 08:36, S A <[hidden email]> wrote:
Hi,

to answer my own question, I've noticed our product uses .gdbinit with the following lines:

handle SIGSTOP nostop
handle SIGSTOP noprint

When combined with IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to "true", apparently the CDI/DSF debuggers are unable to suspend.

Our debugger based on DSF unfortunately suspends (all threads) on attach launch, which is not the case for the old implementation based on CDI. We are trying to use ATTR_DEBUGGER_NON_STOP to prevent this. Is there a way to not suspend all threads on attach, that does not involve using ATTR_DEBUGGER_NON_STOP (note that this is not improved by setting ATTR_DEBUGGER_STOP_AT_MAIN to "false")? We can maybe resort to a job that resumes the launch after its started, but it would be great if there is no suspend in the first place.

Best regards,
Simeon

---------- Forwarded message ---------
From: S A <[hidden email]>
Date: Mon, 9 Mar 2020 at 15:36
Subject: How to suspend a DSF debug session?
To: <[hidden email]>


Hi all,

I'm trying to use DSF instead of the old CDI debugger, so far I've managed to trigger debug executions with a custom launch. But I'm having trouble with suspending the debug session from product/test code.

Here is roughly the code at which I've arrived (note that its part of a test):

            IAdaptable context = DebugUITools.getDebugContext();
            IDMContext dmc = context.getAdapter(IDMContext.class);
            DsfSession mi = DsfSession.getSession(dmc.getSessionId());
            IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);
            DsfServicesTracker tracker = new DsfServicesTracker(Activator.getDefault().getBundle().getBundleContext(), mi.getId());
            IRunControl runControl = tracker.getService(IRunControl.class);
            // wait up to 30 seconds for IRunControl.canSuspend() to return true
            ImmediateRequestMonitor suspendRequestMonitor = new ImmediateRequestMonitor(null);
            runControl.suspend(executionContext, suspendRequestMonitor);
            assertTrue("Failed to suspend CDT DSF debug launch", suspendRequestMonitor.isSuccess());
            // wait up to 30 seconds for IRunControl.isSuspended() to return true
            // the wait for suspend times out

I'm seeing this in the error log:

!MESSAGE Request for monitor: 'RequestMonitor (com.verigy.itee.utm.test.debug.TestUtmDebuggerProxy$1@2fddae92): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

Unfortunately I don't know how to continue debugging the DSF code (to find out what the problem is), I see e.g.  "55-exec-interrupt --thread 1" is written to some output stream in AbstractMIControl.TxThread.run(). The respective error stream doesn't contain anything, no lines are read in: AbstractMIControl.ErrorThread. I found bug 509812 (which was fixed in 2017), but nothing else. I also tried increasing the timeout in GDBRunControl_7_0_NS.MonitorSuspendJob.TIMEOUT_DEFAULT_VALUE to 30 seconds, still the same results.

CDT is version 9.6.

GDB version should be: GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7

I'm using IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to true.

The debug execution context is at:

(gdb[0].proc[52864].threadGroup[i1],gdb[0].proc[52864].OSthread[1]).thread[1]

I've added some outputs for writing and reading in AbstractMIControl, here is what I see (it seems fine to me):

[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)
[Mon Mar 09 14:32:10 CET 2020] Wrote: 66-exec-interrupt --thread 1

[Mon Mar 09 14:32:10 CET 2020] Read: 66^done
[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)

!ENTRY org.eclipse.cdt.dsf 4 10005 2020-03-09 14:32:20.502
!MESSAGE Request for monitor: 'RequestMonitor (org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor@331190c1): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

There is only 1 "exec-interrupt" command in the output.

Note that I have no experience with GDB itself, I'm not a C/C++ developer.

Best regards and thanks,
Simeon
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev

_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: How to suspend a DSF debug session?

Jonah Graham
Hi Simeon,

Yes you are correct, adding a new step in the middle of that sequence is not possible with how it is written. In the past sequences like that have been exposed to have better API for extenders as and when needed (e.g. FinalLaunchSequence).

However, I would guess that it would be best to complete the sequence in the super class before doing the resume, and as such I would add this in the subclass (add appropriate error checking for your use case as well as obtaining the command factory and command control):

@Override
public void attachDebuggerToProcess(IProcessDMContext procCtx, String binaryPath,
        DataRequestMonitor<IDMContext> dataRm) {
    super.attachDebuggerToProcess(procCtx, binaryPath, new ImmediateDataRequestMonitor<IDMContext>(dataRm) {
        @Override
        protected void handleSuccess() {
            IExecutionDMContext dmc = (IExecutionDMContext) getData();
            ICommand<MIInfo> miExecContinue = fCommandFactory.createMIExecContinue(dmc, true);
            fCommandControl.queueCommand(miExecContinue, new ImmediateDataRequestMonitor<MIInfo>(dataRm));
        }
    });
}

HTH,
Jonah


~~~
Jonah Graham
Kichwa Coders
www.kichwacoders.com


On Wed, 11 Mar 2020 at 10:34, S A <[hidden email]> wrote:
Hi Jonah,

> Are you writing your own extension to DSF-GDB? If so, you could change the launch sequence by overriding org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.attachDebuggerToProcess(IProcessDMContext, String, DataRequestMonitor<IDMContext>)

is there a somewhat elegant way of overwriting the steps from this method? I see that in org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory.createProcessesService(DsfSession) different GDBProcesses objects are created for different GDB versions. Do I actually have to go over all of them and copy tons of code just to add 1 resume step to each attach sequence?

I do see that our old CDI debugger started the launch with a "resume=true" parameter, so I guess I'll have to change the launch sequence as you suggest. But the code in question doesn't seem to be written with overriding the sequence in mind.

Best regards and thanks,
Simeon



On Tue, 10 Mar 2020 at 21:08, Jonah Graham <[hidden email]> wrote:
Hi Simeon,

I am unsure how much you have simplified your test case. Have you hid the async nature of the code?

It appears to me based on what you have provided that you are running outside of the DSF Executor thread, but trying to interact with objects "owned" by the executor thread. i.e. to create a tracker, get a service or call suspend you need to be in the executor thread.

I would expect code that is trying to suspend the target to look like (sorry for indentation loss in email):

IAdaptable context = DebugUITools.getDebugContext();
IDMContext dmc = context.getAdapter(IDMContext.class);
DsfSession mi = DsfSession.getSession(dmc.getSessionId());
IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);

Query<Object> query = new Query<Object>() {
@Override
protected void execute(DataRequestMonitor<Object> rm) {
DsfServicesTracker tracker = new DsfServicesTracker(
Activator.getDefault().getBundle().getBundleContext(), mi.getId());
try {
IRunControl runControl = tracker.getService(IRunControl.class);
runControl.suspend(executionContext, rm);
} finally {
tracker.dispose();
}
}
};

try {
mi.getExecutor().execute(query);
Object result = query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
//  probably don't catch in tests
}
// your target has now suspended.


Now, what I am seeing that doesn't make sense is that there is no *stopped message in your log. With an MI trace you should be able to reproduce outside of Eclipse.

Some other notes that may help:
- You can turn on tracing so you don't have to instrument AbstractMIControl. You can use either the standard tracing in Eclipse (org.eclipse.cdt.dsf.gdb/debug = true) or use the console in your target eclipse (https://wiki.eclipse.org/CDT/User/NewIn92#Hide_gdb_traces_by_default)
- Non-stop has a more complete (and complex) service that extends IRunControl - you can use IMultiRunControl to suspend/resume/control/query multiple threads.
- As for suspending or not in all-stop, I don't know all the ins and outs of that decision, but https://bugs.eclipse.org/bugs/show_bug.cgi?id=333284#c19 indicates that it is a possible future feature that nobody worked on. Are you writing your own extension to DSF-GDB? If so, you could change the launch sequence by overriding org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.attachDebuggerToProcess(IProcessDMContext, String, DataRequestMonitor<IDMContext>)

HTH,
Jonah
~~~
Jonah Graham
Kichwa Coders
www.kichwacoders.com


On Tue, 10 Mar 2020 at 08:36, S A <[hidden email]> wrote:
Hi,

to answer my own question, I've noticed our product uses .gdbinit with the following lines:

handle SIGSTOP nostop
handle SIGSTOP noprint

When combined with IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to "true", apparently the CDI/DSF debuggers are unable to suspend.

Our debugger based on DSF unfortunately suspends (all threads) on attach launch, which is not the case for the old implementation based on CDI. We are trying to use ATTR_DEBUGGER_NON_STOP to prevent this. Is there a way to not suspend all threads on attach, that does not involve using ATTR_DEBUGGER_NON_STOP (note that this is not improved by setting ATTR_DEBUGGER_STOP_AT_MAIN to "false")? We can maybe resort to a job that resumes the launch after its started, but it would be great if there is no suspend in the first place.

Best regards,
Simeon

---------- Forwarded message ---------
From: S A <[hidden email]>
Date: Mon, 9 Mar 2020 at 15:36
Subject: How to suspend a DSF debug session?
To: <[hidden email]>


Hi all,

I'm trying to use DSF instead of the old CDI debugger, so far I've managed to trigger debug executions with a custom launch. But I'm having trouble with suspending the debug session from product/test code.

Here is roughly the code at which I've arrived (note that its part of a test):

            IAdaptable context = DebugUITools.getDebugContext();
            IDMContext dmc = context.getAdapter(IDMContext.class);
            DsfSession mi = DsfSession.getSession(dmc.getSessionId());
            IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);
            DsfServicesTracker tracker = new DsfServicesTracker(Activator.getDefault().getBundle().getBundleContext(), mi.getId());
            IRunControl runControl = tracker.getService(IRunControl.class);
            // wait up to 30 seconds for IRunControl.canSuspend() to return true
            ImmediateRequestMonitor suspendRequestMonitor = new ImmediateRequestMonitor(null);
            runControl.suspend(executionContext, suspendRequestMonitor);
            assertTrue("Failed to suspend CDT DSF debug launch", suspendRequestMonitor.isSuccess());
            // wait up to 30 seconds for IRunControl.isSuspended() to return true
            // the wait for suspend times out

I'm seeing this in the error log:

!MESSAGE Request for monitor: 'RequestMonitor (com.verigy.itee.utm.test.debug.TestUtmDebuggerProxy$1@2fddae92): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

Unfortunately I don't know how to continue debugging the DSF code (to find out what the problem is), I see e.g.  "55-exec-interrupt --thread 1" is written to some output stream in AbstractMIControl.TxThread.run(). The respective error stream doesn't contain anything, no lines are read in: AbstractMIControl.ErrorThread. I found bug 509812 (which was fixed in 2017), but nothing else. I also tried increasing the timeout in GDBRunControl_7_0_NS.MonitorSuspendJob.TIMEOUT_DEFAULT_VALUE to 30 seconds, still the same results.

CDT is version 9.6.

GDB version should be: GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7

I'm using IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to true.

The debug execution context is at:

(gdb[0].proc[52864].threadGroup[i1],gdb[0].proc[52864].OSthread[1]).thread[1]

I've added some outputs for writing and reading in AbstractMIControl, here is what I see (it seems fine to me):

[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)
[Mon Mar 09 14:32:10 CET 2020] Wrote: 66-exec-interrupt --thread 1

[Mon Mar 09 14:32:10 CET 2020] Read: 66^done
[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)

!ENTRY org.eclipse.cdt.dsf 4 10005 2020-03-09 14:32:20.502
!MESSAGE Request for monitor: 'RequestMonitor (org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor@331190c1): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

There is only 1 "exec-interrupt" command in the output.

Note that I have no experience with GDB itself, I'm not a C/C++ developer.

Best regards and thanks,
Simeon
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev

_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
S A
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: How to suspend a DSF debug session?

S A
Thanks, works!

On Wed, 11 Mar 2020 at 17:03, Jonah Graham <[hidden email]> wrote:
Hi Simeon,

Yes you are correct, adding a new step in the middle of that sequence is not possible with how it is written. In the past sequences like that have been exposed to have better API for extenders as and when needed (e.g. FinalLaunchSequence).

However, I would guess that it would be best to complete the sequence in the super class before doing the resume, and as such I would add this in the subclass (add appropriate error checking for your use case as well as obtaining the command factory and command control):

@Override
public void attachDebuggerToProcess(IProcessDMContext procCtx, String binaryPath,
        DataRequestMonitor<IDMContext> dataRm) {
    super.attachDebuggerToProcess(procCtx, binaryPath, new ImmediateDataRequestMonitor<IDMContext>(dataRm) {
        @Override
        protected void handleSuccess() {
            IExecutionDMContext dmc = (IExecutionDMContext) getData();
            ICommand<MIInfo> miExecContinue = fCommandFactory.createMIExecContinue(dmc, true);
            fCommandControl.queueCommand(miExecContinue, new ImmediateDataRequestMonitor<MIInfo>(dataRm));
        }
    });
}

HTH,
Jonah


~~~
Jonah Graham
Kichwa Coders
www.kichwacoders.com


On Wed, 11 Mar 2020 at 10:34, S A <[hidden email]> wrote:
Hi Jonah,

> Are you writing your own extension to DSF-GDB? If so, you could change the launch sequence by overriding org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.attachDebuggerToProcess(IProcessDMContext, String, DataRequestMonitor<IDMContext>)

is there a somewhat elegant way of overwriting the steps from this method? I see that in org.eclipse.cdt.dsf.gdb.service.GdbDebugServicesFactory.createProcessesService(DsfSession) different GDBProcesses objects are created for different GDB versions. Do I actually have to go over all of them and copy tons of code just to add 1 resume step to each attach sequence?

I do see that our old CDI debugger started the launch with a "resume=true" parameter, so I guess I'll have to change the launch sequence as you suggest. But the code in question doesn't seem to be written with overriding the sequence in mind.

Best regards and thanks,
Simeon



On Tue, 10 Mar 2020 at 21:08, Jonah Graham <[hidden email]> wrote:
Hi Simeon,

I am unsure how much you have simplified your test case. Have you hid the async nature of the code?

It appears to me based on what you have provided that you are running outside of the DSF Executor thread, but trying to interact with objects "owned" by the executor thread. i.e. to create a tracker, get a service or call suspend you need to be in the executor thread.

I would expect code that is trying to suspend the target to look like (sorry for indentation loss in email):

IAdaptable context = DebugUITools.getDebugContext();
IDMContext dmc = context.getAdapter(IDMContext.class);
DsfSession mi = DsfSession.getSession(dmc.getSessionId());
IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);

Query<Object> query = new Query<Object>() {
@Override
protected void execute(DataRequestMonitor<Object> rm) {
DsfServicesTracker tracker = new DsfServicesTracker(
Activator.getDefault().getBundle().getBundleContext(), mi.getId());
try {
IRunControl runControl = tracker.getService(IRunControl.class);
runControl.suspend(executionContext, rm);
} finally {
tracker.dispose();
}
}
};

try {
mi.getExecutor().execute(query);
Object result = query.get(TestsPlugin.massageTimeout(500), TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
//  probably don't catch in tests
}
// your target has now suspended.


Now, what I am seeing that doesn't make sense is that there is no *stopped message in your log. With an MI trace you should be able to reproduce outside of Eclipse.

Some other notes that may help:
- You can turn on tracing so you don't have to instrument AbstractMIControl. You can use either the standard tracing in Eclipse (org.eclipse.cdt.dsf.gdb/debug = true) or use the console in your target eclipse (https://wiki.eclipse.org/CDT/User/NewIn92#Hide_gdb_traces_by_default)
- Non-stop has a more complete (and complex) service that extends IRunControl - you can use IMultiRunControl to suspend/resume/control/query multiple threads.
- As for suspending or not in all-stop, I don't know all the ins and outs of that decision, but https://bugs.eclipse.org/bugs/show_bug.cgi?id=333284#c19 indicates that it is a possible future feature that nobody worked on. Are you writing your own extension to DSF-GDB? If so, you could change the launch sequence by overriding org.eclipse.cdt.dsf.gdb.service.IGDBProcesses.attachDebuggerToProcess(IProcessDMContext, String, DataRequestMonitor<IDMContext>)

HTH,
Jonah
~~~
Jonah Graham
Kichwa Coders
www.kichwacoders.com


On Tue, 10 Mar 2020 at 08:36, S A <[hidden email]> wrote:
Hi,

to answer my own question, I've noticed our product uses .gdbinit with the following lines:

handle SIGSTOP nostop
handle SIGSTOP noprint

When combined with IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to "true", apparently the CDI/DSF debuggers are unable to suspend.

Our debugger based on DSF unfortunately suspends (all threads) on attach launch, which is not the case for the old implementation based on CDI. We are trying to use ATTR_DEBUGGER_NON_STOP to prevent this. Is there a way to not suspend all threads on attach, that does not involve using ATTR_DEBUGGER_NON_STOP (note that this is not improved by setting ATTR_DEBUGGER_STOP_AT_MAIN to "false")? We can maybe resort to a job that resumes the launch after its started, but it would be great if there is no suspend in the first place.

Best regards,
Simeon

---------- Forwarded message ---------
From: S A <[hidden email]>
Date: Mon, 9 Mar 2020 at 15:36
Subject: How to suspend a DSF debug session?
To: <[hidden email]>


Hi all,

I'm trying to use DSF instead of the old CDI debugger, so far I've managed to trigger debug executions with a custom launch. But I'm having trouble with suspending the debug session from product/test code.

Here is roughly the code at which I've arrived (note that its part of a test):

            IAdaptable context = DebugUITools.getDebugContext();
            IDMContext dmc = context.getAdapter(IDMContext.class);
            DsfSession mi = DsfSession.getSession(dmc.getSessionId());
            IExecutionDMContext executionContext = DMContexts.getAncestorOfType(dmc, IExecutionDMContext.class);
            DsfServicesTracker tracker = new DsfServicesTracker(Activator.getDefault().getBundle().getBundleContext(), mi.getId());
            IRunControl runControl = tracker.getService(IRunControl.class);
            // wait up to 30 seconds for IRunControl.canSuspend() to return true
            ImmediateRequestMonitor suspendRequestMonitor = new ImmediateRequestMonitor(null);
            runControl.suspend(executionContext, suspendRequestMonitor);
            assertTrue("Failed to suspend CDT DSF debug launch", suspendRequestMonitor.isSuccess());
            // wait up to 30 seconds for IRunControl.isSuspended() to return true
            // the wait for suspend times out

I'm seeing this in the error log:

!MESSAGE Request for monitor: 'RequestMonitor (com.verigy.itee.utm.test.debug.TestUtmDebuggerProxy$1@2fddae92): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

Unfortunately I don't know how to continue debugging the DSF code (to find out what the problem is), I see e.g.  "55-exec-interrupt --thread 1" is written to some output stream in AbstractMIControl.TxThread.run(). The respective error stream doesn't contain anything, no lines are read in: AbstractMIControl.ErrorThread. I found bug 509812 (which was fixed in 2017), but nothing else. I also tried increasing the timeout in GDBRunControl_7_0_NS.MonitorSuspendJob.TIMEOUT_DEFAULT_VALUE to 30 seconds, still the same results.

CDT is version 9.6.

GDB version should be: GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-100.el7

I'm using IGDBLaunchConfigurationConstants.ATTR_DEBUGGER_NON_STOP set to true.

The debug execution context is at:

(gdb[0].proc[52864].threadGroup[i1],gdb[0].proc[52864].OSthread[1]).thread[1]

I've added some outputs for writing and reading in AbstractMIControl, here is what I see (it seems fine to me):

[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)
[Mon Mar 09 14:32:10 CET 2020] Wrote: 66-exec-interrupt --thread 1

[Mon Mar 09 14:32:10 CET 2020] Read: 66^done
[Mon Mar 09 14:32:10 CET 2020] Read: (gdb)

!ENTRY org.eclipse.cdt.dsf 4 10005 2020-03-09 14:32:20.502
!MESSAGE Request for monitor: 'RequestMonitor (org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor@331190c1): Status ERROR: org.eclipse.cdt.dsf.gdb code=10004 Suspend operation timeout. null' resulted in an error.

There is only 1 "exec-interrupt" command in the output.

Note that I have no experience with GDB itself, I'm not a C/C++ developer.

Best regards and thanks,
Simeon
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev
_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev

_______________________________________________
cdt-dev mailing list
[hidden email]
To unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/cdt-dev