Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebIDE Integration #1

Open
FWeinb opened this issue Apr 4, 2019 · 73 comments
Open

WebIDE Integration #1

FWeinb opened this issue Apr 4, 2019 · 73 comments

Comments

@FWeinb
Copy link

FWeinb commented Apr 4, 2019

As discussed in Moddable-OpenSource/moddable#132 I am opening an issue here.

I just had a minute to test the integration of the new WebSocket-Debugger into the WebIDE. Looking well so far I started by just piping in the device log into the log area:

image

What would be great is a way to detect when the mod was uploaded and run. I am currently querying /mod/install but it returns as soon as the upload was completed.

Another problem is the mixed-content problem regarding https/http on resources hosted on the device itself. Chrome is blocking these requests and you need to manual allow loading the execution. This is problematic for uploading and connecting to the unsecured websocket connection.

@phoddie
Copy link
Owner

phoddie commented Apr 4, 2019

@FWeinb - Great start. I'm glad it worked for you too.

What would be great is a way to detect when the mod was uploaded and run.

Yes, I expected this would be something we need to work on. It it is a little tricky. Let me explain. The upload of the mod is separate from installation of the mod. The install can only happen on a clean boot of a virtual machine (because the mod's symbols need to be remapped). That's why the virtual machine always restarts after installing a mod. Restarting reboot to the device, which drops all network connections as Wi-Fi is restarted too. The mod is then run after restart. In theory, we could avoid dropping the network connection by not restarting the microcontroller and only restarting the virtual machine. But, that is complicated and unlikely to be stable (all running services need to be cleanly exited, all memory freed), so I don't particularly want to explore that route.

Instead, I propose we rearrange the flow. Currently runmod executes the mod at start-up. That is not necessary. It is just one useful behavior. Another useful behavior could be to wait for a debugger connection. Once that is established, then run the mod. That way, the debugger connection is in place from the start of the mod's excecution. The choice between these behaviors could be made by another HTTP request from the WebIDE.

What do you think?

Another problem is the mixed-content problem regarding https/http on resources hosted on the device itself. Chrome is blocking these requests and you need to manual allow loading the execution. This is problematic for uploading and connecting to the unsecured websocket connection

I'm not sure how to solve this. Chrome's move to treating http like a pariah on the web has very unfortunate consequences for IoT. We are bumping into one here. As I understand it, we cannot use public certificates here because ".local" addresses are not owned by a single entity. We could use a private certificate (with a great deal of work on the device side...) but that requires the user to install the private certificate into the browser (or machine running the browser) which works against the goal of having the WebIDE "just work" with arbitrary devices. Ideas?

@FWeinb
Copy link
Author

FWeinb commented Apr 4, 2019

@phoddie
Modifying the startup behaviour of runmod based on a HTTP request seams like the best way to go forward.

The mixed-content policy is very hard to work around. It is very strange that there isn't a way to ask the user for permission to establish an unsecured connection. For now it would be possible to host the WebIDE on plain http but that is currently not supported with netlify and other services. The Web is moving to https only and IoT devices will need to catch up with that but there is no good way to generate a certificate that will be trusted.

@phoddie
Copy link
Owner

phoddie commented Apr 4, 2019

I'll make the changes to runmod so we try that out.

I am sympathetic to the challenges of browser security policies. I'm optimistic that we'll figure something out. That said, web security is security for the web, not the internet. While I am glad the browser vendors are working to improve the security of the web, IoT should not be obliged to support every decision made for the web. That would lead to a significant increase in complexity and cost for IoT.

@FWeinb
Copy link
Author

FWeinb commented Apr 4, 2019

@phoddie
I had a litte bit of time and implemented a basic instruments view:
image

To implement the stepping debugger I need to refactor the WebIDE a lot. The file handling isn't optimal and I need to think about how to switch between the debugging and editor view.

I don't have that much time to work on it though.

@lprader
Are you still evaluating the WebIDE for the use in a workshop? Would be great to get some input on features you want to see included.

@phoddie
Copy link
Owner

phoddie commented Apr 5, 2019

@FWeinb - Nice! Instrumentation is one of my favorite features. It is essential for embedded development. Happy to see it arrive so early here. ;)

