| Summary: | [Pin&Clone] TimeoutException when pinning with GDB >= 7.1 | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Tools] CDT | Reporter: | Marc Khouzam <marc.khouzam> | ||||
| Component: | cdt-debug-dsf-gdb | Assignee: | Project Inbox <cdt-debug-dsf-gdb-inbox> | ||||
| Status: | NEW --- | QA Contact: | Jonah Graham <jonah> | ||||
| Severity: | normal | ||||||
| Priority: | P3 | CC: | anders, bruno.do.medeiros, cdtdoug, jonah, marc.dumais, pawel.1.piech, torbjorn.svensson, vinod.appu | ||||
| Version: | 8.0 | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Linux | ||||||
| See Also: | https://git.eclipse.org/r/c/cdt/org.eclipse.cdt/+/180690 | ||||||
| Whiteboard: | |||||||
| Attachments: |
|
||||||
|
Description
Marc Khouzam
Alternate way to reproduce this issue: 1- run a program that creates threads, with GDB >= 7.1 and non-stop 2- pin the variable view to a thread 3- step over a line of code that creates a new thread Note: a very similar exception happens if we instead pin another debug view: Expression and Registers, at least. The mechanism is probably exactly the same as described in first comment, just triggered in a different VMNode. For example, if the Expressions view is pinned instead of the variables view: java.util.concurrent.TimeoutException at org.eclipse.cdt.dsf.concurrent.Query.get(Query.java:126) at org.eclipse.cdt.dsf.gdb.internal.ui.GdbPinProvider.getData(GdbPinProvider.java:156) at org.eclipse.cdt.dsf.gdb.internal.ui.GdbPinProvider.getCombinedLabels(GdbPinProvider.java:181) at org.eclipse.cdt.dsf.gdb.internal.ui.GdbPinProvider.isPinnedTo(GdbPinProvider.java:283) at org.eclipse.cdt.debug.internal.ui.pinclone.PinCloneUtils.isPinnedTo(PinCloneUtils.java:254) at org.eclipse.cdt.dsf.gdb.internal.ui.viewmodel.launch.ContainerVMNode.updatePropertiesInSessionThread(ContainerVMNode.java:312) at org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.AbstractContainerVMNode$2.run(AbstractContainerVMNode.java:138) at org.eclipse.cdt.dsf.concurrent.DefaultDsfExecutor$TracingWrapperRunnable.run(DefaultDsfExecutor.java:374) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Is this still an open issue? (In reply to Vinod Appu from comment #2) > Is this still an open issue? I would expect so. Have you hit a similar issue? Yes, I'm looking into it. I can see due to some reason the below if is not always good enough to return null (Inside GdbPinProvider.java, line 129) when terminate button is pressed. At times the session is active and it goes further down to a wait(2 second) which won't be notified.
private IThreadDMData getData(final IThreadDMContext threadDmc) {
if (threadDmc == null || !fSession.isActive())
return null;
............
............
Any thoughts?
I am not 100% sure I follow - Is the case at line 130 that the session is active, but by the time the query runs the session has terminated? If so, then this should just be a handled error, not even logged. Are you getting a TimeoutException or a RejectedExecutionException? Are you hitting the deadlock described in Comment 0? That deadlock is not at session termination, but during the session IIUC. (In reply to Jonah Graham from comment #5) > Are you getting a TimeoutException or a RejectedExecutionException? There is a race condition between immediateExecutor.execute(query); and data = query.get(2, TimeUnit.SECONDS); that means you may not get the RejectedExecutionException and will just timeout when you do the get. I'm getting timeout exception only. I got confused since I couldn't able to reproduce when I tried with only Eclipse + CDT where as I'm always getting it from our own custom product. Now I understand that it's a matter of timing to get the issue. The problem we are facing is this issue is hitting us in a multicore debugging session with view pinned => End user has to wait ~6seconds or more on any of the debug operations. Any way out you think? Created attachment 286336 [details]
Hack for the issue
I'm planning the above hack to get rid of the issue at the moment. Am I going to miss something with this?
(In reply to Vinod Appu from comment #8) > Created attachment 286336 [details] > Hack for the issue > > I'm planning the above hack to get rid of the issue at the moment. Am I > going to miss something with this? Please provide this as a gerrit and I can review it properly. As a picture I can't even copy&paste it into Eclipse. Getting "fatal: http://git.eclipse.org:29418/cdt/org.eclipse.cdt.git/info/refs not valid: is this a git repository?" when try git push gerrit HEAD:refs/for/master I've tried to follow https://kichwacoders.com/2017/05/03/getting-started-with-gerrit-on-eclipse-cdt/ This is my first ever commit, please guide me. I answered a longer answer with screenshots/etc in https://mattermost.eclipse.org/eclipse/ Quick answer is it looks like the URL is incorrect. Get the correct URL from https://git.eclipse.org/r/admin/repos/cdt/org.eclipse.cdt while logged on. New Gerrit change created: https://git.eclipse.org/r/c/cdt/org.eclipse.cdt/+/180690 (In reply to Marc Khouzam from comment #0) > The implementation of IProcesses.getExecutionData() for GDB <= 7.0 is > entirely local so does not need to send a command to GDB. However, starting > with GDB 7.1, [...] This is no longer true - since Bug 497592 even GDB 7.0 can make requests. However the change in 497592 ameliorates the case because the command is likely to be cached, meaning no further roundtrip to GDB needed and that means the Query can be run in the executor thread. BTW I cannot reliably reproduce this bug, I think because of Bug 497592. I have seen an occasional timeout when fast stepping or similar, but even then I am not getting a UI freeze, only a Executor freeze. (Although an executor freeze can cause a UI freeze if any Query is made on the main thread while the executor is frozen.) It generally is a bad idea to use Query (or anything blocking) in executor thread. I believe the proper fix is to refactor the code so that the Query is always outside the executor thread or otherwise removed. This is somewhat easy to do, simply create a new IDsfPinProvider that has all the methods with an async style that may eventually call getExecutionData. The methods in IPinProvider then effectively become ThreadSafeAndProhibitedFromDsfExecutor (can't actually apply that annotation because of cyclic dependency) and the methods in IDsfPinProvider become ConfinedToDsfExecutor. Only the methods called in the executor thread need to be added to IDsfPinProvider -- AFAICT that is only isPinnedTo. @Vinod - does that make sense? Yes, I thought of get rid of Query first then I go for the hack for a quick solution. I'll try your suggestion and give an update. |