[HN Gopher] Debugging tricks in the browser
___________________________________________________________________
Debugging tricks in the browser
Author : bkudria
Score : 541 points
Date : 2023-11-11 01:35 UTC (21 hours ago)
(HTM) web link (alan.norbauer.com)
(TXT) w3m dump (alan.norbauer.com)
| temporallobe wrote:
| None of these are weird or something the browser is trying to
| hide from you, just things that an experienced front-end
| developer would probably know, although I was not aware of the
| monitor() command.
|
| That being said, I am pleasantly surprised at the debugging and
| development tooling that is built right into most modern
| browsers. It really does make the UI development experience very
| powerful. I wish more back-end languages had this experience.
| ethbr1 wrote:
| It's a joke title.
| chii wrote:
| > I wish more back-end languages had this experience.
|
| the jvm debugging experience is pretty good imho.
|
| It's the compiled languages that have a poor experience with
| debugging - try injecting code to execute in a c debugger! It's
| hard as hell to do!
| bpye wrote:
| You know the tooling leaves something to be desired when
| editing instruction bytes is the best option to NOP out an
| assert - for example.
| saagarjha wrote:
| Generally a conditional breakpoint is good enough to do
| this (though perhaps not very fast).
| jeroenhd wrote:
| > try injecting code to execute in a c debugger! It's hard as
| hell to do!
|
| I mean, theoretically, not really? Allocate a page RW, put in
| some compiled code, remap as R+X, redirect execution there,
| return code execution to where it was. Jumping through those
| hoops will be more expensive when you use the debugger like
| that (you'd need to hot patch some kind of jump statement to
| circumvent that) but it's not exactly impossible.
|
| Things become difficult when the compiler starts optimizing
| out code, because the debugger would need to keep track of
| everything, but I don't see why it'd be technically
| impossible to do so.
|
| Executing code in a C debugger is basically how modern
| reverse engineering works, it's a lot harder than in other
| languages but it's certainly possible.
| saagarjha wrote:
| Yeah, both GDB and LLDB know how to do this.
| jeroenhd wrote:
| > I wish more back-end languages had this experience.
|
| I know what that feels like. I have that same feeling about a
| whole bunch of languages that has been available in .NET for at
| least 15 years now.
|
| When I got into programming, I moved from VB6 to VB.NET to C#,
| the latter two using a cracked version of MS Visual Studio I
| downloaded at school. I only started seriously using the
| debugger somewhere around the time I taught myself C#.
|
| Because of this, I got used to the idea that in a normal
| debugger, you could just click and drag back the point of
| execution, modify the code, and hit resume. The VS time
| traveling debugger will actually revert variable assignments,
| recompile the modified code, insert it in its place, and
| continue execution. This wouldn't work with P/Invoke calls, but
| it worked great for what I was trying to do. Debugging and
| fixing mistakes was absolutely trivial.
|
| Imagine my betrayal when I found out that there was nothing
| like this in C++, or Java, or Javascript. Java has gotten a
| similar feature, but I've never worked with an IDE that
| integrated it even close to how well VS 2008 integrated it.
|
| Even today, this seemingly basic feature that I took for
| granted just isn't available in many modern IDEs. I understand
| natively compiled languages like C/C++/Rust/Go not supporting
| the inline code replacement feature, but the hot reload in
| languages like Kotlin, Java, and Javascript just don't work
| like it did for me back in 2008.
|
| As for all these tricks: I think most of them are available in
| most IDEs. Anything involving conditional breakpoints will work
| regardless of the language you use (although languages like
| Rust can have some restrictions). Tracing callers should work
| in any decent debugger. Timing individual functions may require
| writing out long package names to get to the right methods, but
| they should be available. The monitor() trick can be replaced
| by a logging method breakpoint.
|
| How well DOM-related debugging works, will depend on whether or
| not your GUI framework uses a DOM and how it's constructed. If
| you're composing a DOM from multiple individual functions (like
| in React/Flutter/Kotlin Compose) then you can add breakpoints
| to all the relevant state alterations. If your tooling uses a
| more C-inspired windowing mechanism, you're probably going to
| have to get creative.
|
| When you get down into the weeds of it, I think you'll find
| that more of these features are available for backend languages
| than you might expect. I would recommend any developer to
| occasionally read the changelogs of their IDEs (or to grab an
| IDE if you normally don't use any) and take a few moments to
| explore the possibilities of modern debuggers.
| kccqzy wrote:
| I love your description of undoing code execution, modifying
| the code and continuing. I think too often these days because
| of the UNIX philosophy of doing one thing well, the debugger
| and the compiler and even the linker are different projects,
| making it unnecessarily complicated to combine these tools
| other than passing blobs of output into another tool's input.
| We should aim higher.
| seba_dos1 wrote:
| > Imagine my betrayal when I found out that there was nothing
| like this in C++, or Java, or Javascript.
|
| For compiled languages (C, C++, Go, Rust etc.), check out
| https://rr-project.org/
| jeroenhd wrote:
| This looks rather neat, and there seems to be ample IDE
| support as well! It looks absolutely perfect, but makes me
| wonder why this isn't included in VS Code and IntelliJ by
| default when you install a (supported) language's debugger.
| lenkite wrote:
| What pre-historic Java IDE were you using ? Intellij has
| supported time travel debugging in Java for nearly a decade.
|
| https://www.jetbrains.com/help/idea/altering-the-program-
| s-e...
| jeroenhd wrote:
| Back then, Eclipse was what every guide and book told me to
| use, so that was where I started. These days I'm mostly on
| Jetbrains products. Microsoft made VS a weirdly slow,
| bloated piece of kit, but I still miss some of the features
| they have had for ages.
|
| I don't get automatically reloaded classes in IntelliJ,
| though I think there's a button to manually reload code
| manually? The whole ease of development came from not
| having to manually pick what code to reload while
| debugging. Java also seems to have a bunch of limitations
| that C# doesn't have (and didn't have back when I tried it
| on Windows). For example, you can't add a method, or alter
| the return type of a method.
|
| As for time travel debugging, I'm not sure how you do that
| in IntelliJ? I can't even see any way to undo the previous
| line of execution, let alone step through code in two
| directions. It looks like there are plugins for a bunch of
| languages, though, but those are all external tools built
| by third parties.
|
| Rolling back executed code seems to work in Rider, but I
| don't seem to get any Edit and Continue functionality on
| Linux, which is probably a Microsoft thing.
|
| It looks like I was mistaken though, "IntelliTrace" was a
| VS2010 feature, not 2008: https://learn.microsoft.com/en-
| us/archive/msdn-magazine/2010...
| jmkni wrote:
| I think the author was just having a bit of fun with the title
| adamnemecek wrote:
| `queryObjects` is notably missing. It is a crazy API which
| returns a list of all objects created by a particular
| constructor. One can for example get a list of all functions on
| the heap by doing `queryObjects(Function)`.
|
| This will return even functions contained in some module that are
| "private".
| chrismorgan wrote:
| To be honest, this might be one they'd be _justified_ in not
| wanting you to know. Crazy indeed. Chromium-only, I presume.
| adamnemecek wrote:
| Haha, I agree.
|
| They do seem to have some strange restrictions on this. E.g.
| When you evaluate it the function returns undefined but it
| also outputs the array underneath. You can right click and
| save it to variable.
|
| I think the point of this so that you cannot assign the
| output programmatically, there has to be a person who saves
| it to a variable by right clicking.
| chrismorgan wrote:
| I think it'll be because for architectural reasons it can't
| return a value synchronously, combined with historical
| ergonomic reasons. I don't know when it was introduced,
| it's possible that originally it could be synchronous and
| only subsequent V8 changes prevented that. Probably it
| landed before you could use `await` in the console, and
| they decided that made the ergonomics of Promising it too
| bad for the typical use case (though _now_ you could write
| `await queryObjects(Function)` if it worked that way). All
| I _know_ is that the documentation at https://developer.chr
| ome.com/docs/devtools/console/utilities... says it returns
| an array of objects, which is patently false.
|
| I can't see any reason for preventing assigning the output
| programmatically.
| Jerrrry wrote:
| >>setTimeout(function() { debugger; }, 5000);
|
| This is clever; after all, the only way to beat the recursive
| turtle stack of chrome debuggers debugging themselves is with the
| debugger statement.
|
| sam.pl, of the infamous myspace Sammy worm, used debugging
| gotcha's to prevent visitors from de-mystifying his obfuscated
| html homepage.
| zubairq wrote:
| Nice, I never knew this trick existed
| cookiengineer wrote:
| This is what happens when websites prevent an open
| Console/DevTools side panel. They basically have a main loop
| running, inserting a debugger; statement in various places
| where they're annoying, and they do that at 30FPS / 32ms so
| that the DevTools become useless because there's no way to
| "ignore" debugger statements.
| lexicality wrote:
| Why would this be a problem? I have a debugger. If you
| conveniently invoke it for me I can simply delete the
| offending code.
|
| Also both Chrome and Firefox have a "disable breakpoints"
| button that would instantly defeat this issue.
| themoonisachees wrote:
| This button was added to specifically combat that, and even
| then it means you can't use breakpoints at all. IMO the
| missing link is a way to specifically ignore a single
| debugger call.
| gear54rus wrote:
| TFA has instructions on adding conditional breakpoint
| with 'false' inside. Wouldn't this work?
| 3abiton wrote:
| Wait, that's it? This is too simple to be so good.
| darekkay wrote:
| That's one of my most used bookmarklets:
| https://darekkay.com/blog/debugging-dynamic-content/
| lelandfe wrote:
| Woah, "Emulate a focused page" is a great tip, too.
| awalGarg wrote:
| You can just hit F8 and the debugger will pause at the next
| instruction. Works in both Chrome/FF.
| DustinBrett wrote:
| Neither the bookmarklet or F8 is ideal if you want to
| retain focus and any other state that you may effect by
| going and clicking or pressing a key.
| lelandfe wrote:
| F8 first causes focus to be lost from the document body.
| Just tested in Chrome.
| johnfn wrote:
| Another way to do this, if you don't want to wait 5 seconds, is
| just to use the "pause script execution" shortcut, which is
| cmd-\\. It'll freeze the page on whatever line of JS was
| currently executing, and then you can inspect the problematic
| element like normal.
| Andrews54757 wrote:
| I've noticed that a lot of websites will try to prevent you from
| using the debugger. They use various techniques ranging from
| calling `debugger` every second to entrapped sourcemaps to make
| debugger features work against you!
|
| Take a look at disable-devtool [1], it surprises me just how many
| methods can be used to detect usage of an invaluable tool that
| should be a user's right to use. These "exploits" should really
| be patched browser-side, but I don't see any active efforts by
| browsers to fix this.
|
| I've created a simple anti-anti-debug extension [2] that monkey-
| patches my way around these anti-debug scripts. It works fine for
| now, but I can't imagine it working consistently in the long term
| once the inevitable arms race begins.
|
| How can we get Google, Mozilla, etc... to care about dev tool
| accessibility?
|
| [1]: https://github.com/theajack/disable-devtool
|
| [2]: https://github.com/Andrews54757/Anti-Anti-Debug
| supriyo-biswas wrote:
| A simple way to solve this issue is to just deprecate the
| debugger statement and have people rely on setting up
| breakpoints manually, or request an explicit opt in into the
| debugger statement so that random websites don't hijack it.
| Andrews54757 wrote:
| That would be helpful, but there are also other methods that
| don't involve using the debugger. For example, one technique
| involves periodically printing a custom object to the console
| with a toString getter. This is programmatically called by
| the browser only when the devtools are opened. This allows
| the website to know when you've opened devtools and they will
| redirect/block/crash your browser in response.
| no_time wrote:
| They don't need to deprecate it. I remember reading a
| blogpost here that was about bypassing these kinds of checks.
| They recompiled SpiderMonkey with the debugger() method
| renamed to something else.
| jeroenhd wrote:
| I've pondered why websites who are that afraid of reverse
| engineering don't simply feed the browser mock data or kill a
| user's session (with a five minute IP block) when the browser
| requests a source map. Almost all browsers request them by
| default the moment you open the debugger and normal users very
| rarely hit the debugger.
|
| Sure, it'd be trivial to circumvent such a block, but it'd
| easily inconvenience most of the low-hanging fruit enough that
| things like community maintained ad blockers could become
| ineffective. Surely simply never serving ads to people who open
| the dev tools would prevent the 99.9% of normal users from
| using effective ad blockers in their browsers.
| Andrews54757 wrote:
| I've seen some websites do this in the wild, it's why I
| recommend turning the sourcemaps off in the troubleshooting
| section of my anti-anti-debug tool.
|
| It's pretty easy to circumvent this method, but honestly the
| user shouldn't have to configure their browsers to be
| resistant to anti-debugging. From the side of the website, it
| should be impossible to know if the debug tools are just
| open.
| iudqnolq wrote:
| I haven't seen any anti reverse engineering on sites with
| significant technical expertise. For example Facebook just
| prints a very reasonable warning. I've seen anti-debugger
| stuff only on relatively shady and cheap websites. I suspect
| the issue with your suggestion is it would require replacing
| static file serving with a smarter backend.
| cxr wrote:
| Imagine if browser developer tools were reasonably architected
| so e.g. opening the DOM inspector didn't provide a vector for
| anti-tamper code targeting the JS debugger to DOS your attempts
| to poke at the CSS or read network requests. Or get this: for
| non-hostile content--like something you yourself have written--
| maybe you could have the debugger and the inspector open in
| separate windows, or even have multiple object inspectors open
| on different objects at the same time. Gee. Fuckin' novel idea.
| Maybe this is something we'll be able to look forward to once
| the year 2000 rolls around.
| quickthrower2 wrote:
| The ultimate way is process everything on the server with a
| sockets to webapi adaptor on the client. Then all you see is
| commands coming from the server to pull various strings.
| youngtaff wrote:
| Even then some sites detect the DevTools connection and
| prevent you from normal (on-site) actions
| quotemstr wrote:
| Don't any browsers support re-style reverse debugging yet?
| amluto wrote:
| I'd like to see a way to access local variables of an IIFE,
| without breaking into code in the IIFE's scope. Is there some way
| to convince the debugger to do this?
| jeroenhd wrote:
| If you're entering a breakpoint from a function called by the
| IIFE, you can just walk up the stack. If you're outside the
| IIFE entirely, I don't think it's possible The variables you're
| looking for may not even exist in memory, either before or
| after execution. Javascript doesn't have static variables like
| other languages do, so each time the IIFE is called, the
| variables inside it are thrown out. Javascript is also very
| much single-threaded (unless you use web workers and such,
| which come with limited interactivity with their parent pages)
| so unless you're trying to race-condition yourself with an
| async/await call, I don't think there's even a way to
| conceptually have these variables around in memory outside the
| IIFE scope.
|
| You could (ab)use `var` to initialize the variable outside the
| IIFE scope so you can see the values produced by the last IIFE
| call.
| plugin-baby wrote:
| IIFE: immediately-invoked function expression
|
| https://en.m.wikipedia.org/wiki/Immediately_invoked_function...
| kristopolous wrote:
| I wrote a tool to do that about 12 years ago. You still need to
| modify it a bit but you get a big bang for your buck
|
| https://github.com/kristopolous/_inject
|
| You can basically wander around any function context at any
| arbitrary time and see what happened. It exploits the reference
| counter to keep the contexts from being destroyed. It was
| really great back when I did a lot of client side js
|
| The killer app version of this would be to open a repl at any
| context. As it stands it requires a good bit of competency to
| do it well.
| Zecc wrote:
| Are you looking for logpoints?
|
| https://firefox-source-docs.mozilla.org/devtools-user/debugg...
|
| Edit: just realized this is literally the first thing mentioned
| in the linked article.
| amluto wrote:
| Not really. Suppose I have access to a closure that was
| created by the invocation of an IIFE. I would like to access
| variables that are in scope as seen from inside the closure,
| and I'd like to do this without executing the closure.
| cantSpellSober wrote:
| Why use IIFEs in JS now that we have block-scoping with
| let/const and modules to isolate data? (open question)
| rootsudo wrote:
| This is something I really need to pick up / is there a dedicated
| book or study for this or is it just web dev / front end all the
| way down?
| lancebeet wrote:
| I can really recommend following the "What's new in DevTools"
| series by the chrome team. Clicking a link to read release
| notes when you're in the middle of something may not seem
| appealing, but spending 5 minutes to skim through it when a new
| version is released is well worth your time. There are also
| digestible videos that are just a few minutes long and will
| give you a brief overview. While their purpose is to show new
| features, in my experience you will often gain understanding of
| the current limitations of the tools as well.
| russellbeattie wrote:
| I can never get watched variables to work. The scoping and
| updating rules for it are a mystery to me. I assume only global
| variables can be watched, but even then it never works as I
| expect, so I end up just flooding the log with values when
| testing.
|
| I've thought for years the console should add Data.gui [1] style
| UI for viewing/testing variable and settings values. You can see
| it action on this CodePen [2].
|
| 1. https://github.com/dataarts/dat.gui
|
| 2. https://codepen.io/russellbeattie/full/kGxaqM
| 20after4 wrote:
| I've had the same frustration. The browsers have such great
| debugging features, in theory, but they never seem to work
| reliably. I can't even get all of my breakpoints to reliably
| hit.
|
| Everything seems to work ok when the code is unrolled but as
| soon as it gets bundled, even if not minified, it seems that a
| lot of debugger features get broken, at least that's been my
| experience.
|
| Note: I'm not a front-end engineer and I'm probably doing
| something wrong.
| iudqnolq wrote:
| Even though minified variables appear under the correct name in
| the sidebar panel in chrome I still get an error that they're
| undefined in a watchpoint, which is annoying.
| acemarke wrote:
| I'm going to put in a very relevant self-plug for the tool that I
| work on.
|
| I work at Replay.io, and we're building a true "time traveling
| debugger" for JS. Our app is meant to help simplify debugging
| scenarios by making it easy to record, reproduce and investigate
| your code.
|
| The basic idea of Replay: Use our fork of Firefox or Chrome to
| make a recording of your app, load the recording in our debugger
| UI, and you can pause at _any_ point in the recording. In fact,
| you can add print statements to any line of code, and it will
| show you what it _would_ have printed _every time that line of
| code ran_!
|
| From there, you can jump to any of those print statement hits,
| and do typical step debugging and inspection of variables. So,
| it's the best of both worlds - you can use print statements _and_
| step debugging, together, at any point in time in the recording.
| It also lets you inspect the DOM and the React component tree at
| any point as well.
|
| I honestly wish I'd had Replay available much earlier in my
| career. I can think of quite a few bugs that I spent hours on
| that would have been _much_ easier to solve with a Replay
| recording. And as an OSS maintainer for Redux, there's been a
| number of bugs that I was _only_ able to solve myself in the last
| year because I was able to make a recording of a repro and
| investigate it further (like a tough subscription timing issue in
| RTK Query, or a transpilation issue in the RTK listener
| middleware).
|
| If anyone would like to try it out, see https://replay.io/record-
| bugs for the getting started steps to use Replay (although FYI
| we're in the middle of a transition from Firefox to Chromium as
| our primary recording browser fork).
|
| I also did a "Learn with Jason" episode where we talked about
| debugging concepts in general, looked at browser devtools UI
| features specifically, and then did an example of recording and
| debugging with Replay: https://www.learnwithjason.dev/travel-
| through-time-to-debug-...
|
| If you've got any questions, please come by our Discord and ask!
| https://replay.io/discord
| lelanthran wrote:
| > (although FYI we're in the middle of a transition from
| Firefox to Chromium as our primary recording browser fork)
|
| What's the goal of this transition?
| acemarke wrote:
| Replay's founders originally worked as engineers on the
| Firefox DevTools (and in fact our debugger client UI started
| as a fork of the FF Devtools codebase, although at this point
| we've rewritten basically every single feature over the last
| year and a half). So, the original Replay implementation
| started as a feature built into Firefox, and thus the current
| Replay recording browser you'd download has been our fork of
| Firefox with all the recording capabilities built in.
|
| But, Chromium is the dominant browser today. It's what
| consumers use, it's devs use for daily development, and it's
| what testing tools like Cypress and Playwright default to
| running your tests in. So, we're in the process of getting
| our Chromium fork up to parity with Firefox.
|
| Currently, our Chromium for Linux fork is fully stable in
| terms of actual recording capability, and we use it
| extensively for recording E2E tests for ourselves and for
| customers. (in fact, if you want to, all the E2E recordings
| for our own PRs are public - you could pop open any of the
| recordings from this PR I merged yesterday [0] and debug how
| the tests ran in CI.)
|
| But, our Chromium fork does not yet have the UI in place to
| let a user manually log in and hit "Record" themselves, the
| way the Firefox fork does. It actually automatically records
| each tab you open, saves the recordings locally, and then you
| use our CLI tool to upload them to your account. We're
| actually working on this "Record" button _right now_ and hope
| to have that available in the next few weeks.
|
| Meanwhile, our Chrome for Mac and Windows forks are in early
| alpha, and the runtime team is focusing on stability and
| performance.
|
| Our goal is to get the manual recording capabilities in place
| ASAP so we can switch over and make Chromium the default
| browser you'd download to make recordings as an individual
| developer. It's already the default for configuring E2E test
| setups to record replays, since the interactive UI piece
| isn't necessary there.
|
| Also, many of the new time-travel-powered features that we're
| building rely on capabilities exposed by our Chromium fork,
| which the Firefox fork doesn't have. That includes the
| improved React DevTools support I've built over the last
| year, which relies on our time-travel backend API to extract
| React component tree data, and then does post-processing to
| enable nifty things like sourcemapping original component
| names even if you recorded a production app. I did a talk
| just a couple weeks ago at React Advanced about how I built
| that feature [1]. Meanwhile, my teammate Brian Vaughn, who
| was formerly on the React core team and built most of the
| current React DevTools browser extension UI, has just rebuilt
| our React DevTools UI components and started to integrate
| time-travel capabilities. He just got a working example of
| highlighting which props/hooks/state changed for a selected
| component, and we've got some other neat features like
| jumping between each time a component rendered coming soon.
| All that relies on data extracted from Chromium-based
| recordings.
|
| [0] https://github.com/replayio/devtools/pull/9885#issuecomme
| nt-...
|
| [1] https://blog.isquaredsoftware.com/2023/10/presentations-
| reac...
| Cannabat wrote:
| Do you plan to maintain the FF Replay fork?
|
| Great work Replay team! Awesome tech.
| acemarke wrote:
| Thanks! Yeah, the browser runtime team is doing
| incredible work to make this possible, backend has made
| great progress speeding up requests and improving
| scaling, and us frontend folks are getting to build on
| top of that.
|
| We're not currently doing active dev work on the FF fork
| due to the focus on Chromium, and I think the goal is to
| fully try to move over to Chromium as the user recording
| browser. So, we probably _won't_ be maintaining the FF
| fork going forward due to limited resources. I think our
| next runtime focus after Chromium parity will be Node.
| We've already got an alpha-level Node for Linux fork that
| actually works decently - I've used it myself to record
| Jest or Vitest tests or Node scripts, and debug them. But
| that does need a lot of work to flesh it out.
| altano wrote:
| I'm the author of the article and my advice is that you stop
| reading it and go learn about Replay.io instead. It's the most
| slept on web tech and will up your debugging game immensely.
| Seriously, go check it out.
| 10000truths wrote:
| Is replay.io able to deterministically replay multiple
| WebWorkers interacting with a SharedArrayBuffer?
| acemarke wrote:
| We might be able to replay the app as a whole, but we don't
| currently support debugging workers that I know of. I know we
| don't support recording WebGL at the moment, and there's
| probably a couple similar recording limitations I can't think
| of off the top of my head.
|
| We've got some articles linked in our docs that talk about
| how the recording/replay mechanism uses "effective
| determinism" that's close enough to the original to be
| accurate:
|
| https://docs.replay.io/learn-more/contribute/how-replay-
| work...
| dmitry-vsl wrote:
| >> you can use print statements and step debugging, together,
| at any point in time in the recording
|
| I am working on something similar. I am building an IDE that
| allows to jump from the line printed by a console.log call to a
| corresponding code location, and observe variables and
| intermediate expressions.
|
| It also displays a dynamic calltree of a program, allowing to
| navigate it in a time-travel manner.
|
| Currently it only supports pure functional subset of
| JavaScript, but I am working on support for imperative
| programming (mutating data in place).
|
| https://leporello.tech/
| aidos wrote:
| Once I can replicate an issue locally, I don't normally find it
| too difficult to understand what's happening.
|
| Harder is reproducing a bug based on what I've got to go on in
| Sentry. Mostly it's easy enough to figure out but the traces
| you get in JS are very light in information compared to what
| you get in Python for example.
|
| Anyone have any tips on getting more information in the initial
| report?
| crtasm wrote:
| > Once you launch the browser, you will be prompted to sign in
| with your Google account.
|
| What is the reason/need for this?
| acemarke wrote:
| Replay takes data privacy seriously. Recordings can be
| shared, but you control who has access to them, and we need
| to know who owns each recording. Our user accounts are
| currently based on Google auth, so you have to log in before
| recording so we can track ownership.
| adr1an wrote:
| For the sake of completeness, I can recommend Werkzeug. I use it
| for Django backend development and it's incredibly useful. It
| allows me to have "PDB" shell right in the browser whenever and
| wherever an exception is met.
| scwoodal wrote:
| +1. It's easy to drop a 1/0 wherever I want Werkzeug to show up
| in the browser.
| agumonkey wrote:
| does it still requires to have django-extension/runserver_plus
| ?
| adr1an wrote:
| idk if it's a hard requirement, probably not... but I am with
| it... at a dev-specific settings.py just like Django debug
| toolbar, to avoid adding a dependency to production ;)
| agumonkey wrote:
| Aight, I was just asking because we hit some tiny road
| bumps with runserver_plus long ago, but it might be worth
| using it again to shorten debugging time.
| Inviz wrote:
| One trick i use all the time is debugging by searching through
| loaded scripts by UI string:
|
| 1) Go to Network panel, start recording network requests
|
| 2) Open left sidebar and invoke search to type in the code/ui
| string you want to find
|
| 3) It'll usually find it in some weird bundled js chunk file,
| click on the result
|
| 4) It opens the network request for that file, now right click
| anywhere in file and pick "Open in Sources" or something along
| that line, that jumps to debugger
|
| 5) Now place your debugger statement, this will probably load
| sourcemaps too
| thrdbndndn wrote:
| Probably a good place to ask a specific question about debugging
| here.
|
| A few years ago, I was hacking a web bookreader.
|
| It has a function that is used to decode images (they're
| encrypted in some way) into canvas, and I want to find it so I
| can call it directly in my user script to batch download decoded
| images.
|
| So I monkey patched `CanvasRenderingContext2D` function, added
| breakpoint, and found where the the function is defined in the
| 100k lines of obfuscated JS source code, easily.
|
| The problem is.. once the page is rendered, the function would be
| nested in some objects, something like
| `window.abd.fdsfsd.r2323.fsdfs.fasf.xyy.myfunc`.
|
| I don't know how exactly I can find the full "path" of the
| function so I can call it, despite I'm literally pausing inside
| of it. I eventually got it done, but it was manual and painful.
|
| So I'm wandering: is there a better way to do it? The browser
| obviously knows it, it just lacks of a way to tell.
| kossTKR wrote:
| I would like to know this as well.
|
| A tree overview of all nested functions and objects with a
| search function that quickly jumps to that place, and maybe
| even let you call that function with data from state?
| j-krieger wrote:
| You can use `trace` to trace the call stack but I don't know of
| any way to walk back up the call stack.
| gear54rus wrote:
| Do you want to have this in Tampermonkey script ONLY or not
| necessarily? You can use ResourceOverride addon to simply
| replace the 100k script with your own script that is almost the
| same but also assigns the function you need to window.myFn or
| something. There it can just be picked up by TM.
| thrdbndndn wrote:
| Thanks for the suggestion, but the goal is to just _use_ this
| function in my own code (which has lots of other things going
| on).
|
| I guess it technically can be done by modifying the existing
| JS in-place, but doing so with a very large, minified JS
| would be a nightmare in term of maintenance.
| danShumway wrote:
| To parent off of GP, I've run into this recently while
| working on some webextension code and I'm thinking my
| solution is going to be to monkey-patch the script, but
| merely to expose a reference to the object/function in
| question.
|
| So TLDR don't monkey-patch a giant minified source file
| with a bunch of your own code. Monkey-patch the function
| just enough to get it to be exposed globally with its
| context, and then have your code separately reference it.
|
| This is still fragile (unless you have a stable entry point
| with regex or something, which is not completely certain to
| exist, it'll likely break whenever the script changes), and
| is still not ideal, and I'm still thinking a bit to see if
| I can do anything better, but I suspect it's more stable
| than trying to access the function directly by coding the
| path and should be a great deal simpler as well since it
| will work even if the function/context is in a closure.
|
| ----
|
| Of course, you might be lucky and there might actually be a
| way to get at the function. For example, I am separately
| looking into seeing if I can figure out a clean way to
| reliably look for imports exposed through a webpack bundle,
| since those are exposed globally and if you can find the
| paths reliably you should be able to get access to any of
| the imports (although you still won't have access to the
| closures). I haven't made much progress on it though,
| mostly because it's kind of frustrating to work on.
|
| ----
|
| There is also the possibility (although I suspect it would
| get very messy very quickly, and I'm not sure of current
| browser support) that you could theoretically maybe rig
| something together with `function.caller`
| (https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Refe...), possibly patching the
| minified source file merely to remove "use strict".
|
| I have not messed with `caller` in probably close to a
| decade at this point, so I make no promises at to whether
| it still works at all :) but... in its heyday before we
| realized how wildly insecure it was, it did allow
| reconstructing the stack from a function in-code in some
| situations.
| alex7734 wrote:
| The browser does not know the path. Also, if the function (or
| one of its parents) is in a closure, there may not even be a
| path to the function from window.
|
| If you're sure the function is reachable from window you can
| search for it recursively: (function () {
| function search(prefix, obj, fn, seen = null) {
| if (!seen) seen = new Set(); // Prevent
| cycles. if (seen.has(obj)) return false;
| seen.add(obj); console.log('Looking in ' +
| prefix); for (let key of Object.keys(obj))
| { let child = obj[key];
| if (child === null || child === undefined) {
| } else if (child === fn) {
| console.log('Found it! ' + prefix + '.' + key);
| return prefix + '.' + key; } else if
| (typeof child === 'object') { //
| Search this child. let res =
| search(prefix + '.' + key, child, fn, seen);
| if (res) { return res;
| } } }
| return false; } // For example:
| let fn = function() { alert('hi'); } window.a = {};
| window.a.b = {}; window.a.b.c = {};
| window.a.b.c.f = fn; return search('window',
| window, fn); })();
| thrdbndndn wrote:
| Yeah it's reachable (in unsafeWindow for user script), I
| eventually find it by something similar.
|
| In your example, you already has a reference of `fn` to use,
| which isn't the case for my userscript (if I have a
| reference, I would just use it!).
|
| I have to search based on the features in plain text of the
| function (using some regexes on `fn.toString()` to check how
| the arguments look like).
| alex7734 wrote:
| The idea is that you use a breakpoint somewhere where you
| have a reference to the function to see it then paste the
| search() function in the debugger console and call it to
| find it in window
| thrdbndndn wrote:
| Oh I got it now. Thanks! Will try next time.
| Zecc wrote:
| Have you tried accessing `arguments.callee`[0]? It is
| unfortunately deprecated and might throw an error. I've never
| tried it myself as I rarely use breakpoints in the debugger.
| [0]: https://developer.mozilla.org/en-
| US/docs/Web/JavaScript/Reference/Functions/arguments/callee
| Mizza wrote:
| I've been a Python/Elixir programmer for a long time and I make
| heavy use of pdb.set_trace()/IEx.pry().
|
| Lately, I've inherited a very messy NodeJS backend and have been
| pulling my remaining hair out working without proper debugging
| tools. I've gone back to 'console.log' debugging, but it makes me
| feel like a caveman.
|
| I can't believe that this whole popular ecosystem doesn't have a
| proper debugging REPL - can anybody point me in the right
| direction?
| 0000000000100 wrote:
| You can do some solid debugging with NodeJS if you use the
| VSCode dev tools. Just add it as a debugging option and you can
| add breakpoints and step through functions.
|
| Works pretty great, JavaScript is pretty nice to debug since
| everything is incapsulated inside an object for the most part.
| madeofpalk wrote:
| It does. `node --inspect-brk`. You can connect to it with VS
| Code or Chrome dev tools. The tricky part is whether there's
| build tooling infront of just the nodejs command, like
| converting typescript or something like that. But if you run
| `node`, then it's pretty easy.
|
| Its debugging REPL is just the javascript console itself.
| Mizza wrote:
| I looked into that a little bit, but I've got this TS
| transpiling crap to deal with as well, and I don't want to
| lose my live code reloading.
|
| I guess I'll try again when I find the time. Was hoping there
| was some 3rd party package I could use to just drop in and
| set a trace. Thanks.
| connor4312 wrote:
| That should work fine in the vscode debugger, you just want
| to make sure that the transpiler you're using is generating
| sourcemaps. Generally they do by default. If you have
| issues, open a github issue and I'll fix it :)
| williamdclt wrote:
| As somebody else pointed out, --inspect or --inspect-brk is
| what you're after.
|
| In VsCode you can also use the "open JavaScript debug terminal"
| command: it opens a terminal in which any node command
| automatically starts with a debugger attached
| kaptainscarlet wrote:
| What I like about the Elixir repl, which I assume is similar to
| the Erlang repl is its ability to connect to a live process, a
| feature I haven't seen in the Node JS ecosystem.
| agumonkey wrote:
| Maybe not sufficient, but I just found out about python snoop
|
| https://pypi.org/project/snoop/
|
| deep tracer decorator
| lewisjoe wrote:
| The debugging tools built within the browsers have come a long
| way in the last couple of decades. I'm a JS veteran and I'm
| deeply grateful to all the people putting in such efforts to make
| debugging code in the browser so intuitive.
|
| Whenever I go to a different zone of development, like backend or
| a different language, I miss this ecosystem of debugging tools
| that modern browsers have by default.
| beebeepka wrote:
| Absolutely. It's not perfect but it sure beats the debugging
| nodejs with vscode experience a fellow developer was pushing. I
| would take the console over this hell.
| pyrolistical wrote:
| I don't know if you are making the implication that you could
| use chrome devtools to debug nodejs, so I'm making it
| explicitly clear you can!
| https://nodejs.org/en/docs/guides/debugging-getting-started
| civilitty wrote:
| Shout outs to the people behind the Firebug extension which
| really kicked browser devtools into high gear.
| OOPMan wrote:
| What in particular do you feel is so special about the JS
| debugging experience?
|
| I've done a lot of debugging on Python, Java and C++ over the
| years and never felt like I was missing tools (although I
| certainly met plenty of people that were ignorant of their
| options in this regard...)
| halvo wrote:
| I switched to c# dev from web a couple years ago and am
| baffled there's no built in way to see the network requests
| my app is making when debugging
| TheBigSalad wrote:
| Lol been waiting patiently for that for 20 years in .Net.
| Such an obvious gap.
| elpachongco wrote:
| I haven't had the need to use it but I've been thinking if
| something like the last one `Monitor Events for Element` exists.
| Glad it does. Although according to the article, it's a Chrome-
| only feature. I wonder if there are any alternatives for Firefox?
| BMorearty wrote:
| Under the section "Debugging Property Reads": how would you
| convert `{configOption: true}` to `{get configOption() {
| debugger; return true; }}` using a conditional breakpoint?
___________________________________________________________________
(page generated 2023-11-11 23:01 UTC)