I've committed changes to support running the mod when the debugger connects, as we discussed above. Let me know if it works for you. The docs are up-to-date with the details.

Regarding the workshop, our Mozilla friends invited us to help out with two workshops they are holding at JSConf EU. We would introduce the Moddable SDK as it relates to the Mozilla Web of Things initiative. That is in early June. It makes an interesting (if ambitious) goal, and perhaps in your part of the world?

@lprader
Copy link
Collaborator

lprader commented Apr 5, 2019

@FWeinb yes, definitely still interested in the potential for this in workshops! The most time consuming part of every workshop is getting all the necessary drivers and libraries installed and Moddable SDK tools built on everyone's laptop, so the WebIDE is really great since it cuts that part out of the process. The ability to load gists is perfect for that setting too.

There are a few features I can think of off the top of my head that would be useful:

  • Ability to add files manually
  • Ability to open multiple gists
  • Ability to specify which files to upload

Like Peter said, there's JSConf EU in June. I'll also be running a workshop in late May, which would be an even more ambitious goal than that :)

@FWeinb
Copy link
Author

FWeinb commented Apr 5, 2019

@phoddie Great will have a look at it as soon as possible.

JS Conf EU sounds exciting, I am living in Germany so definitely in my part of the world but I am currently still a student (last semester) and do not know if I could find the time and money to go there.

@lprader
Thanks for the feedback. I will need to refactor most of the WebIDE going forward. So having these requirements is really valuable.
What would be the most valuable features of the debugger? Currently we have Instrumentation and logging, which is a good start. Is a stepping debugger required for the workshops? I am just asking to evaluate on what has the highest priority.

Building the stepping debugger is a huge task with a lot of ui design involved and would definitely take up the majority of my time.

Late May early June is definitely ambitious but I think if we cut back on the debugger and focus on the features you mentioned we could have a useable WebIDE for the workshops.

@FWeinb
Copy link
Author

FWeinb commented Apr 5, 2019

@phoddie
I tried to integrate your latest changes and run into a different problem. The debugger is connected so fast that the ESP did not restart yet.
I solved it by not relying on the Timer to restart but rather block the HTTP request to mod/install until before the ESP is restarted.

main.js
@@ -97,20 +97,20 @@ class ModServer extends Server {
 			case 6:													// request body received
 				if (undefined !== this.position) {
 					trace("installed mod\n");
-					this.server.restart();
 				}
 				break;
-
 			case 8:
 				return {headers: ['Access-Control-Allow-Origin', '*', 'Access-Control-Allow-Methods', 'GET, PUT'],  body: "done\n"};
+			case 10:
+				if (undefined !== this.position) {
+					this.server.restart();
+				}
+				break;
 		}
 	}
 	restart() {
-		Timer.set(() => {
-			trace("restarting\n");
-			this.close();
-			restart();
-		}, 5000);
+		trace("restarting\n");
+		restart();
 	}
 }

It is working but the ESP is crashing instead of restarting cleanly:

Exception (3):
epc1=0x40201af1 epc2=0x00000000 epc3=0x00000000 excvaddr=0x400391a8 depc=0x00000000
ctx: cont
sp: 3ffe98e0 end: 3ffe9b80 offset: 01a0
>>>stack>>>
3ffe9a80:  3fff7d24 00000000 00000000 40207d10
3ffe9a90:  3ffefd0c 0000125d 0000125d 40201be0
3ffe9aa0:  00000018 3ffea248 3fff90f4 40202058
3ffe9ab0:  3fff7f8c 3ffea248 3fff8b54 40107054
3ffe9ac0:  402817bc 3fff8b54 000014d0 40100f7e
3ffe9ad0:  40280d89 3fff934c 00000018 40100ff8
3ffe9ae0:  402491ee 3fff8e94 3fff8e9c 40247101
3ffe9af0:  3fff7f8c 00000004 3fff8e94 40249f42
3ffe9b00:  fffffffe 3fff8e9c 3fff8e94 402486dd
3ffe9b10:  3ffefd0c 00001231 00001231 3fff8bec
3ffe9b20:  00000040 00000060 3fff8e94 40248799
3ffe9b30:  00000000 3ffefd2c 3fff8bec 402046d4
3ffe9b40:  40201462 3ffefd98 3fff8f5c 3ffe9bac
3ffe9b50:  3fffdad0 00000000 3ffe9ba4 40252262
3ffe9b60:  3fffdad0 00000000 3ffe9ba4 40252048
3ffe9b70:  feefeffe feefeffe 3ffe8b60 40100120
<<<stack<<<

