Archive

Posts Tagged ‘Monitor’

Spotlight on DWS’s IDebugger

December 3rd, 2010

DWScript includes a debugging facility, in the form of the IDebugger interface. The TdwsSimpleDebugger component implements that interface and can be used to simply surface the events.

Debugger interface

You activate a debugger by merely attaching it to a compiled script (a TdswProgram), you’ll then get notified of debugging events. Note that the events will be invoked from the thread the scripts runs in, so if you’ve got some UI updates involved f.i., you’ll have to handle the cross-thread synchronization.

  • StartDebug: invoked when the program execution (under debug) starts.
  • DoDebug: invoked for each instruction by executed.
  • StopDebug: invoked when the program execution (under debug) ends.
  • EnterFunc: invoked when the script enters a function.
  • LeaveFunc: invoked when the script enters a function.

For aborting script execution, you have the standard TdwsProgram.Stop method.

Standard debugging tasks

Breakpoints

Breakpoints can be implemented by merely checking the position of the instruction you get in DoDebug against a reference of breakpoints (you can use a TBits for that). You can then suspend or check conditions (see below).

Suspend, step

To suspend execution, just don’t return from DoDebug and the script will effectively be suspended.

When stepping, DoDebug will fire on instructions, so if you step from DoDebug to DoDebug, and the user placed two instruction in the same script lines f.i., you’ll step twice on the same script line. If that isn’t desirable, you can filter and step only if the source line changed.
Step into and step over can be implemented with the help of the EnterFunc/LeaveFunc notifications.

Evaluating symbols

If you want to evaluate a symbol, you can use Expr.Prog.Table.FindSymbol(), with Expr being the expression you got passed in the DoDebug. That will find the symbol in the current context (the current method if you’re in a method f.i.). You can also find a symbol from the root by going through the Root property.
Note that FindSymbol will return any symbol, not just variables (TDataSymbol), so you can use this to evaluate functions (with side-effects) if you wish. Data symbols are stored in the stack, so the relevant part for you will be a data symbol’s stack address (Addr).

The stack is accessible via Expr.Prog.Stack, you’ll need it to evaluate data symbols. You can of course also use it to modify a variable (just write to the variable’s stack location).

Call stack

DWS 2.1: If you want the call stack, the most pragmatic approach is IME to do it via EnterFunc/LeaveFunc, the script call stack structure exist, but they aren’t really geared towards ease of use when debugging. So you can just maintain your own simplified call stack.

DWS 2.2+: StackTrace is available directly in the execution, both as a raw expression CallStack array, or via CallStackToString, as a textual version. You also have access to any script Exception call stack via the StackTrace method.

Note on calls to Delphi-functions

Keep in mind the debugger can only operate on the script code. If the script has invoked a Delphi function, and your execution is stuck there, the debugger won’t help. You’ll have to handle suspension in your Delphi code.

That’s a reason why here it’s considered a good practice to wrap calls to Delphi code with a safety net, as failure, crashes, incorrect data are the norm when scripting. Raw exposure of Delphi (or external) functions can often be problematic when the user is writing and debugging his scripts.

Using the debugger for profiling

You can easily make use of IDebugger for profiling purposes via DoDebug and EnterFunc/LeaveFunc. Instrumenting is implicitly there, so it’s just a matter of performing the timings.

In our mini-IDE for scripting here (not open-source), a sampling profiler is always active when running code: it periodically suspends the script, notes the current expression, call stack and resumes execution ASAP. For scripting purposes, a sampling frequency of 100 Hz is more than enough IME, and it’s low-frequency enough to have no measurable impact on the script execution time.
Another cheap profiling tool is to add a function call counter (via EnterFunc), with the two combined, you can pretty much identify all bottlenecks at a glance.

Finally, another tool in your chest can be to implement an execution monitor with the debugger, like the one in SamplingProfiler, which can be useful not just at the IDE level, but also at runtime. A typical use is to make a watchdog screen, where you can have an overview of what all the running scripts are doing: useful to diagnose in-production slowdowns, see if they’re all stuck on the same database access, shared resources, or whatever.

Tips , , , , ,

SamplingProfiler 1.7.0 still hot from the compiler

April 15th, 2009

SamplingProfiler v1.7.0 is now available, you can get the zip and release details from its changelog page.

As announced last week, the changes are a fix for a bug that could drastically affect the execution speed of the profiled application when relying on MAP files for debug information, if you were hit by this bug, things should be like night and day with this version (and hopefully I didn’t break anything else in the process…).

The other main addition is that of the real-time monitor, which with default parameters and when activated locally should be reachable at http://localhost:880/ (see the help for other details). The monitor is still at an early stage, and only provides real-time information, as time allows, it may grow to offer more profiling and debug features.SamplingProfiler RealTime MonitorThe current monitor page is a rather basic html page that is fully refreshed periodically, which isn’t very pretty at the moment… an XML version of the real-time information is available at http://localhost:880/sampling.xml, if you come up with a pretty AJAX-based version before I do, feel free to contribute it ;)

News , , , , , , ,

MapFileStats v1.2 out and other news

April 9th, 2009
Comments Off

MapFileStats v1.2 is now available for download, it fixes reported issues and introduces a few minor improvements, such as using the ability to abort search paths scans and remembering MAP File and Search Paths options between executions. You can find the complete list in the changelog.

In other news v1.7 of SamplingProfiler should be ready “soon”. It fixes a bug that could drastically reduce the profiled application’s execution speed (when using MAP file information), and will introduce a “Real Time Monitor”, which allows to see what a profiled application is doing in real-time (unsurprisingly).
The monitor is actually a simple web server embedded into the profiler, so you can monitor an application that is run locally or on another machine. Real-time data will be accessible both as a bare-bones HTML page, or in XML form for the AJAX freaks out there.

News , , , , , ,