Creating VSCode Debugger Extension - visual-studio-code

I'm in the process of trying to write a VSCode extension to support basic SNES application development. I already have a basic grammar definition and build task, so I have syntax highlighting, and am able to build my project with Ctrl+Shift+B using the bass v14 assembler, but now I'm trying to figure out how to launch the project using launch.json. I've already worked through the official docs and played around with the mock debugger project, but I can't seem to figure out how to adapt it for my extension. To start, I'm using the bsnes-plus emulator as my debugger. There isn't really any command-line or IPC interface that will actually allow me to implement a proper debug adapter, so all I really want to do is to run the program and pass it my output file to launch. For the time being, I'm assuming that bsnes-plus.exe is located in my $PATH, but eventually I'll try and figure out the best practices for external executable dependencies for an extension.
So here are my current questions:
Is the "program" field of launch.json my compiled application, or is it bsnes-plus.exe?
If "program" is my application, where do I specify bsnes-plus.exe? Or vice versa.
Is there a way to specify my own project-level variables, e.g. $OUTPUT so that I don't have to hard-code the output filename into both the build task and the launch task?
At one point, I was able to get the launch command to open bsnes-plus, but not load the game, and when I closed it, VSCode complained that the debugger terminated unexpectedly and immediately re-opened bsnes-plus. How do I avoid this? Do I need to write a debug adapter even though it's not going to actually do anything other than launch the application, just so I can tell VSCode that it exited cleanly?

