Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Language IDEs » C / C++ IDE (CDT) » Support for multithread stack in Debug view(Support for multithread stack in Debug view)
Support for multithread stack in Debug view [message #1767426] Thu, 06 July 2017 02:16 Go to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
I am extending Eclipse CDT plugin for our MCU. I have implemented Remote Debugging Launcher feature by implementing launch configuration types and launch delegates. I am now implementing FreeRTOS thread-aware debugging feature.

So far, I have already created views for Task list, Queue list, Timer list and Heap usage by reading the values of the FreeRTOS kernel global variables (like uxCurrentNumberOfTasks, pxCurrentTCB, xQueueRegistry, etc). Now I have to make the built-in Debug view show the stack of all threads/tasks. Currently, the Debug view shows only the stack of 1 task - the suspended running task.

Based on the gdb logs, Eclipse CDT queries our custom GDB with the MI command -list-thread-groups and it returns an array of only 1 task.
threads=[{id="1",target-id="Thread 1",details="Runnable",frame={level="1",addr="0x00003e2c",func="prvPrintTask",args=[{name="pvParameters",value="0x800cd8"}],file="../free_rtos_example\
3.c",fullname="C:\\free_rtos_example3.c",line="781"},state="stopped"}]
Since the GDB is not aware that MCU is running on FreeRTOS, then it does not know that there are more than 1 thread. In fact, GDB "info threads" always return 1 thread.

To support multiple thread stack in the Debug view, I think that I need to replace the Eclipse CDT to query the FreeRTOS task global variables (similar to what I did for the Task list view) instead of querying -list-thread-groups. This query happens when the debug session is suspended. So I need to know where the class where CDT sends an MI command during suspend.

Am I correct? What classes, extension points do I need to extend or implement? Any help will be appreciated. Thank you.

Regards,
Richmond

Re: Support for multithread stack in Debug view [message #1767571 is a reply to message #1767426] Fri, 07 July 2017 08:25 Go to previous messageGo to next message
Jonah Graham is currently offline Jonah GrahamFriend
Messages: 397
Registered: June 2014
Senior Member
Try providing your own implementation of either IProcesses (or more likely one of its sub-interfaces like IGDBProcesses, or extending existing classes), or if just the command need replacing but the rest of the logic in GDBProcesses_* is correct and you simply want to issue your own command you can extend CommandFactory and override the various createMIListThreadGroups.

Does that help in getting you started?

That said, before you start from scratch I would recommend considering one of the existing implementations of FreeRTOS support for Eclipse before spinning up a new one. For example, see http://www.codeconfidence.com/freertos-tools.shtml MCU On Eclipse wrote a good article a couple of years ago too: https://mcuoneclipse.com/2015/10/03/freertos-arm-thread-debugging-with-eclipse-and-gdb/
Re: Support for multithread stack in Debug view [message #1767586 is a reply to message #1767426] Fri, 07 July 2017 09:34 Go to previous messageGo to next message
John Dallaway is currently offline John DallawayFriend
Messages: 13
Registered: July 2009
Junior Member
Hi Richmond

Since GDB already supports multi-threaded debugging, you will find it much easier to implement task aware debugging as a layer underneath GDB rather than on top of it. This is the approach taken by ThreadSpy: http://www.codeconfidence.com/threadspy

Regards

John Dallaway
Re: Support for multithread stack in Debug view [message #1767590 is a reply to message #1767571] Fri, 07 July 2017 10:09 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
Hi Jonah,


Thank you. I searched of -list-thread-groups keyword and also arrived at CommandFactory. To extend CommandFactory, it seems I have to newServiceFactory() in GdbLaunchDelegate and extend ServiceFactoriesManager, GdbDebugServicesFactory, CommandFactory_6_8, CommandFactory. Will try to work on this track.

As for Code Confidence, the plugin downloaded via Eclipse from http://www.highintegritysystems.com/StateViewer/ do not support multi-thread stack in Debug view. It only supports custom views for task, queues and timers.


Regards,
Richmond

Jonah Graham wrote on Fri, 07 July 2017 08:25
Try providing your own implementation of either IProcesses (or more likely one of its sub-interfaces like IGDBProcesses, or extending existing classes), or if just the command need replacing but the rest of the logic in GDBProcesses_* is correct and you simply want to issue your own command you can extend CommandFactory and override the various createMIListThreadGroups.

Does that help in getting you started?

That said, before you start from scratch I would recommend considering one of the existing implementations of FreeRTOS support for Eclipse before spinning up a new one. For example, see http://www.codeconfidence.com/freertos-tools.shtml MCU On Eclipse wrote a good article a couple of years ago too: https://mcuoneclipse.com/2015/10/03/freertos-arm-thread-debugging-with-eclipse-and-gdb/

Re: Support for multithread stack in Debug view [message #1767592 is a reply to message #1767586] Fri, 07 July 2017 10:23 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
Hi John,

Thanks. Yes, ThreadSpy seems to work outside of the plugin but inside the toolchain. "It intercepts thread-related queries raised by GDB and provides responses to these queries from its own configurable model of kernel thread states." So ThreadSpy will intercept GDB commands like -list-thread-groups and reply to it by reading FreeRTOS kernel global variables. This is an interesting approach and does not need CDT knowledge so it is easier to implement. I will try this approach as well.

Regards,
Richmond


John Dallaway wrote on Fri, 07 July 2017 09:34
Hi Richmond

Since GDB already supports multi-threaded debugging, you will find it much easier to implement task aware debugging as a layer underneath GDB rather than on top of it. This is the approach taken by ThreadSpy: http://www.codeconfidence.com/threadspy

Regards

John Dallaway

Re: Support for multithread stack in Debug view [message #1767608 is a reply to message #1767592] Fri, 07 July 2017 14:24 Go to previous messageGo to next message
John Dallaway is currently offline John DallawayFriend
Messages: 13
Registered: July 2009
Junior Member
Hi Richmond

Richmond Umagat wrote on Fri, 07 July 2017 11:23
So ThreadSpy will intercept GDB commands like -list-thread-groups and reply to it by reading FreeRTOS kernel global variables.


To be clear, it is the remote protocol queries issued by GDB (such as "qfThreadInfo") which are intercepted by ThreadSpy, not the GDB/MI commands issued by CDT.

Regards

John Dallaway
Re: Support for multithread stack in Debug view [message #1767725 is a reply to message #1767608] Mon, 10 July 2017 11:01 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
Hi John,


Thanks for the clarification. Yes, I do observe calls like qfThreadInfo, qsThreadInfo, qThreadExtraInfo in our GDB bridge python application.


Regards,
Richmond

John Dallaway wrote on Fri, 07 July 2017 14:24
Hi Richmond

To be clear, it is the remote protocol queries issued by GDB (such as "qfThreadInfo") which are intercepted by ThreadSpy, not the GDB/MI commands issued by CDT.

Regards

John Dallaway

Re: Support for multithread stack in Debug view [message #1767789 is a reply to message #1767590] Tue, 11 July 2017 07:23 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
Hi Jonah,

I've extended GdbDebugServicesFactory which is called in the extended GdbLaunchDelegate. The extended GdbDebugServicesFactory overrides createCommandControl and createProcessesService. createCommandControl is for calling the extended CommandFactory_6_8 which overrides createMIListThreadGroups while createProcessesService is for calling the extended GDBProcesses_7_10 which overrides GDBProcesses_7_0 getProcessesBeingDebugged() and GDBProcesses_7_1 getExecutionData().

Overriding createMIListThreadGroups do not seem to be proper as this only creates the command that will be executed by getProcessesBeingDebugged() in GDBProcesses_7_0. I've override getProcessesBeingDebugged() instead by extending GDBProcesses_7_10 but getProcessesBeingDebugged() has many dependencies on the file that makes it complicated. I can just pass a simulated MIThreads[] to the DataRequestMonitor but MIThreads[] constructor is protected so I need to construct MIOutput and MIThreadInfoInfo instead of MIThreads.

Is this path possible? Is there class I can extend to override a function like getThreadList(), where I can simply provide my own MIThreads[] array to replace the one retrieved from the result of createMIListThreadGroups command execution?

Regards,
Richmond



Richmond Umagat wrote on Fri, 07 July 2017 10:09
Hi Jonah,


Thank you. I searched of -list-thread-groups keyword and also arrived at CommandFactory. To extend CommandFactory, it seems I have to newServiceFactory() in GdbLaunchDelegate and extend ServiceFactoriesManager, GdbDebugServicesFactory, CommandFactory_6_8, CommandFactory. Will try to work on this track.

As for Code Confidence, the plugin downloaded via Eclipse from http://www.highintegritysystems.com/StateViewer/ do not support multi-thread stack in Debug view. It only supports custom views for task, queues and timers.


Regards,
Richmond

Jonah Graham wrote on Fri, 07 July 2017 08:25
Try providing your own implementation of either IProcesses (or more likely one of its sub-interfaces like IGDBProcesses, or extending existing classes), or if just the command need replacing but the rest of the logic in GDBProcesses_* is correct and you simply want to issue your own command you can extend CommandFactory and override the various createMIListThreadGroups.

Does that help in getting you started?

That said, before you start from scratch I would recommend considering one of the existing implementations of FreeRTOS support for Eclipse before spinning up a new one. For example, see http://www.codeconfidence.com/freertos-tools.shtml MCU On Eclipse wrote a good article a couple of years ago too: https://mcuoneclipse.com/2015/10/03/freertos-arm-thread-debugging-with-eclipse-and-gdb/


Re: Support for multithread stack in Debug view [message #1767797 is a reply to message #1767789] Tue, 11 July 2017 08:33 Go to previous messageGo to next message
Jonah Graham is currently offline Jonah GrahamFriend
Messages: 397
Registered: June 2014
Senior Member
Hi Richmond,

If you submit a patch that provides some refactoring to the version in CDT now, I would be happy to review it. The good thing about DSF is you can replace any service with your own implementation, so you can simply copy* GDBProcesses_7_0 and make the modifications you need.

My guess is you want to do something between the async return of createMIListThreadGroups and the call to makeExecutionDMCs? Remember, if you submit that change back to CDT, that overridable methods are written asynchronously so, if needed, other extenders can provide multiple steps.

HTH
Jonah


* consider licensing when you do

Re: Support for multithread stack in Debug view [message #1768028 is a reply to message #1767797] Thu, 13 July 2017 06:36 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
Hi Jonah,

Thanks, I am now able to put up multiple dummy threads in the Debug view by implementing both getProcessesBeingDebugged() and getExecutionData() - providing dummy threads created using MIThreadInfoInfo and MIOutput to the DataRequestMonitor.

Now, I am trying to query the FreeRTOS kernel global variables to replace the dummy threads with the real thread names, ids, state. To query the FreeRTOS kernel global variables, I am using IExpressionDMContext (similar to what I used in the Task View feature). IExpressionDMContext requires an IExecutionDMContext. I've tried retrieving IExecutionDMContext from both getProcessesBeingDebugged() and getExecutionData() but it doesn't work. I also tried implementing event handler eventDispatched(ISuspendedDMEvent e) for e.getDMContext() but it also does not work.

How do I get a valid IExecutionDMContext for use of IExpressionDMContext in getProcessesBeingDebugged() and getExecutionData()?

Thanks,
Richmond
Re: Support for multithread stack in Debug view [message #1768034 is a reply to message #1768028] Thu, 13 July 2017 07:15 Go to previous messageGo to next message
Jonah Graham is currently offline Jonah GrahamFriend
Messages: 397
Registered: June 2014
Senior Member
Hi Richmond,

I think I am misunderstanding the question. getProcessesBeingDebugged() job is to create and return IExecutionDMContexts.

Jonah

PS My company provides Eclipse consultancy and we have specific experience in DSF. Please be in touch with me: jonah at kichwacoders.com and we can set up a meeting to discuss your needs?
Re: Support for multithread stack in Debug view [message #1768057 is a reply to message #1768034] Thu, 13 July 2017 10:26 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
Hi Jonah,

Thanks. Its working now. I made the event handler eventDispatched(ISuspendedDMEvent e) run inside a Runnable object then executed it via DebugPlugin.getDefault().asyncExec().

Next issue would be determining the stack trace for each of the FreeRTOS tasks. There are no FreeRTOS global kernel variables for function call stack. Any idea how to retrieve that?

Regards,
Richmond
Re: Support for multithread stack in Debug view [message #1768058 is a reply to message #1768057] Thu, 13 July 2017 10:40 Go to previous messageGo to next message
Jonah Graham is currently offline Jonah GrahamFriend
Messages: 397
Registered: June 2014
Senior Member
Not sure off the top of my head.
Re: Support for multithread stack in Debug view [message #1769073 is a reply to message #1768058] Wed, 26 July 2017 09:37 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
When a breakpoint is triggered, it always use thread-id="1". This leads to CDT querying the call stack of task 1. In order for CDT to query stack of the active task X, I think I need to modify the breakpoint notification to specify the correct thread-id number. Are there any callback in CDT where I can modify this breakpoint trigger notification?
Re: Support for multithread stack in Debug view [message #1769074 is a reply to message #1769073] Wed, 26 July 2017 09:51 Go to previous messageGo to next message
Jonah Graham is currently offline Jonah GrahamFriend
Messages: 397
Registered: June 2014
Senior Member
I thin you want to customize (provide your own) MIRunControlEventProcessor<version>, look at createEvent method where it converts thread-id into a DMC
Re: Support for multithread stack in Debug view [message #1769156 is a reply to message #1769074] Thu, 27 July 2017 07:24 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
Thanks. Spot on.

I extended MIRunControlEventProcessor and override eventReceived() to replace the thread-id value 1 to value the thread id of the active task. After the modifications, CDT is now querying the stack trace of the active task.
However, CDT is also querying the stack trace of all tasks that are already expanded, that is all tasks that were previously queried. I only want to show the stack trace of the active task. How can I programmatically prevent that? (Having an 'error' response to the non-active task doesn't make the stack trace disappear.)
Re: Support for multithread stack in Debug view [message #1769172 is a reply to message #1769156] Thu, 27 July 2017 08:59 Go to previous messageGo to next message
Jonah Graham is currently offline Jonah GrahamFriend
Messages: 397
Registered: June 2014
Senior Member
Quote:
I only want to show the stack trace of the active task.


My guess is that will require changing the view model rather than the data model, but you might be able to fake it with a data model change.


Option 1: For the view model you need to change ThreadVMNode.updateElementsInSessionThread(IChildrenUpdate) or similar to only add the desired tasks to the list of threads. However, If you are modelling your tasks as processes, look at ContainerVMNode.updateElementsInSessionThread(IChildrenUpdate) instead.

Option 2: For the data model you need to change getProcessesBeingDebugged to only return the active task, not all of them.


My two cents is it seems like a bad idea, as a user I would certainly like to see stack traces of all stacks if possible, perhaps it isn't possible in your design. :-)
Re: Support for multithread stack in Debug view [message #1769241 is a reply to message #1769172] Fri, 28 July 2017 07:29 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
I ended up implementing updateHasElementsInSessionThread() of StackFramesVMNode. If the task being queried is not the active task, then I report setHasChilren to false. This leads CDT to query the stack of only the active task.

Now that this version is already working, I can now work on supporting stack traces of non-active tasks. To support stack trace of non-active tasks, I think I have 2 options:
Option 1: given the stack address in the TCB, read and parse the memory for the function name, file name, line number.
Option 2: while suspended, do context switch to a non-active task to make it active. once it is active, query the call stack and then restore the original active task. ErichStyger provides some script for ARM achitecture. https://github.com/ErichStyger/McuOnEclipse_PEx/blob/master/Drivers/freeRTOS/gdbBacktraceDebug/

Any thoughts will be appreciated. Thanks.
Re: Support for multithread stack in Debug view [message #1769249 is a reply to message #1769241] Fri, 28 July 2017 08:54 Go to previous messageGo to next message
Jonah Graham is currently offline Jonah GrahamFriend
Messages: 397
Registered: June 2014
Senior Member
No additional thoughts, have fun with this.
Re: Support for multithread stack in Debug view [message #1769584 is a reply to message #1769249] Wed, 02 August 2017 01:52 Go to previous messageGo to next message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
Is it possible for Eclipse CDT plugin to READ and MODIFY the macro definitions in a header file of a C application?
I need to provide a user interface to display the macro values in FreeRTOSConfig.h and allow user to customize the values. Is that possible?
Another option is to ignore user-provided FreeRTOSConfig.h and completely RECREATE FreeRTOSConfig.h based on user-provided values.
Re: Support for multithread stack in Debug view [message #1769621 is a reply to message #1769584] Wed, 02 August 2017 08:52 Go to previous messageGo to next message
Jonah Graham is currently offline Jonah GrahamFriend
Messages: 397
Registered: June 2014
Senior Member
Please start a new thread on this new topic. Short answer is yes (look up refactoring support), but other people are more suited to this and they won't see this new comment deep in this comment thread.
Re: Support for multithread stack in Debug view [message #1772231 is a reply to message #1769621] Thu, 07 September 2017 01:44 Go to previous message
Richmond Umagat is currently offline Richmond UmagatFriend
Messages: 17
Registered: July 2017
Junior Member
Hi, I am encountering exception in DfsSession CDT code. Could anyone help what could cause the issue. The issue doesn't happen always so its a timing issue related. What could be the cause of the issue? Thanks.

!STACK 0
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor50.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.cdt.dsf.service.DsfSession.doDispatchEvent(DsfSession.java:531)
at org.eclipse.cdt.dsf.service.DsfSession.access$2(DsfSession.java:475)
at org.eclipse.cdt.dsf.service.DsfSession$3.run(DsfSession.java:398)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock.eventDispatched(DsfMemoryBlock.java:719)
at org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlock.eventDispatched(GdbMemoryBlock.java:163)
... 13 more
Root exception:
java.lang.NullPointerException
at org.eclipse.cdt.dsf.debug.model.DsfMemoryBlock.eventDispatched(DsfMemoryBlock.java:719)
at org.eclipse.cdt.dsf.gdb.internal.memory.GdbMemoryBlock.eventDispatched(GdbMemoryBlock.java:163)
at sun.reflect.GeneratedMethodAccessor50.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.cdt.dsf.service.DsfSession.doDispatchEvent(DsfSession.java:531)
at org.eclipse.cdt.dsf.service.DsfSession.access$2(DsfSession.java:475)
at org.eclipse.cdt.dsf.service.DsfSession$3.run(DsfSession.java:398)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Previous Topic:Rpath on Windows
Next Topic:Type 'std::thread' could not be resolved with Eclipse 4.7 (Oxygen)
Goto Forum:
  


Current Time: Wed Dec 13 11:27:44 GMT 2017

Powered by FUDForum. Page generated in 0.02152 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software