Yves Posted January 4, 2013 Report Share Posted January 4, 2013 Have you ever wanted to step inside a Javascript function while tracking down a bug with a C++ debugger?Did you miss the ability to single-step through Javascript code to figure out how something works?Well, I did. I planned to look into the AI a bit and there were a lot of situations where I wished I had the same tools as with C++. Another recent situation convinced me to try figuring out how it could be realized.EDIT: I've put the outdated information below into a spoiler.Get the most up to date information and the newest version of the debugger from this wiki article (or read the whole thread).http://trac.wildfire...scriptDebuggingCurrent statusI have a very basic and heavily WIP version that supports toggling breakpoints, continuing the execution and some additional things. It should work with all runtimes and contexts we are using (GUI, Simulation AI etc...), there might be some possible threading issues, thought.Commands can be executed via a mongoose webserver that we already use for the profiler and maybe other things. There's no convenient UI, you have to know how to pass certain URLs. There's no way yet how to receive information about the content of variables at runtime.As you can see it's not very useful yet, but now that the basics are implemented it should be possible to add new features and improve it. More technical backgroundIt uses the JSDBGAPI provided by Spidermonkey 1.8.5. Newer versions of Spidermonkey provide a simplified new API (along with memory leak fixes and more), but unfortunately Mozilla isn't interested in doing the work and publishing a independent build from Firefox. We had a discussion about that on IRC.Supported commands at the moment (with example values)Toggling (setting/removing) breakpoints:http://127.0.0.1:9000/ToggleBreakpoint?filename=gui/gamesetup/gamesetup.js&line=1481Continuing when the execution stops at a breakpoint:http://127.0.0.1:9000/ContinueList all *.js files loaded into the vfs.http://127.0.0.1:9000/EnumJsFilesPreExecGet a File loaded into the vfs:http://127.0.0.1:9000/GetFile?filename=globalscripts/Math.jsGet the names of all Scriptinterface instances:http://127.0.0.1:9000/EnumScriptInterfacesWhat's next / Web developer wantedI thought it's time to think a bit about the UI before I implement too many additional features.I have written some HTML a long time ago and I think it would be quite an effort to learn everything required to make a useful webinterface for calling these commands, displaying sourcecode, toggling breakpoints by clicking etc...I would appreciate it if there was someone who's more used to it and could help creating such a UI.This would allow me to focus on the server-side.Here's the current WIP version (be warned, I haven't spent a single second cleaning it up or making it less ugly )Feedback is always welcome!javascript_debugging_WIP_v.0.1.diff Quote Link to comment Share on other sites More sharing options...
MishFTW Posted January 4, 2013 Report Share Posted January 4, 2013 Ah, leper was right. I could make a simple UI for this. As long as it doesn't involve too much back-end I'll be on IRC Saturday (GMT evening); sadly school has started again. Quote Link to comment Share on other sites More sharing options...
historic_bruno Posted January 4, 2013 Report Share Posted January 4, 2013 It's great to have someone working on this again! Have you seen #410?(BTW I think you should clarify this is not a web JS debugger but one specifically for 0 A.D., otherwise people will be suggesting stuff like Venkman...) Quote Link to comment Share on other sites More sharing options...
zoot Posted January 4, 2013 Report Share Posted January 4, 2013 Sounds really handy. Maybe I can work with Geek377 on the UI. I don't really have experience with all that AJAX/HTML5 fanciness, but I'd be happy to work on the engine-facing stuff. Quote Link to comment Share on other sites More sharing options...
MishFTW Posted January 4, 2013 Report Share Posted January 4, 2013 Zoot, by all means go ahead if you're ready Just call me for the fancy stuff Quote Link to comment Share on other sites More sharing options...
zoot Posted January 4, 2013 Report Share Posted January 4, 2013 Yves, I have applied your patch thusly: https://github.com/zootzoot/0ad/commit/4d01ee88ca6dbcac9a2706f3a9d40a5444aea75dHow do you enable the debugging server? Should I make a debug build? Quote Link to comment Share on other sites More sharing options...
Yves Posted January 4, 2013 Author Report Share Posted January 4, 2013 Yves, I have applied your patch thusly: https://github.com/z...9d40a5444aea75dHow do you enable the debugging server? Should I make a debug build?Yes at the moment it's only enabled in debug builds (#ifdef DEBUG). It should definitely not be enabled in release builds for reasons like performance, security and stability.It's great to have someone working on this again! Have you seen #410?No I haven't. (BTW I think you should clarify this is not a web JS debugger but one specifically for 0 A.D., otherwise people will be suggesting stuff like Venkman...)Yes that's an important note. It doesn't seem to be possible to use 3th party tools that are designed for other Javascript embedding applications like Firefox.Ah, leper was right. I could make a simple UI for this. As long as it doesn't involve too much back-end I'll be on IRC Saturday (GMT evening); sadly school has started again.Sounds really handy. Maybe I can work with Geek377 on the UI. I don't really have experience with all that AJAX/HTML5 fanciness, but I'd be happy to work on the engine-facing stuff.Thank you, that would be awesome! If you have time, please check if the format returned is OK or if I should change anything so that once you start you don't have to worry about these things.I thought it could be something similar to source/tools/profiler2/profiler2.html regarding the technologies used, but you're free about that. Quote Link to comment Share on other sites More sharing options...
MishFTW Posted January 4, 2013 Report Share Posted January 4, 2013 Hey maybe we could get a HTML/CSS/JS GUI indeed if we embedded Firefox rather than Webkit (if its easier of course) Quote Link to comment Share on other sites More sharing options...
zoot Posted January 4, 2013 Report Share Posted January 4, 2013 Geek, do you have any experience with AJAX or something similar? I think that is what we would want for a live UI here. Quote Link to comment Share on other sites More sharing options...
zoot Posted January 4, 2013 Report Share Posted January 4, 2013 Yves, I get this when trying to do a debug build:==== Building mocks_real (debug) ======== Building network (debug) ======== Building simulation2 (debug) ======== Building scriptinterface (debug) ======== Building engine (debug) ======== Building graphics (debug) ======== Building atlas (debug) ======== Building gui (debug) ======== Building lowlevel (debug) ====DebuggingServer.cpp==== Building mongoose (debug) ======== Building mocks_test (debug) ======== Building AtlasObject (debug) ======== Building AtlasScript (debug) ======== Building Collada (debug) ====ScriptInterface.cpp==== Building AtlasUI (debug) ====GameSetup.cpp==== Building ActorEditor (debug) ====../../../source/scriptinterface/DebuggingServer.cpp: In function ‘void NewScriptHook(JSContext*, const char*, unsigned int, JSScript*, JSFunction*, void*)’:../../../source/scriptinterface/DebuggingServer.cpp:132:47: fejl: could not convert ‘0’ from ‘int’ to ‘jsval’make[1]: *** [obj/scriptinterface_Debug/DebuggingServer.o] Fejl 1make[1]: *** Venter på uafsluttede job....Linking enginemake: *** [scriptinterface] Fejl 2Am I missing something? Quote Link to comment Share on other sites More sharing options...
Yves Posted January 4, 2013 Author Report Share Posted January 4, 2013 I have created a new version which also changes the part of code that can cause the compile error mentioned above.In addition to that it implements the new command "step" to step a single line after you have set and triggered a breakpoint.http://127.0.0.1:9000/Stepjavascript_debugging_WIP_v.0.2.diff Quote Link to comment Share on other sites More sharing options...
zoot Posted January 4, 2013 Report Share Posted January 4, 2013 I have created a new version which also changes the part of code that can cause the compile error mentioned above.Now I get this:==== Building mocks_real (debug) ======== Building network (debug) ======== Building simulation2 (debug) ======== Building scriptinterface (debug) ======== Building engine (debug) ======== Building graphics (debug) ======== Building atlas (debug) ======== Building gui (debug) ====DebuggingServer.cpp==== Building lowlevel (debug) ======== Building mongoose (debug) ======== Building mocks_test (debug) ======== Building AtlasObject (debug) ======== Building AtlasScript (debug) ======== Building Collada (debug) ====ScriptInterface.cpp==== Building AtlasUI (debug) ====GameSetup.cpp==== Building ActorEditor (debug) ====../../../source/scriptinterface/DebuggingServer.cpp: In function ‘JSTrapStatus TrapHandler_(JSContext*, JSScript*, jsbytecode*, jsval*, jsval)’:../../../source/scriptinterface/DebuggingServer.cpp:13:38: fejl: invalid cast from type ‘jsval’ to type ‘CDebuggingServer*’../../../source/scriptinterface/DebuggingServer.cpp: In member function ‘void CDebuggingServer::NewScriptHook(JSContext*, const char*, unsigned int, JSScript*, JSFunction*, void*)’:../../../source/scriptinterface/DebuggingServer.cpp:130:54: fejl: no matching function for call to ‘jsval_layout::jsval_layout(CDebuggingServer* const)’../../../source/scriptinterface/DebuggingServer.cpp:130:54: bemærk: candidates are:In file included from ../../../libraries/spidermonkey/include-unix/js/jspubtd.h:47:0, from ../../../libraries/spidermonkey/include-unix/js/jsapi.h:49, from ../../../source/scriptinterface/ScriptTypes.h:81, from ../../../source/scriptinterface/ScriptInterface.h:25, from ../../../source/scriptinterface/DebuggingServer.h:6, from ../../../source/scriptinterface/DebuggingServer.cpp:3:../../../libraries/spidermonkey/include-unix/js/jsval.h:294:15: bemærk: jsval_layout::jsval_layout()../../../libraries/spidermonkey/include-unix/js/jsval.h:294:15: bemærk: candidate expects 0 arguments, 1 provided../../../libraries/spidermonkey/include-unix/js/jsval.h:294:15: bemærk: jsval_layout::jsval_layout(const jsval_layout&)../../../libraries/spidermonkey/include-unix/js/jsval.h:294:15: bemærk: no known conversion for argument 1 from ‘CDebuggingServer* const’ to ‘const jsval_layout&’../../../source/scriptinterface/DebuggingServer.cpp: In function ‘JSTrapStatus TrapHandler_(JSContext*, JSScript*, jsbytecode*, jsval*, jsval)’:../../../source/scriptinterface/DebuggingServer.cpp:14:1: advarsel: kontrol når til slutningen af ikke-void funktion [-Wreturn-type]make[1]: *** [obj/scriptinterface_Debug/DebuggingServer.o] Fejl 1make[1]: *** Venter på uafsluttede job....Linking enginemake: *** [scriptinterface] Fejl 2make: *** Venter på uafsluttede job....Any hope of persuading you to push your changes to a GitHub branch? This would make it less likely that I screw up the patching process. Quote Link to comment Share on other sites More sharing options...
Yves Posted January 4, 2013 Author Report Share Posted January 4, 2013 Any hope of persuading you to push your changes to a GitHub branch? This would make it less likely that I screw up the patching process.It doesn't look like you've done anything wrong with the patching.Please try compiling just DebuggingServer.cpp with the same options as I did (maybe you have to adjust some library directories):g++ -g -Wall -DDEBUG -DLIB_STATIC_LINK -DUSING_PCH -DWITH_SYSTEM_MOZJS185 -Wno-switch -Wno-reorder -Wno-invalid-offsetof -Wextra -Wno-missing-field-initializers -Wunused-parameter -Wredundant-decls -Wnon-virtual-dtor -Wundef -fstack-protector-all -D_FORTIFY_SOURCE=2 -fstrict-aliasing -fno-omit-frame-pointer -fpch-preprocess -msse -fvisibility=hidden -I/usr/include/nspr -I/usr/include/js -Winvalid-pch -include "../../../source/pch/scriptinterface/precompiled.h" -I/usr/X11R6/include/X11 -I/usr/X11R6/include -I/usr/include/X11 -I../../../source/pch/scriptinterface -I../../../source -I../../../libraries/valgrind/include -c ../../../source/scriptinterface/DebuggingServer.cpp -o ./DebuggingServer.oEDIT: I've figured out why it happens, but not yet how to resolve it.If I use the bundled version of spidermonkey, I get the same errors. Quote Link to comment Share on other sites More sharing options...
Yves Posted January 4, 2013 Author Report Share Posted January 4, 2013 OK, this version should work for the bundled version too.Credits go to Philip for helping me with the pointer to jsval conversion. javascript_debugging_WIP_v.0.3.diff Quote Link to comment Share on other sites More sharing options...
zoot Posted January 4, 2013 Report Share Posted January 4, 2013 It works This will be very useful. And JSON is clearly the right output format. Maybe you want to add some status outputs on those commands that don't have it yet, e.g. "{status: true}" when a breakpoint is set and "{status: false}" when it is unset (or something along those lines). Quote Link to comment Share on other sites More sharing options...
quantumstate Posted January 5, 2013 Report Share Posted January 5, 2013 This will be good, a step through debugger would help in quite a few situations. We could add some neat features to make it easy to look at the components for an entity. Quote Link to comment Share on other sites More sharing options...
Yves Posted January 5, 2013 Author Report Share Posted January 5, 2013 The next version is ready and you can now examine variable content at runtime.New functionsBoth functions are only available when the execution is halted because you have triggered a breakpoint or used step after triggering a breakpoint.Getting the callstackhttp://127.0.0.1:9000/GetCallstackIt will return something like that:["keywordTestOR","annonymous","testFilter","initMapNameList","selectMapType","__eventhandler31 (selectionchange)","initMain","onTick","__eventhandler28 (tick)"]keywordTestOR is the innermost function which got called by an annonymous function, which got called by "testFilter" etc...Getting all variables from a stack frame.http://127.0.0.1:9000/GetStackFrame?nestingLevel=0If you look at the function above (GetCallstack), nestingLevel=0 would point to the innermost stackframe (keywordTestOR). Native functions as "__eventhandler31" don't return any data.Other modificationsI've uncommented the most annoying LOGERROR calls that spammed the screen.EnumJsFilesPreExec returns a slightly different output format (I hope that's better).javascript_debugging_WIP_v.0.4.diff Quote Link to comment Share on other sites More sharing options...
historic_bruno Posted January 5, 2013 Report Share Posted January 5, 2013 I can't get the breakpoints to work. What happens when a breakpoint is hit? Quote Link to comment Share on other sites More sharing options...
k776 Posted January 5, 2013 Report Share Posted January 5, 2013 Yves, I'm very keen to help with the UI on this. What would be nice is if, in your path, when you hit the root path (http://localhost:9000) it would load an index.html file (which can be blank for now). That way I know which file to modify. Then I'll link in JQuery from googles JS CDN and get to work implementing some buttons which execute the url asynchronously and then updates the page with results. Quote Link to comment Share on other sites More sharing options...
Yves Posted January 6, 2013 Author Report Share Posted January 6, 2013 I can't get the breakpoints to work. What happens when a breakpoint is hit?I've always used the example from the first post for testing. Maybe there are some issues I haven't discovered yet with other files and lines.http://127.0.0.1:9000/ToggleBreakpoint?filename=gui/gamesetup/gamesetup.js&line=1481Start the game. there should be a yellow warning message on the upper left corner that the javascript debugging is enabled.Enter the URL in your browser to toggle a breakpoint.Select "Singleplayer->Matches"Now the UI should "freeze" because the breakpoint callback is called and loops until you continue/step.The breakpoint will be triggered multiple times. You can either remove the breakpoint and call Continue once or call Continue multiple times.As you see it only stops one thread which is one thing that could cause issues.Yves, I'm very keen to help with the UI on this.Good What would be nice is if, in your path, when you hit the root path (http://localhost:9000) it would load an index.html file (which can be blank for now). That way I know which file to modify. Then I'll link in JQuery from googles JS CDN and get to work implementing some buttons which execute the url asynchronously and then updates the page with results.I thought we could do it similar to 0ad/source/tools/profiler2.html.It uses a local file which can be opened in a browser, modified or placed wherever you want. Why would we need to provide the index.html via webserver? Quote Link to comment Share on other sites More sharing options...
k776 Posted January 6, 2013 Report Share Posted January 6, 2013 I thought we could do it similar to 0ad/source/tools/profiler2.html.It uses a local file which can be opened in a browser, modified or placed wherever you want. Why would we need to provide the index.html via webserver?Ah, ok. I'll have to look into how it does it.Edit: Oh yup. That looks very doable. Attempting to compile the game in debug with the patch. Will let you know where I get. Quote Link to comment Share on other sites More sharing options...
historic_bruno Posted January 6, 2013 Report Share Posted January 6, 2013 I've always used the example from the first post for testing. Maybe there are some issues I haven't discovered yet with other files and lines.http://127.0.0.1:9000/ToggleBreakpoint?filename=gui/gamesetup/gamesetup.js&line=1481Start the game. there should be a yellow warning message on the upper left corner that the javascript debugging is enabled.Enter the URL in your browser to toggle a breakpoint.Select "Singleplayer->Matches"Now the UI should "freeze" because the breakpoint callback is called and loops until you continue/step.The breakpoint will be triggered multiple times. You can either remove the breakpoint and call Continue once or call Continue multiple times.As you see it only stops one thread which is one thing that could cause issues.I try those steps and I get the debugging enabled message, some of the other commands work but not breakpoints. The UI doesn't freeze when entering match setup, which is what I was expecting. Could it be something about how the Spidermonkey lib was built on Windows? Quote Link to comment Share on other sites More sharing options...
Yves Posted January 6, 2013 Author Report Share Posted January 6, 2013 I try those steps and I get the debugging enabled message, some of the other commands work but not breakpoints. The UI doesn't freeze when entering match setup, which is what I was expecting. Could it be something about how the Spidermonkey lib was built on Windows?I can confirm this on Windows. I'll try to figure it out and edit this post or add a new one when I know more.EDIT: I forgot to initalize a boolean variable. Apparently it becomes false by default on Linux but not on Windows.There was also another problem with an uninitialized jsval which should be solved now.This version is now tested on Windows and Linux.A known Issue is that it crashes when exiting the game, which I think is related to using Javascript contexts in multiple threads and will require some more thinking.Here's the updated patch:javascript_debugging_WIP_v.0.5.diff Quote Link to comment Share on other sites More sharing options...
MishFTW Posted January 6, 2013 Report Share Posted January 6, 2013 The last time I tried, it it didn't work in terms of being built in debug mode. I didn't get a yellow message. ( I used make config=debug -j3 )I'll try again with version 0.5 Quote Link to comment Share on other sites More sharing options...
Yves Posted January 6, 2013 Author Report Share Posted January 6, 2013 That's strange.Did it build without errors and do you execute the pyrogenesis_dbg executable? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.