Is the "program" field of launch.json my compiled application, or is it bsnes-plus.exe?
This is entirely up to the debug extension. It's just passed through to the debug adapter. It usually corresponds to the specific app/script being debugged though, not the runtime that's running it, so I would suggest it should be your compiled application.
If "program" is my application, where do I specify bsnes-plus.exe? Or vice versa.
You can put it any other field. In Dart, we have a dartPath field that can be passed through to the debug adapter. It's usually populated silently by the DebugConfigurationProvider.resolveDebugConfig though (we detect the SDK by searching PATH) so the user never needs to add it.
Is there a way to specify my own project-level variables, e.g. $OUTPUT so that I don't have to hard-code the output filename into both the build task and the launch task?
You can't make your own variables, but using resolveDebugConfig you can manipulate the launch config yourself before it's passed to the debug adapter, which probably allows you to do what you need here (eg. you could do a string replace on program - or you could even just add it if it's not set, allowing a launch.json-less launch too).
Do I need to write a debug adapter even though it's not going to actually do anything other than launch the application, just so I can tell VSCode that it exited cleanly?
I'm not sure what happened here without more details, but having a debug adapter probably makes the most sense - for example if you want to make the Stop/Restart buttons work on the toolbar, you'd probably want a debug adapter that can terminate and/or restart the process.

Related

Build code in vscode using external http server

Our code building process is done via an http server which starts the build process after receiving a project uuid from the build command. Once the server starts the compilation, GCC compatible output can be fetched from it.
Note: only my extension is aware of the project uuid which is different per workspace.
AFAIU I can implement it by:
programmatically adding a task which will call a script with the correct workspace uuid. Is this possible?
Having my extension manage the build process. This seems to be far from supported.
Bottom line, I'm trying to avoid asking the user to add anything to the configuration files and I want to completely manage the build process.
Thanks!
As I didn't find a suitable only vscode solution I did the following:
Defined a helper script which I executed as the task. The helper script was respojnsible for the communication against the HTTP server.
I registered the task using vscode.workspace.registerTaskProvider API, and made sure to register it only after figuring out the UUID.
Then in the task itself I executed the helper script.
(A nice task register example can be found here: https://github.com/Microsoft/vscode-extension-samples/tree/master/task-provider-sample)

Mac: attach commandline parameters to a running application on Mac failed

Today I have a strange problem on MacOs. I hope I can explain the precondition exactly for understanding. We are using the install4j version 6.0.1.
Our application is implemented with an install4j silent update check application as the main "launcher" to check for updates during the startup process of our application. This application is totally configured by the install4j IDE. It checks whether an update exists and for that downloads the new installer and executes it. That's working fine. If the application is up-to-date the "main" application launcher will be executed by the Execute Launcher-action. Therefore the "extraCommandLineArguments" will be passed to the launcher and the application will be started. That's working also fine and the parameters will be passed correctly to our main class.
Now the strange behavior: when I start the application twice with several parameters during the first instance is always running the parameters will not be passed to the first instance neither a second instance will be created. The launcher is configured by install4j to allow multiple instances of the application and the single-instance option is implemented by our application itself. Therefore the main-class checks whether an instance is always running and will pass the parameters to the first instance. Now it seems that the second instance will never be created because I can't attach to the vm-process by IDE at debug mode. Therefore I set the debug vm parameters to the vmoption file. I tried several options to start the second instance:
execute our application normally with the "updater"-application and set commandline parameters
execute our application directly by the launcher-executable and set commandline parameters
execute our application by calling the JavaApplicationStub of the launcher and passing the commandline parameters to it
For all options the running instance will get the focus but do not receive any parameter and I can not attach the second process by the IDE to debug the behavior. It seems our application (main-class) will not be executed a second time. At the Info.plist file there is the MacLauncher class recognized as the main-class. Is tere any logic implemented to search for a running instance and ignore a second one?
The strange thing is: at windows everything works fine. The second process passes the parameter to the running instance. What could be different on mac? How can I check whether install4j is calling our main application class configured at the launcher? Are there any debug-options?
Thanks in advance for any help.
On Mac OS X, GUI applications are in single instance mode by default. This is a property of the Mac OS X desktop environment. The only way to open a second instance, is to call
open -n my.app

cannot load runtime-gdb.py

I'm trying to debug a program written using Go inside eclipse. I can set and hit breakpoints pretty consistently, but I cannot view the contents of my variables. When I start debugging the program, I always get the following error on my console.
warning: File "/usr/local/go/src/pkg/runtime/runtime-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
add-auto-load-safe-path /usr/local/go/src/pkg/runtime/runtime-gdb.py
line to your configuration file "/home/johnlawrie/.gdbinit".
To completely disable this security protection add
set auto-load safe-path /
line to your configuration file "/home/johnlawrie/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual. E.g., run from the shell:
info "(gdb)Auto-loading safe path"
Thinking that the problem might be due to the error message, I put the entry into my .gdbinit file as instructed. However, I get the same message every time I run as if I did nothing at all. This is the contents of my /home/johnlawrie/.gdbinit file
add-auto-load-safe-path /usr/local/go/src/pkg/runtime/runtime-gdb.py
Any ideas what I need to do to make this change take effect? I have tried logged off and back in.
Thanks,
John Lawrie
It did learn what was happening. When gdb is started from Eclipse/CDT, it is started with option -nx, which means it doesn't load .gdbinit in the home directory.
I was able to get this to work by creating a .gdbinit file as a peer to the src, bin, and pkg directories in my workspace and adding the following line to it
set auto-load safe-path /usr/local/go/
It should be add-auto-load-safe-path /usr/local/go/src/pkg/, not the path to the script.
Also keep in mind that gdb doesn't really work with Go, specially v1.3.
From http://golang.org/doc/gdb:
GDB does not understand Go programs well. The stack management,
threading, and runtime contain aspects that differ enough from the
execution model GDB expects that they can confuse the debugger, even
when the program is compiled with gccgo. As a consequence, although
GDB can be useful in some situations, it is not a reliable debugger
for Go programs, particularly heavily concurrent ones. Moreover, it is
not a priority for the Go project to address these issues, which are
difficult. In short, the instructions below should be taken only as a
guide to how to use GDB when it works, not as a guarantee of success.

Convenient way to run eclipse plugin

I have recently started developing an Eclipse plugin (which is basic stuff for now) and I am struggling with "default" way to run Eclipse plugin ("Run as Eclipse application").
The Eclipse is starting another instance with my plugin already installed in it (this is default behaviour).
The problem is that when I want to re-run my plugin project and I press "run" button again (or Ctrl + F11) (and the another Eclipse instance still running) I get following message:
"Could not launch the application because the associated workspace is currently in use by another Eclipse application".
The error makes sense, and when I close "testing" Eclipse instance I am able to run my plugin again.
The question is - "is it normal routine for plugin development?". Maybe I am missing something, e.g. special arguments for Eclipse?
This seems all pretty normal. The error message is since the run configuration is specifing a workspace and when you start a second instance using the same workspace it is locked and considered in use.
What I usually do when testing a plugin is to create a run configuration (click "Run...") where I disable all the plugins I wont need when testing. This makes sure that the test starts up a couple of seconds quicker. Make sure you save that run configuration as a *.launch file aswell, that makes it quicker to test the next time. Or it can be used to share the configuration.
There's a lot you can configure in the run configuration, such as eclipse arguments, vm argument, if you want environment variables set, etc. So be sure to experiment a little.
In your run configuration. Main tab->Workspace Data ->Location text box add this:
${workspace_loc}/../runtime-EclipseApplication${current_date:yyyyMMdd_HHmmss}
Note the suffix ${current_date:yyyyMMdd_HHmmss} by this every time you launch your application new workspace will be created. So you will not get any error message saying workspace is locked.
But be careful as the folder .metadata will be different for different instances as their work-spaces are different. Thus preferences stored/retrieved by different instances are NOT in sync.
You are probably missing one important point: Eclipse supports the Java hot code replacement. Therefore in many cases you can modify your Java code while your application Eclipse instance is running, save the code and continue without restarting.
If hot code replacement is not possible, Eclipse will tell you, so you always know whether the editing changes are applied to the running instance.
This works best with more recent versions of the JVM, so consider upgrading to the latest Java 7 version, even if you write code to be compliant with Java 1.5 or 6.

(Eclipse) How to interact with console view?

Eclipse uses console view as read-only.
How can I type command in console view? Is it possible? E.g: ls, mvn install...
Edited:
Thanks Ben and Kelly.
I understand I can interact with Eclipse's console when my application is running. However, I meant I want an embedded console as like as the one in Kate, Dolphin (press F4 in Dolphin)... So I can use bash script in Eclipse's console. Is that possible? Or is there a plugin for that? I have googled but perhaps my keywords were not right...
Edited
Edward has found duplicate question here: Is there an Eclipse plugin to run system shell in the Console?
And it was answered :-)
I don't know how to mark this one as solved. So I place message here, I got the answer.
Edited
But it is not useful. It doesn't have auto complete feature, when I need to type a long file name, or want a hint for a forgotten name,... it is worst :-(
When the console is waiting for input it shows a green prompt that allows you type.
You can test it out by making a simple console application that reads from standard input.
You are trying to think of the Eclipse console as if it were connected to a command-line process. It is actually connected to the JVM used to execute your Java code. Thus, it only shows output that your program sends to System.out and conversely only is available for input if the Java code you are running is requesting input from System.in.
A decent exercise would be to write a small Java program that redirects the input and output to a child process of your favorite shell, for example: http://www.devdaily.com/java/edu/pj/pj010016
The Eclipse Console view is used for communicating with an executed program (typically Java, or similar). If you want to use it as a console, as mentioned in the comment under #Ben S's answer, the Target Management Eclipse project provides a view that can be used for that reason. I don't have it installed right now, so I cannot tell you the required plug-in/view name, but I have used it to connect to the local computer and works.