# EXCEPTION DESCRIPTION
# Exception 3 LoadStoreError: Processor internal physical address or data error during load or store

# EXCEPTION LOCATION
# 0x40201af1: umm_assimilate_up at /Users/fweinb/esp/esp8266-2.3.0/cores/esp8266/umm_malloc/umm_malloc.c:1163

# CALLS
# 0x40207d10: fxCall at /Users/FWeinb/GitHub/moddable/xs/sources/xsAPI.c:1713
# 0x40201be0: _umm_free at /Users/fweinb/esp/esp8266-2.3.0/cores/esp8266/umm_malloc/umm_malloc.c:1287
# 0x40202058: free at /Users/fweinb/esp/esp8266-2.3.0/cores/esp8266/umm_malloc/umm_malloc.c:1733
# 0x40107054: vPortFree at /Users/fweinb/esp/esp8266-2.3.0/cores/esp8266/heap.c:18
# 0x402491ee: xs_socket_destructor at /Users/fweinb/GitHub/moddable/modules/network/socket/lwip/modSocket.c:1102
# 0x40247101: xs_timer_callback at /Users/fweinb/GitHub/moddable/modules/base/timer/modTimer.c:76
# 0x40249f42: xs_listener_destructor at /Users/fweinb/GitHub/moddable/modules/network/socket/lwip/modSocket.c:1530 (discriminator 2)
# 0x402486dd: socketDownUseCount at /Users/fweinb/GitHub/moddable/modules/network/socket/lwip/modSocket.c:1102
# 0x40248799: socketClearPending at /Users/fweinb/GitHub/moddable/modules/network/socket/lwip/modSocket.c:1102
# 0x402046d4: modMessageService at /Users/FWeinb/GitHub/moddable/xs/platforms/esp/xsHost.c:1072
# 0x40201462: delay at /Users/fweinb/esp/esp8266-2.3.0/cores/esp8266/core_esp8266_wiring.c:53
# 0x40252262: loop at /Users/FWeinb/GitHub/moddable/build/devices/esp/main.cpp:87
# 0x40252048: loop_wrapper() at /Users/fweinb/esp/esp8266-2.3.0/cores/esp8266/core_esp8266_main.cpp:56
# 0x40100120: cont_norm at /Users/fweinb/esp/esp8266-2.3.0/cores/esp8266/cont.S:109

@phoddie
Copy link
Owner

phoddie commented Apr 5, 2019

Yikes. I'll take a look over the weekend. FWIW - usually some time is needed before restarting to allow the HTTP request to finish. Without that, the installer (IDE) cannot reliably receive the HTTP response code that the upload succeeded.

@FWeinb
Copy link
Author

FWeinb commented Apr 5, 2019

@phoddie
Thanks. I investigated a little more and noticed that the main problem is that the XsbugServer isn't properly closed before restart which will never close the detached socket and the browser has no idea that the server closed the socket at all. Closing that socket would allow the browser to try to reconnect to the server.

@phoddie
Copy link
Owner

phoddie commented Apr 5, 2019

Thanks. I was thinking along the same lines on my drive to the office. I will try closing the listeners immediately but waiting to restart until the HTTP install connection is complete.

@FWeinb
Copy link
Author

FWeinb commented Apr 6, 2019

I did a rework of the ui and added the toolbar from vscode to separat the editing and debugging. I toke the moddable logo and did a little modification and integrated it, if that is something I should not have done I will remove it:

image

The debugging button in the toolbar will reflect the connection state by displaying a little coloured dot in the corner. Green means connected, blue connecting and red a connection error. The instruments data is still just dumped into the UI, I will create something similar to what is found in xbug:

image

The next step will be to update the file explorer to support basic file operations. That will take a little more time because I have to improvement the internal state structure for that.

@phoddie
Copy link
Owner

phoddie commented Apr 7, 2019

