Skip to main content

Known Limitations and Future Work

Syntax Limitations

Some JS syntax constructs are not supported at all or support is limited:

  • Generator functions
    • Untested and not properly traced.
  • Some es6 features are traced correctly, but data flow analysis is limited.
    • We do not currently connect data flow through es6 deconstruction.
    • In verbose mode, Dbux raises some warnings tagged with "[NYI]" to notify you of those missing connections.

NOTE: The code should still work fine, but some of Dbux's analysis tools (especially Data Flow) will not be able to provide all actual connections.

Problems with Values

  • Big objects, arrays and strings are truncated because trying to record all values might severely impact performance.
  • We currently do not properly trace all built-in data types. This is tracked in:
  • We also plan to make the currently hardcoded thresholds configurable, if there is sufficient demand for this.

Calling process.exit as well as uncaught exceptions are not always handled properly

  • You might see a message along the lines of "Process shutdown but not all data has been sent out. Analysis will be incomplete. This is probably because of a crash or process.exit was called manually."
  • That is because process.exit and uncaught exceptions kill the process, even if not all recorded data has been sent out yet. As a result, not all runtime data could be recorded properly. That is why Dbux tries to stall upon process.exit and uncaught exceptions and also issues a warning.
    • NOTE: some frameworks that kill your process by can be configured not to do so (e.g. for Mocha you want to add the --no-exit flag).
  • This was tracked in:

Remote Analysis

@dbux/runtime is currently hard-coded to connect to a localhost server (see @dbux/runtime/src/client/Client.js). You thus cannot use Dbux remotely. However, one can export + import trace log files on different machines.

Tracked in:

Observer Effect

By trying to observe a program, while not intending to, you will inevitably change its behavior due to the observer effect. Here are a few examples:

  • Property getters with side effects will be called automatically by Dbux (to get all that juicy runtime data) and potentially break things
    • Dbux tracks data in real-time, by reading and recording variables, objects, arrays etc.
    • It also reads all (or at least many) properties of objects, thereby unwittingly causing property side-effects.
    • Examples:
      • class A { count = 0; get x() { return ++this.count; } }; const a = new A();
        • When Dbux reads x (when tracing the constructor call) it will unwittingly change this.count.
      • const o = { get z() { console.log('z called'); return 42; } }
        • When Dbux reads z, and you will see an unwanted "z called" in your console.
    • The only way to prevent these bugs is (currently) by writing side-effect-free getters (in most cases, getters are supposed to be side-effect-free anyway).
  • Proxies
    • As explained in the previous point, [@dbux/runtime](dbux-runtime] iterates over and collects values of object properties automatically in its quest for gathering runtime data.
    • As discussed here, Proxies are transparent by design; meaning there is no general way to determine if something is a proxy or not.
    • At the same time, Proxy property access, also very much by design, often has side effects.
    • -> This means that in many scenarios where Proxies (with side effects) are in play, you might just not be able to use Dbux properly.

You can completely disable tracing of any sensitive AST nodes by preceding them with a /* dbux disable */ comment. Tracked in issue #209.

eval and dynamically loaded code

As a general rule of thumb - Any dynamically loaded code will currently not be traced. That is because we are not proactively scanning the application for code injections or outside code references.

This includes:

  • Calling eval on non-instrumented code

  • Any kind of <script> tags containing or referencing non-instrumented code

  • If it is not generated dynamically: instrument that code beforehand.

  • If the code is generated dynamically, Dbux cannot be of help right now, as we would have to ship and inject @dbux/babel-plugin dynamically. While this is not impossible, it is not at all a priority to us. Contact us if you really need this to work.

Function.prototype.toString and do not behave as expected

Because we instrument the function body, and sometimes even change the structure of functions, to allow better tracing their behavior, their myFunc.toString() is not what you expect it to be. name on the other hand should always survive (please report an issue if not).

(This is only of concern to those who rely on serializing and deserializing functions. E.g. for sending functions of to run in a webworker* etc.)

File Path Issues on Windows

  • A bug unrelated to Dbux occurs very rarely, when running things in VSCode's built-in terminal: it might change require or import paths to lower- or upper-case drive letter.
    • NOTE: Luckily, we have not seen this bug occur in quite some time.
    • The bug causes a mixture of lower-case and upper-case drive letters to start appearing in require paths
    • Official bug report:
    • Workaround: Restart your computer (can help!), run command in external cmd or find a better behaving shell/terminal.

Future Work: Missing Features

This list serves to keep track of features that could prove very valuable for dynamic analysis and debugging purposes.

In addition to the issue tracker, we have some more "exotic items" that we can only add slowly over time, and we encourage Dbux users to talk to us about and vote in favor of. So many things that can be done... So little time...

  • Fix #640: tracing the internals of react is currently (01/2022) bugged.
  • Change @dbux/runtime to evict unused data.
    • NOTE: It currently keeps almost all data in memory, since it will need some of it to keep track of and/or establish connections between reads, writes, interrupted functions and more.
  • Typescript support.
  • Properly test and provide recipes for all environments, e.g.:
    • Node's vm (Jest uses that also)
    • WebWorker
    • WebContainer
    • more...
  • Config file support for instrumentation + runtime.
  • Configurable stats display for CallGraph stats (see ContextNode._addStats)
  • Proper stats screen where one can easily analyze all kinds of program execution statistics
  • Better loop comprehension (tracked in #222).
  • Advanced analysis of code along the dependency tree(s)
  • Support web-based VSCode
  • Support Yarn PnP - considerations include:
    • Using Traditional Debugger with PNP
      • NOTE: file paths could look a little like this: repo/.yarn/virtual/webpack-dev-server-virtual-98c281437e/0/cache/
      • ESM Support

Future Work: Crazy Ideas

  • Dynamic, adaptive runtime recording, to reduce noise and improve performance.
    • Currently, a loop of 1 million iterations already stretches Dbux to its limits. We want to improve that.
    • Adaptive trace logging would be advantageous. It should:
      1. Only log traces that are "relevant", and:
      2. Allow user to easily select or change what is "relevant".
  • More advanced search/filter analysis features, such as...
    • searching for arrays/objects that contain certain values
    • searching/filtering of/by all (or subset of) node_modules, package names
    • enabling/disabling/grouping of/by modules/files etc. in call graph
    • searching/filtering only system calls or sub-systems (e.g. all HTTP calls)
    • complex search queries (and, or, parentheses etc.)
  • Advanced context-sensitive keymap support to expand/collapse/click all buttons (e.g. similar to AOE4's "grid keys")
    • provide a single Toggle Dbux Keymap shortcut/command. When enabled:
    • show relevant shortcut key next to each button (if possible?)
    • vscode.commands.executeCommand('setContext', 'dbux.keyboardMode.enabled', true);
    { "keybindings": [
    "command": "dbux.selectTrace",
    "key": "q",
    "when": "dbux.keyboardMode.enabled"
    // ...
    // this command toggle expands/collapses the first "expandable" button of TraceDetails (usually `Value`)
    "command": "dbux.traceDetails.btns.toggle.first"
    // ...
    // ...
    // this command clicks the first "meaningfully clickable" button of TraceDetails (which is the first navigation button?)
    "command": ""
    // ...