eclipse-plugins
eclipse-plugins copied to clipboard
JLinkGDBServerCL.exe Windows tray icons do not disappear
Hello there, I have posted a topic on segger forums about the windows icon not dissapearing after succesfull programing in Eclipse:
http://forum.segger.com/index.php?page=Thread&postID=9013#post9013
But they seem to be blaming the plugin- that it doesnt close properly. Could you relate please? I would apreciate all help!
My experience and testing capabilities with Windows are limited; are you sure you are using the CL (command line) version of the server? Normally there should be no icons for internal command line processes.
Yes, I am using all tools within the eclipse plugin. Ps: this occurs when using RUN configuration.
Please provide a screenshot of the Preferences -> Run/Debug -> String Substitution window.
Here:
seems ok.
please provide more details (like how do you terminate the debug session), in order to reproduce the problem.
Its the way i said in this topic: https://github.com/gnuarmeclipse/plug-ins/issues/8
I use RUN configuration, the board is programmed but jlink is not detached. I then click terminare (like terminating debug session). The tray then remains.
I then click terminare (like terminating debug session)
you can terminate a debug session in many ways. which process is selected when you terminate the session, and which button do you push?
I gues its the only process running for the jlink:
by clicking that red square button you are brutally killing the jlink gdb server process.
probably it is not prepared to gracefully die in this situation.
try terminating the application in the Debug perspective, this should issue the terminating commands to GDB client, which should nicely terminate the J-Link GDB server process.
I did that as well, im quite sure i am killing the same thing.
as I said, this is wrong, you have to kill the debugged process, not the GDB client or server.
But how can i terminate the process then? Theres the same button everywhere. I just checked in the debug view, its the same behaviour.
try terminating the application in the Debug perspective
explicitly, this means:
- go to the debug perspective
- select the .elf process, in the top left window
- click the toolbar red square terminate button
this is the normal way to terminate any debugging session.
clicking the terminate button in the console window just kills the associated process.
similarly, selecting another process in the top left window and clicking the toolbar terminate, kills that process, not the application.
the plug-in has a lot of logic to detect when one of the processes dies or is brutally killed, to terminate the application and the other processes, but if you just kill directly the J-Link GDB server, it is simply gone, don't expect a graceful termination.
I did it accrording to your instruction- the tray icon stays.
I was finally able to test it on Windows (actually on a friend's computer) and you are right, the J-Link icon remains in the tray.
The reason is probably the one mentioned by SEGGER, the terminating logic is quite complicated, and it is quite likely that the process is finally killed.
But the point is completely different: why does a background process display a tray icon at all? In my opinion it shouldn't, and this would simply avoid the problem.
I reported the problem to SEGGER.
Thank you :)
Any news about this one? We're observing the same issue and it is quite annoying.
Its a J-Link software issue but they not seem to care about it: http://www.forum.segger.com/index.php?page=Thread&postID=9013&highlight=#post9013
I think this topic needs to be reopened. I am writing a tool to do some extra debugging and essentially it is a proxy server that sits between the GNU arm eclipse GDB client handling and the JLink GDB server. So basically instead of having the GNU ARM eclipse debug configuration launch jlinkgdbservercl, it launches my tool. My tool then internally launches jlinkgdbservercl and connects to it. The GDB client from eclipse then sends server GDB RSP commands to my tool and I forward them back and forth between jlinkgdbservercl. This works perfectly. However when I press the terminate button as you have suggested in the debug perspective, the JLink GDB server tray icon stays in the bottom right until I hover over it and it disappears, because the actual jlinkgdbserver process has been killed incorrectly.
The reason this happens is because I have figured out that something is forcibly terminating my tool process, and the only thing that would do that is the GNU ARM eclipse Jlink plugin OR the GDB client. I don't think its the GDB client. The reason I know my process is being forcibly terminated when I press the terminate button in the debug perspective is that I have a while loop inside my tool that keeps the program alive under all circumstances. The only thing that can kill my tool process is a task kill from another process or the task manager.
If you just run jlinkgdbservercl instead of my tool, upon the terminate action, the tray icon stays in the bottom right.
Here is a test you can run: Open jlinkgdbservercl from the command line with proper arguments (make sure you have -singlerun) and connect to a jlink and then see the "waiting for gdb connection..." text. Connect to the jlinkgdbserver through a client and then disconnect from the client and notice that the JLink GDB server shuts down gracefully. Run the jlinkgdbservercl from the command line again.. and now instead of connecting through a client, forcibly kill the jlinkgdbservercl process from the task manager. You will notice the tray icon is still there until you hover over it (this bug).
From the previous discussion, I am 99% sure this is a problem in the GNU ARM Jlink plugin and not segger's jlinkgdbserver. If any program has a tray icon and you forcibly kill the process associated with it in task manager, you will notice the exact same behavior where the tray icon stays until you hover over it. In this case, this is a windows issue where the tray icon is not cleaned up when the process is killed... Nonetheless the plugin is killing the process forcibly instead of just disconnecting from the server session and letting jlinkgdbserver kill itself because of the -singlerun option.
I have peered through the plugin source code before, so I think I will peer again and see how the termination logic is. I am fairly certain the plugin is forcibly killing the server.
One way to fix this problem would be to... not forcibly kill the process and just disconnect from the server as suggested above. Another potential option that I am investigating is launching a stub or set of stub processes before I launch my tool that the plugin will be allowed to kill forcibly. The stub launches my tool and my tool monitors the stub to see if the plugin killed the process then shuts down gracefully as it should.
you are probably right, the termination logic is very complicated, and it may very well forcibly terminate the server.
the complication is due to not having a single termination logic, but many. each red square button is associated to one process, and pressing it terminates, more or less abruptly, that process.
each such termination should also handle the termination of the other processes, and here is probably where the wrong logic may be.
if you want to help fixing this, please take a look at the code and suggest changes.
I have taken a look at the source code, and I see a few spots where it seems like a process.destroy is being called. Those would probably be the areas I would start with. The point of the jlinkgdbserver -singlerun option is that the jlink gdb server will terminate automatically once all server connections are lost, which makes it a nice option. All you essentially have to do in the code is not call the destroy and only terminate the socket connection to the server and that would fix the issue. Since the connection to the jlink gdb server is lost, it dies on its own.
I may have a play around with the source code at some point, but I would rather explore my own option with the process stub. I am an outsider looking in and as such, I don't like messing with the source code of plugins made by other groups. Also, I am not versed in DSF architecture, and the plugin code seems fairly complicated. As some background, I am really a .NET guy and I don't have a ton of experience with java.
I am not sure how you are terminating the server at this point. So as a first guess, I would say that you are launching the jlink gdb server and then making a server socket connection to it. Then when you want to terminate the server, you forcibly kill the process and you get an exception when trying to read from the socket, which then you handle as a terminate.
If the above is the case, then instead of forcibly killing the process, what you should do instead is just close the socket connection by doing it explicitly - remove all the destroy process calls and replace with socket.close or whatever. This should cause the same exception to appear on the socket read in the same way as killing the process.
I guess you missed the previous explanation. there are multiple termination processes. each process started by DSF is accompanied by a monitoring thread, with a specific logic to be performed when the process is terminated.
so, when you press the red button, the termination process is the one of the process selected. in other words, the behaviour is different if you terminate the session killing different processes.
You are correct, because what it sounds like you are saying sounds ridiculously obvious to me.. on how the plugin functionally works.. so obvious in fact, I don't know why you have stated it. What you have stated however cannot be as obvious as it seems, therefore, I don't think we are on the same page.
What I think you are saying is that each different termination button in the debug perspective is associated with different termination logic. As far as I know, there are 2 possible red buttons I am aware of: The main one at the top left and another one in the console view on the bottom right. I couldn't care less about the button on the console view, but rather the main red terminate button everybody uses in the top left.
After doing some further investigation, it seems like the termination logic is not only killing the associated GDB server process, but killing the 'process tree' in windows. I am not sure if this is a java implementation thing or it's explicitly done like this in the plugin. I have to assume it is a java thing, because as far as the plugin is concerned, there is only one process being launched, not multiple behind the scenes.
The reason I found out that the process tree is being killed is because I tried making a stub program that sits between jlinkgdbserver and the gnu jlink plugin. The gnu jlink plugin launches the stub and then the stub launches the jlinkgdbserver. My expectation was that the gnu jlink plugin would only terminate the stub; however, it terminates both the stub and any spawned process from the stub. One can kill spawned processes of a parent process in windows by killing the 'process tree'.
As a result of the previous bad behavior, I have investigated an option where I create the jlinkgdbserver as a child of another process and not my stub. Therefore the plugin launches my stub then my stub launches jlinkgdbserver as a child of explorer.exe. When the plugin terminates the server, jlinkgdbserver gets terminated correctly as it is not a child of the stub which the plugin forcibly terminates.
I am not going to scour the plugin source anymore. I have looked at it for a few hours, and if my suspicion is correct, it would be very complicated to change how the server process is terminated no less than rewriting half the plugin. I guess I have to leave the analysis and implementation up to the experts if the issue is to be fixed :)
I don't think we are on the same page
from what I can read in your message, we aren't.
As far as I know, there are 2 possible red buttons I am aware of: The main one at the top left and another one in the console view on the bottom right.
that's correct
it seems like the termination logic is not only killing the associated GDB server process, but killing the 'process tree' in windows
here is where you miss the details. there is not one termination logic, but 4 different ones, associated to the processes in the 'process tree' as you call it:
each of the 4 processes has a monitoring thread associated; some also have a console.
when you press the top red button, it sends the terminate request to the process selected in the tree. to be sure that things are clear: if you select the thread or one of the lines below it and press the top red Terminate button, an event is sent to an internal java thread monitoring the debug; if you select JLinkGDBServer and press the same Terminate button, the event is sent to the thread monitoring JLinkGDBServer, which in turn sends a terminate signal to the external process; if you select arm-none-eabi-gdb and press the Terminate button, the event is sent to the thread monitoring arm-none-eabi-gdb, which in turn sends a terminate signal to the external process; if you select Semihosting and SWV, the event is sent to an internal java thread that telnets to the semihosting port and forwards output to the console.
a similar logic is executed when you press the Terminate button in the console: it sends an event to the monitoring thread associated with the selecte/active console, which might be JLinkGDBServer, arm-none-eabi-gdb or the smihosting thread.
so selecting the gdb client or JLinkGDBServer and pressing Terminate is somehow similar to going to the system process viewer and sending the terminate signal.
the complicated logic is in the monitoring thread associated with the debug session (the Thread entry), which normally should issue a command to the gdb client, which should issue a command to the server an then disconnect the socket from the server.
apparently somehting wrong happens at that moment, and the JLinkGDBServer is abruptly terminated.
I'll reopen this and, time permitting, try to take a look at the termination logic.
Ah, I see what you are saying now. I am concerned with the red #2 item, the jlinkgdbserver. When I say 'process tree', I mean Win32 process tree not related to eclipse but the real process tree on the computer. To use your explanation, when the thread monitoring the jlinkgdbserver process terminates, it terminates the 'entire' win32 process tree associated with the jlinkgdbserver, not just the server. This means for example, if I make a proxy application (which I have explained above) and have the plugin launch it thinking it is jlinkgdbservercl.exe, when the plugin terminates it, it will also terminate any process launched from my proxy app.
So
- Plugin launches proxy app (my exe. Looks and feels like jlinkgdbservercl.exe)
- My proxy app launches the actual jlinkgdbservercl.exe internally and pipes its output to the std output of my proxy app.
- Plugin connects to my proxy app thinking its jlinkgdbservercl.exe and gets the exact same output.
As you can see, my app launches win32 'child' process internal to it. So the hierarchy looks like this in terms of processes:
Eclipse -> Plugin -> proxy app -> jlinkgdbservercl.exe
When the plugin terminates the proxy app, I expect the process tree to now look like this:
Eclipse -> Plugin -> -> jlinkgdbservercl.exe.
But instead it looks like this:
Eclipse -> Plugin -> ->
Why? Because in my research, the termination logic for jlinkgdbserver in the plugin is killing the win32 'process tree' and not just the direct launched child (proxy.exe). LIke I was saying, this could be a java implementation thing.
Regardless, the termination logic for the thread monitoring the "jlinkgdbserver" is forcibly terminating the win32 'process tree' when it executes.
Now, this could be a bear of an issue to fix based on how the logic is in the plugin, which is why I went with a different approach to fixing the problem for my specific use case.
My specific use case is that I want to have the plugin launch a proxy server that internally filters all of the RSP GDB packets coming to it from the plugin and then passes them to jlinkgdbservercl which I launch internally to my proxy app. So to do this, I create the proxy app with a server that the plugin can connect to just like the jlinkgdbserver and then read all of the packets from the plugin and pass them back and forth to jlinkgdbserver. The proxy app is being to used to create a custom debug extension window separate from eclipse and I need to be able tell when the plugin stops, halts, steps, the debugged CPU when the user presses the debug buttons in the eclipse debug perspective (pause, run, etc.). I have the proxy portion completed and it actually works quite well. The issue comes into play when I need to 'gracefully' shutdown the proxy server because it needs to save some user data on shutdown that might have changed while debugging. Of course, forcibly terminating my proxy server and associated child processes spawned from it (jlinkgdbserver.exe being one of them) means I can't gracefully shutdown and the jlinkgdbserver tray icon incorrectly shows in the bottom right. Not exactly a good user experience :)
I am concerned with the red #2 item
really? do you explicitly select the JLinkGDBServer entry before clicking the Terminate button? the usual way is to leave the Thread entry selected.
When I say 'process tree', I mean Win32 process tree not related to eclipse but the real process tree on the computer.
I don't know the windows implementation details of the Java classes, but on POSIX there is no such thing. the java class calls some kind of exec(...) to start a new process and gets a process id. to terminate that process, it send the SIG_TERMINATE signal to it.
I remember that on windows the implementation was somehow different (more complicated and unusual), but I don't remember the details.
Yeah, I understand windows is different from linux, etc.. Windows has a slight notion of a process tree. Every process is inherently 'independent' in that they can all execute alone. If you shut one of them down through the task manager, any spawned processes from the original will not get shut down and will just keep running.. that is unless you end the 'process tree'. When you create a process in a windows program, the process spawned is a child process and the program that spawned the child is the parent. This is where the 'process tree' is built from for the 2 processes - they form a hierarchy. If the child launches processes itself, they get attached to the hierarchy as well.
Now the really odd thing is that you have process A which spawns B and B spawns C.
So it looks like this process tree:
A(grandparent) -> B (parent) -> C (child).
If you terminate process B, the tree looks like this:
A (original grandparent) -> -> C (root).
So if you break the process tree linkage anywhere in between the two ends of the hierarchy, you can actually create processes which become "roots" and they are now the eldest parent in the chain. This means if I then terminate the process tree using process A above, it will now not kill process C, because C became a root by killing B. Kinda funny.
Using this same idea, the solution for me is to have a 2 stubs that spawn my proxy. So I spawn stub1 which sits at the top, this is what the plugin interacts with directly for stdout. Then Stub1 spawns process stub2, then stub2 spawns the proxy process. Stub1 then connects to the proxy and then terminates stub2. This creates the same breakage in the tree hierarchy I explained above and now the proxy is a root process that won't be forcibly terminated when the plugin terminates Stub1.
I see.
it might work for you, but this is a kludge.
the termination logic for all monitoring threads needs to be revised and perhaps this will solve your problem too.
Haha! I understand that it is a kludge more than you know! When I found out that the plugin was forcibly terminating the server process, I did a bunch of research to see if I could fix the problem without touching the plugin source code.
However.. I do not have the luxury of waiting until the the issue is fixed to move forward. Believe me, it would be great if the functionality could be changed such that I don't have to perform any special logic and I can just run the proxy app from the plugin directly like I intended originally. In my experience, issues like these do not get fixed overnight, and from what you have explained, I don't think its as simple as just commenting out a few lines of code in the plugin.
I don't think its as simple as just commenting out a few lines of code in the plugin
it probably isn't. but we never know until the code is thouroughly checked.
right now I'm updating the project to support the new RISC-V architecture; J-Link is not yet available for RISC-V, but it is expected to be, hopefully in a matter of weeks.
after this, together with the RISC-V team, we'll evaluate the changes required in the J-Link plug-in and, depending on other things we discover, if the problem you are reporting can be easily reproduced, I'll probably address it too.
so, without commiting on a date, it might happen sometime this summer/autumn.