@FWeinb - Nice progress. The logo is fun, but we probably should not break the Moddable logo into component parts.

I have a bunch of changes nearly ready for you to try (I'll post again when they are live). I believe they give the behavior needed for the WebIDE -- the WebSocket receives a close message when restarting and no new incoming connections are accepted once an install, or any other operation that requires a restart, finishes. Further, the restart only waits 5 seconds when the network is slow. It usually is able to cleanly restart almost immediately (once any active HTTP requests are complete). In addition, the changes fix crashes on ESP8266 and ESP32 (very different lwip in the host platforms requires subtle changes in the Moddable client code...).

Still, a deploy & debugging flow is a little tricky over the network, all the more so to work on a microcontroller. I imagine we will refine it further in the future.

@FWeinb
Copy link
Author

FWeinb commented Apr 7, 2019

@phoddie
I though so too regarding the logo, I will revert back to just having WebIDE in the top bar.
Getting the deploy & debugging flow right is tricky but essential. It is awesome to see that you could build something usable this fast. Great to see this much progress in this short of time.

I am very excited to work on the WebIDE more.

@phoddie
Copy link
Owner

phoddie commented Apr 7, 2019

Changes are pushed:

  • Update this repository
  • Update Moddable SDK
  • Reapply the xsPlatform.c/h patches

I hope the crashes have been eliminated, though they were always sporadic for me so it is difficult to be sure.

@FWeinb
Copy link
Author

FWeinb commented Apr 8, 2019

@phoddie Great work, got it working in the WebIDE.

Also got some improvements into the debugging, very crude UI but it is getting there:
image

On thing I have noticed it that if the debugging is stopped for to long the ESP8266 is crashing.

Also added some very basic file adding/removing:
image

These icons are only shown on hover, to not distract too much from the editor.

@phoddie
Copy link
Owner

phoddie commented Apr 8, 2019

Great to see the pieces working together. I'll look into the crash. In my test, I never stop long at a breakpoint. It may just be the watchdog timer.

@phoddie
Copy link
Owner

phoddie commented Apr 8, 2019

I can't seem to get a crash when stopped at a breakpoint. I modified xsbug.js to wait two minutes at a break and continue. That works:

xsb.onBreak = function(msg) {
//	this.doGo();
	console.log("BREAK!")
	setTimeout(() => {
		console.log(" Continue")
		this.doGo()
	}, 1000 * 120);
}

How can I reproduce the problem?

Note that while stopped in xsbug, the http server is blocked since that is hosted by the virtual machine being debugged. Consequently, while stopped at a breakpoint none of the commands to install, restart, etc, will respond.

@FWeinb
Copy link
Author

FWeinb commented Apr 9, 2019

@phoddie
I just tested it again. It was not the long break but the unexpected closure of the WebSocket connection from the browser (when closing the WebIDE while connected to the device)

You can find a crash dump here

@phoddie
Copy link
Owner

phoddie commented Apr 9, 2019

Thanks. Indeed, closing the browser while at a break caused problems. Fixes forthcoming - will let you know when everything is in place to try.

@FWeinb
Copy link
Author

FWeinb commented Apr 9, 2019

@phoddie
Added file drag-and-drop support to the file explorer

image

I don't now if this is necessary but folder support would be nice. A way to download the code in a zip with all the files to compile it locally would be nice to.

@phoddie
Copy link
Owner

phoddie commented Apr 9, 2019

The upload works. While it seems to build the uploaded file, I couldn't seem to get it to execute -- the changes I made to mod.js to invoke it didn't seem to get deployed. I'll have to experiment with that further.

@phoddie
Copy link
Owner

phoddie commented Apr 9, 2019

There are some changes to help with the debugging connection reliability you reported. You'll need to update the Moddable SDK and then apply the latest xsPlatform.c/h patches from the runmod repository.

  • Disconnect while in the debug loop should no longer trigger the watchdog timer. Instead execution should continue.
  • Incoming connection requests are ignored while stoped at a breakpoint (incoming data was already deferred)
  • Disconnect while transmitting data should no longer trigger infinite loops (but I couldn't seem to trigger this condition)

@FWeinb
Copy link
Author

FWeinb commented Apr 10, 2019

@phoddie
Pushed a quick fix for the not updated deployment. All files are saved before the compilation starts now.

I need to completely rewrite the file handling because it is currently very messy, that part was written as a first draft.

Will try your changes tomorrow (it's getting very late/early here)
Was curious and did test it. It is working really great now! The connection will stay open until just before the device is restarted and you get all the logs in the WebIDE about the upload.
image

@phoddie
Copy link
Owner

phoddie commented Apr 10, 2019

Very happy to hear the debugger connection behavior is trending in the right direction. I committed a small change to the xsPlatform.c patch to fix a memory leak when the network debugging connection is dropped. In practice that shouldn't matter here, but it was a problem for a scenario where the debugger connects and disconnects multiple times without an intervening reboot.

I was able to drag & drop a file and have it work as expected. Edits redeployed too. Very nice.

I did run into one hiccup worth noting. The file I uploaded first was named main.js.That didn't work because there is already a main module in the host and it is preloaded. An installed mod cannot override a preloaded module, so that silently failed. Not perfect, but given the way JavaScript and XS are defined, I'm not sure how to allow it. The IDE could flag the conflict (e.g. compare the list of modules returned by the debugger to those modules it intends to deploy). It isn't a priority though. Just noting it here so no one else loses time tracking it down.

@FWeinb
Copy link
Author

FWeinb commented Apr 13, 2019

@phoddie
Had some time to work on this a little more. I build a proper storage solution and have a complete file manager now.

The latest changes to xsPlatform.c are very unstable for me. I get multiple crashes and can't redeploy at all. I need to rest the ESP to get it to work again.

The compiler is working with the full file tree but I think that runmod can't handle accessing modules in sub path. That needs to be updated.

I also modified the gist loading to just import the files into the current workspace (warning before overwriting files).

@phoddie
Copy link
Owner

phoddie commented Apr 13, 2019

The latest changes to xsPlatform.c are very unstable for me

That's troubling. I assume you are referring to the changes of April 10. Those are relatively monitor. I recall you said the changes of April 9 were working well for you. I'll take a look.

The compiler is working with the full file tree but I think that runmod can't handle accessing modules in sub path. That needs to be updated.

I'm not sure I understand. If you would provide instructions for how to see the problem, I can take a look.

@FWeinb
Copy link
Author

FWeinb commented Apr 13, 2019

@phoddie
Yes. The changes made on April 10 are breaking the deploy workflow.

I am currently importing „ping“ as if it where in the root directory but in the file tree you can see it is located in the „src“ directory. If you change it to „src/ping“ runmod is complaining that it can’t find the module.

@phoddie
Copy link
Owner

phoddie commented Apr 13, 2019

runmod does support paths such as src/ping. The build needs to be modified to put the correct path in the binary. I've updated the ping example and build instructions in the documentation to show how to do that. With the changes, the ping module is now loaded fromnetwork/ping instead of ping.

@phoddie
Copy link
Owner

phoddie commented Apr 13, 2019

Regarding instabilities, I don't see any crashes. I do see the WebIDE waiting. I was able to resolve that by being less aggressive about restarting the microcontroller to allow the TCP socket to close cleanly. Here's a quick hack to try to see if that also addresses the problems you observe. Change line 122 of main.js from

restart();

to

Timer.set(restart, 1000);

@phoddie
Copy link
Owner

phoddie commented May 2, 2019

Excellent. I'll try to have it committed before the weekend.

@phoddie
Copy link
Owner

phoddie commented May 4, 2019

Changes are committed. The docs have been updated as well. The patches changed, so be sure to reapply those. It is a lot of changes, so it wouldn't be surprising if there are problems. Let me know how it goes.

@phoddie
Copy link
Owner

phoddie commented May 4, 2019

(Now with ESP32 support)

@FWeinb
Copy link
Author

FWeinb commented May 4, 2019

@phoddie
Got it working in the WebIDE. There was a minor issue, it seams that you are using an update version of the core websocket module. For me Server.handshake and Server.subprotocol where undefined. I changed these to the numeric values and everything started to work.

Animated Showcase of the WebIDE

@phoddie
Copy link
Owner

phoddie commented May 4, 2019

@FWeinb That's great! I'm glad it wasn't too tough to make the changes. I will try it out a bit later.

Apologies for my oversight on the WebSocket constants. Those will be in our next Moddable SDK push.

FWIW -- we have some progress on the wasm tools work. That should be available soon.

@phoddie
Copy link
Owner

phoddie commented May 6, 2019

@FWeinb - Just a quick note here that we've pushed an update to the Moddable SDK with a substantial revision to the wasm tools support. I've opened a separate issue for discussion of that. It includes a link to documentation as well.

@FWeinb
Copy link
Author

FWeinb commented May 6, 2019

@phoddie that looks great! I will look into it and try to update the WebIDE with it. Might be a good idea to make that manifest file editable from within the WebIDE too.

Really great to see your efforts in pushing these WASM tools.

@FWeinb
Copy link
Author

FWeinb commented May 10, 2019

@phoddie
I think you will like this! Have some progress regarding the debugging story inside the WebIDE. I did not have time to implement the the exception handling but local/global/module frames are implemented as well as the list of call sites. I will need to integrate all of that a bit more with the file editor but it is a start.

As always, I made a little video showing it in action (click on the image).
Debugger in action

Creating breakpoints from within the editor and sending them to the microcontroler will be my next objective.

@phoddie
Copy link
Owner

phoddie commented May 10, 2019

Superb! And it is fast too.

@FWeinb
Copy link
Author

FWeinb commented May 10, 2019

While implementing this I noticed two three things about the communication with the device.

  • Currently if we connect to it the device performs a debug stop and needs to get the <go/> command to allow to install a new mod.

  • Another thing was that explicitly closing the socket to the device from the client using socket.close() seams to destroy the underlying socket and I am not able to connect to the device again, need to perform a rest of the device.

  • when the device is restarted via the debugger or after uploading a new module the device should refuse any attempt to connect to it immediately. I try to reconnect to the device as fast es possible but currently have to inject a delay because I don’t want to connect to the device before it rebooted.

As you said. Everything did turn out pretty fast in the way the debugging connection is handling all the traffic while toggling the debug frame information. Good idea to eliminate the http server and only have the web socket connection!

@phoddie
Copy link
Owner

phoddie commented May 10, 2019 via email

@phoddie
Copy link
Owner

phoddie commented May 11, 2019

Currently if we connect to it the device performance a debug stop and needs to get the command to allow to install a new mod.

In my testing, this works. I tested with the xsbug.js script by waiting three seconds after connecting and sending a step, install, and restart:

setTimeout(function() {
	xsb.doStep();
	xsb.doInstall(0, helloWorldXSA);
	xsb.doRestart();
}, 3 * 1000);

If you still see the problem after updating, please let me know the steps to reproduce it.

Another thing was that explicitly closing the socket to the device from the client using socket.close() seams to destroy the underlying socket and I am not able to connect to the device again, need to perform a rest of the device.

The microcontroller was not handling the close request from the browser. The result was that the microcontrollers believed it was still connected and the browser was waiting for a reply to its close request. WebSockets close is now implemented. I was able to connect and disconnect several times in row without restarting.

when the device is restarted via the debugger or after uploading a new module the device should refuse any attempt to connect to it immediately. I try to reconnect to the device as fast es possible but currently have to inject a delay because I don’t want to connect to the device before it rebooted.

This one is complicated. I agree that a delay isn't a great approach. Let's try to eliminate that. After you send a restart, the WebSocket connection should cleanly close. If you wait until the web socket close is received, the device's web socket listener should be gone too. Terminating the listener on receiving the restart command is tough, because it is owned by the application script which is many layers away from the debugger bridge. I'll think about that some more.

@FWeinb
Copy link
Author

FWeinb commented May 11, 2019

Thanks for looking into this

Regarding that example:

setTimeout(function() {
	xsb.doStep();
	xsb.doInstall(0, helloWorldXSA);
	xsb.doRestart();
}, 3 * 1000);

As I am thinking about it my initial idea was to remove the need for doing a doStep there to conceptually split the concerns of the installation process from the debug process. I might not be explaining this good enough. Just from a conceptual standpoint it is strange to have to do a doStep before you can install a new module onto the device, by mixing two concerns debugging and installing.

The last command xsb.doRestart() is currently optional, should we make that explicit or should we keep the current behavior that doInstall will reboot the device automatically?

WebSockets close is now
implemented.

Great! In the next update of the WebIDE I will close the connection to the device.

@phoddie
Copy link
Owner

phoddie commented May 11, 2019

Just from a conceptual standpoint it is strange to have to do a doStep before you can install a new module onto the device ...

The communication protocol does not require you to stop in the debugger in order to install. I gave that example as I understood your previous comment as indicating install did not work when stopped.

That said, I think you should. Depending on the host, you may be overwriting the executing byte code for the currently running mod. That is effectively corrupting the running code and will surely lead to problems. On the ESP8266 it is currently safe because the upload goes to a separate section prior to being installed, but on the ESP32 the upload goes directly to the location where the code executes. They are different because of architectural differences in the hardware.

The last command xsb.doRestart() is currently optional, should we make that explicit or should we keep the current behavior that doInstall will reboot the device automatically?

Install does not perform a restart. The install over http did restart, so perhaps you are recalling that. I changed it in the WebSocket version to give the IDE more control over the process (e.g. perhaps after install it wants to do something else, like update a preference, before restarting).

@FWeinb
Copy link
Author

FWeinb commented May 11, 2019

That said, I think you should. Depending on the host, you may be overwriting the executing byte code for the currently running mod.

Okay that makes sense. Let’s keep it as is.

Install does not perform a restart. The install over http did restart, so perhaps you are recalling that.

Yes I did mix that up.
But isn’t this dangerous in regards to your previous point? After and install the device must be restart, continuing will lead to a crash on the esp32.

@phoddie
Copy link
Owner

phoddie commented May 11, 2019

But isn’t this dangerous in regards to your previous point?
After and install the device must be restart, continuing will lead to a crash on the esp32.

My feeling is that a debugging interface is inherently dangerous because it needs broad access to do its job. There are lots of ways to crash or otherwise cause havoc. I'm not sure it is possible to make it safe in all case. I fear it could be a lot of work to try.

At the moment, my focus is making the debug inteface functional, reliable, and fast. That's already challenging. Any tool using the debug interface (e.g. WebIDE) needs to be aware of what is safe and implement against that. And we are still discovering what is safe. ;)

@FWeinb
Copy link
Author

FWeinb commented May 13, 2019

@phoddie
Got the breakpoints from the WebIDE working.
Click to see it in action:
WebIDE with debugging stop

@phoddie
Copy link
Owner

phoddie commented May 13, 2019

Very nice. It works just the way it should. ;)

@FWeinb
Copy link
Author

FWeinb commented May 13, 2019

After some testing today I ran into an issue that I can't solve. The Moddable Zero is always crashing after uploading the mod via the web browser. I tried to reflash runmod but I still run into these two crashes.

I tried to not run the mod on boot but still after trying to flash it via the WebIDE the ESP is crashing.

@phoddie
Copy link
Owner

phoddie commented May 13, 2019

The first stack trace is the installation of a new mod after rebooting (fxMapArchive). I've never seen a crash there. Either the mod data is a corrupt or it is a previously unseen bug in the install process.

The second trace is less obvious. It looks like it is trying to load and run the mod (fxResolveModule). That it crashes again might be because the mod data is corrupt, or something else entirely. Tough to say without more info.

If you haven't already, try resetting your flash and reinstalling. It shouldn't matter but...

esptool.py erase_flash

And just in case... I posted a fix a few days ago to a bug that corrupted mod installs. Please make sure you are running with that.

@FWeinb
Copy link
Author

FWeinb commented May 14, 2019

@phoddie
Yes, there was indeed a corrupted mod stored on the device. Erasing the flash and re-flashing runmod fixed it. Still strange how this could have happened, I can't reproduce it now.

@FWeinb
Copy link
Author

FWeinb commented May 14, 2019

@phoddie
Added breakpoints to the debugging tab to have an easy way to enable/disable them during runtime.

Debugger with toggleable breakpoints

@phoddie
Copy link
Owner

phoddie commented May 14, 2019

Nice. First feature debugging feature not also in xsbug.

@phoddie
Copy link
Owner

phoddie commented May 27, 2019

@FWeinb - Both of us have occasionally encountered situations where a mod is corrupt. This seems to happen when the transfer is interrupted -- for example by unplugging the device in mid-transfer. The transfer is usually so fast that there isn't much opportunity to happen, although over Wi-Fi stalls do happen so it is more likely. Yesterday, I found a bug in the SPI read/write functions that caused occasional crashes while uploading a mod. I fixed that and will push in the next day or two.

That got me thinking about how to ensure an interrupted mod upload doesn't leave a partially installed (and consequently corrupt) mod in place. The solution I found can be implemented in the WebIDE without a change to the device code. It relies on writing the device header only at the end of the transfer, rather than at the start.

  1. Upload first 4 bytes of mod. This triggers the erase of the full block of flash, which resets any existing signature to ~0.
  2. Do not upload bytes 4 to 8 of the mod. This is the archive signature.
  3. Upload the remaining bytes of the mod (from 8 to the end) as usual.
  4. Go back and write the signature (bytes 4 to 8).
  5. Restart.

@FWeinb
Copy link
Author

FWeinb commented May 27, 2019

@phoddie
I will try to update the WebIDE as soon as I can.

@FWeinb
Copy link
Author

FWeinb commented May 27, 2019

@phoddie
Update the WebIDE.

I guess I have circled in on my problem regarding malformed xml data. If you set a breakpoint (e.g. by adding one using the WebIDE) and re-upload the same mod, in 99% of all cases I will get malformed XML from the device. No idea if this is related just wanted to let you know.

@phoddie
Copy link
Owner

phoddie commented May 27, 2019

I guess I have circled in on my problem regarding malformed xml data. If you set a breakpoint (e.g. by adding one using the WebIDE) and re-upload the same mod, in 99% of all cases I will get malformed XML from the device. No idea if this is related just wanted to let you know.

A (more or less) reproducible case is great. I assume this is only over serial/USB, not WebSockets. Once you upload the mod, you then restart, I assume. What are the commands that get sent after that?

@phoddie
Copy link
Owner

phoddie commented May 28, 2019

I ran into a situation this weekend where during the mod upload I was also configuring the debugger (setting breakpoints, etc). That was too much over serial for the ESP8266 and bad things happened. I fixed it by making sure that during an install nothing else was happening over serial. Since after installing the next step is rebooting, that isn't a problem. Perhaps related to your serial corruption problem.

@phoddie
Copy link
Owner

phoddie commented May 30, 2019

@FWeinb - I just pushed some changes.

  • The patches are now removed from this project as they are integrated in the Moddable SDK. That seems to be working well.
  • There is a new command to set the time, timezone, and daylight savings on the device from the IDE. This is convenient as there is no battery backed real time clock. It works well on ESP8266; on ESP32 the time is set but the timezone and daylights savings are not.
  • There is a command to set the baud rate. It isn't current used, but does work. It may be useful in some circumstances.
  • There is a new command to load a module by name. This has some interesting uses. For now, it allows us to simplify the runmod host. Instead of setting a preference to tell runmod when to execute the mod, the IDE can request that itself when it wants. This gives the IDE more control of the timing and allows a consistent IDE implementation across USB and WebSockets (send the load module message in onLogin, for example). See doLoadModule in xsbug.js for details of the binary message format. It also means that the mod does not have to be named mod (though it cannot be main because that is taken by the host).

If you use the load module command, we can simplify runmod/main.js to this:

import Net from "net";
import MDNS from "mdns";
import {Server} from "websocket"
import Preference from "preference";

class ModDevServer extends Server {
	callback(message, value) {
		if (Server.handshake === message)
			ModDevServer.debug(this.detach());
		else if (Server.subprotocol === message)
			return "x-xsbug";
	}
	static debug(socket) @ "xs_debug";		// hand-off native socket to debugger
}
Object.freeze(ModDevServer.prototype);

export default function() {
	trace(`host ready on serial\n`);

	if (Net.get("IP")) {
		const hostName = Preference.get("config", "name") || "runmod";
		new ModDevServer({port: 8080});
		new MDNS({hostName}, function(message, value) {
			if ((1 === message) && value)
				trace(`host ready at ws://${hostName}.local:8080\n`);
		});
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants