[jsc-dev] How to preload JS scripts into the Web Inspector Debugger without evaluating them?

Brian Burg bburg at apple.com
Fri Jul 13 14:22:14 PDT 2018


Alexander wrote:

>  I have a big JSON file with 400+ different JS scripts which is stored in the iOS app's local db. […] I want to see all of these scripts under Sources tab handy without actually evaluating them, […]


If I understand what you are saying correctly, what you are trying to do is nonsensical. If you have have a bunch of strings that you eval some time later, there’s no way Web Inspector would be able to infer that those are actually scripts until they are parsed as JS and evaluated.

Saam wrote:

>  I believe the reason the inspector needs to actually have the scripts evaluated is once you see the scripts in the inspector, you’re able to set breakpoints and such. This would not be doable without evaluating the scripts.


Under the hood, Web Inspector can set a regex breakpoint that isn’t resolved to a specific FunctionExecutable or whatever. However, this only is possible via UI interactions if the resource has been fetched and parsed through the normal loading mechanisms and shown in the Resources Tab. IIRC the most common case of unresolved/regex breakpoints is for inline scripts in an HTML file.

It’s unclear whether this “app’s local db” is a web database or native database, but the premise is the same: Web Inspector can’t show resources that it hasn’t received. I can’t think of any other case where we would show a resource in Web Inspector without WebKit having tried to parse and evaluate it (if applicable).

FWIW, engineering builds of WebInspectorUI load over 300 separate JS files as part of the UI, and Web Inspector can inspect itself (containing over 600 parsed resources) with no problem. Because the app uses MVC layering and namespaces, we’ve always been able to find an import order that works without any tool assistance. Tools like Browserify can solve this even in tricky cases, i.e. NPM module dependency graphs.

Alexander wrote:

>  But I tried to call JSCheckScriptSyntax() which internally calls makeSource() and it didn't work. Apparently, makeSource() doesn't do an actual parsing? 
> 
> Maybe there is a way by some means to trick an Inspector's debugger ? Perhaps I can pre-parse those scripts somehow without evaluating them in a side-effectful way?

makeSource() puts the bytes of the resource into a struct. checkSyntax() tries to build an AST and reports an exception if one happened. Neither actually evaluates the code into existence. We check syntax in many places (i.e., prior to running code, and for every console autocompletion) and wouldn’t want to show all of those in Web Inspector unless it’s something a developer wants to see.







> On Jul 13, 2018, at 1:25 PM, Alexander Karaberov <alexander.karaberov at gmail.com> wrote:
> 
> Hi Saam and JSC folks,
> 
> Is the goal here just to be able to view all the sources of your scripts? 
> 
> Yes exactly. I just want to see all of them at once, set breakpoints and so on.
> 
> Perhaps there is a way to design these scripts so they don’t actually do any work 
> 
> Unfortunately no. Because some of those scripts are written by 3-rd party developers and we don't want to introduce artificial restrictions for our JS sandbox only to satisfy our debugging whims. This machinery should be completely opaque.
> 
> So you said:
> 
> I don’t know of a way to accomplish this without at least parsing the scripts.
> 
> 

> From my understanding there is no public API for this, right? One of the solutions might be to know an exact function which is responsible for loading script's source into the debugger. Then I may try to get it by dsym("mangled_name") and try to call.
> 
> But it would be really perfect if there is an easier and less hack-ish way to view all the sources of the scripts in the debugger without evaluating them and modifying script sources.
> 
> All the best,
> Alexander
> 
> 
> On Fri, Jul 13, 2018 at 8:41 PM, Saam barati <sbarati at apple.com <mailto:sbarati at apple.com>> wrote:
> + Some folks that work on the web inspector
> 
> Hi Alexander,
> 
> I don’t know of a way to accomplish this without at least parsing the scripts. Is the goal here just to be able to view all the sources of your scripts? I believe the reason the inspector needs to actually have the scripts evaluated is once you see the scripts in the inspector, you’re able to set breakpoints and such. This would not be doable without evaluating the scripts.
> 
> Perhaps there is a way to design these scripts so they don’t actually do any work (like call other functions that may not yet be set up) when you evaluate them. Perhaps they can just expose a single function that can be called to actually make them start doing work?
> 
> - Saam
> 
> > On Jul 6, 2018, at 2:25 PM, Alexander Karaberov <alexander.karaberov at gmail.com <mailto:alexander.karaberov at gmail.com>> wrote:
> > 
> > Hello jsc-dev folks,
> > 
> > I’m currently struggling with one issue. Long story short: let's say I have a big JSON file with 400+ different JS scripts which is stored in the iOS app's local db. When I run a dev/simulator build of the app and open Safari --> Develop --> Debugger I want to see all of these scripts under Sources tab handy without actually evaluating them, otherwise debugging process becomes a bit cumbersome. Also our app is used by a lot of JavaScript developers who develop custom scripts for it, normally they use a simulator + Safari Debugger and they also want to see all the scripts at once. From my understanding for the JS script to be visible in the Debugger --> Sources tab it has be evaluated first. And indeed if I call JSEvaluateScript() in a for-loop for all the 400+ scripts stored in the file it works and I can see all of them in the Debugger. The problem with this approach is that it causes an avalanche of different side-effects, exceptions thrown and so forth, because some scripts call another ones, some scripts are not ready yet to be called (some of the libs or modules were not loaded for instance), some are not intended for execution at the given moment at all and etc. So I have to come up with a different solution and make Inspector's Debugger aware of all the JS scripts at once without executing all of them. In the best case scenario I want something akin to (roughly) JSInspectorLoad(script) which I will call for all the scripts in the file. I tried to call JSCheckScriptSyntax() in a loop in the same way, but it didn’t work. It finds and reports errors but nonetheless in the Debugger I see only those scripts which have already been evaluated. I checked JavaScriptCore code and it seems that all the interesting logic related to Debugger/Inspector resides somewhere inside of profiledEvaluate() function namely either in the CodeProfiling profile(source) or vm.interpreter->executeProgram(). All those calls are private and unfortunately unavailable via the scarce JavaScriptCore public API. My next silly idea is to somehow get pointers to proper functions via the dlsym() and then call them, but I don’t even know where to start with this. Modifying and rebuilding my own version of JavaScriptCore together with its dependencies (bmalloc, WTF) and shipping all these (potentially broken) things with the app is definitely not an option for me. 
> > I will highly appreciate if someone suggests a different approach to preload scripts to the Debugger without evaluating them. Maybe I'm missing something and there is actually a way to do this, because I really need this feature. Thank you very much in advance! 
> > 
> > Kind Regards,
> > Alexander
> > 
> > _______________________________________________
> > jsc-dev mailing list
> > jsc-dev at lists.webkit.org <mailto:jsc-dev at lists.webkit.org>
> > https://lists.webkit.org/mailman/listinfo/jsc-dev <https://lists.webkit.org/mailman/listinfo/jsc-dev>
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/jsc-dev/attachments/20180713/1644e628/attachment-0001.html>


More information about the jsc-dev mailing list