390 likes | 513 Views
Title of Presentation Mark Hammond Skippi-Net Australia. PDC Messages - How does your talk relate to these?. NT5: Empower your current app with Windows NT 5.0 to increase robustness and lower TCO Directory, Security, Management, Networking, Mobile, Multi Media
E N D
PDC Messages - How does your talk relate to these? • NT5: Empower your current app with Windows NT 5.0 to increase robustness and lower TCO • Directory, Security, Management, Networking, Mobile, Multi Media • DNA: Build N-Tier apps using Windows NT 5.0 as your application server • Presentation: DHTML+Script+Contrl, XML • Middle Tier: IIS, ASP, COM+, MSMQ • Data: ADO, OLE DB, ODBC, XML • NT5 Sys Services supporting the above
Active Debugging A study of a sample Active Scripting Language with Debugging support.
Talk Guidelines • Sample Code in external File - Large Fonts • \\starling\events\98pdc\sample_code\Session_Number\EmailName • Tell them what you will tell them • Tell them / show them with code & demos • Tell them what you told them • Tell them what they should DO! • Call To Action Slide at the end • How does it relate to the PDC Objectives?
Engage in the PDC • Create / Confirm your Talk Titles • Action Oriented, “Building, Using...” • Tie your talk into the PDC themes • Create / Confirm your Talk Abstracts • Sell your talk - what are the benefits? • Make the logistical arrangements • Hotel, travel, coaching, demo & release forms • Attend the Exec review with a finished talk • Submit your talk to \\ShowsRUS - ASAP • Participate in Ask the Experts / HOT
Killer Demo • Mixed language debugging demo. • Quite short - paying particular attention to the multiple languages in the call stack. • Particular attention to Forth - indicate this is what we are talking about (ie, we have the full sources!)
Overview • Part I • Introduction to the “ForthScript” sample. • Part II • Discuss key Active Debugging concepts. • Understand the implementation of these concepts in the ForthScript sample. • Part III • Discuss these concepts beyond the ForthScript sample.
What is ForthScript • A Sample Program which implements an Active Scripting language based heavily on “Forth”. • Written completely in C++ • Makes heavy use of ATL and STL. • Written specifically to be a sample • Readability always favoured over speed. • Structured to highlight AXScript and AXDebug support
So what is Forth? • A stack based, “reverse polish” language. • Similar to those HP calculators that don’t have an “=“ button • Eg, to add 2 numbers together in Forth: 2 2 + • The code above pushes “2” on the stack, pushes another “2” on the stack, and the “+” operator pops the top 2 items from the stack, and pushes the result.
Why Forth? • Very simple to implement • Interpreter wont get in the way of the Active Scripting and Debugging code. • Core Interpreter around 800 lines of C++ code. • No parser needed, as there are no complex expressions. • No need for this to be a “viable” language • This language does not attempt to be everything needed for real use.
Sample Code Structure • Main Directory contains the core Forth Interpreter. • No Active Scripting or Debugging knowledge. • Implemented as a family of COM objects. • AXscript directory contains Active Scripting support without Active Debugging. • AXdebug directory extends the Active Scripting implementation to be Active Debugging aware.
Active Scripting Support • Based heavily on the “axwrapper” Microsoft sample. • Much of this code will look familiar if you have seen this sample. • Crucially, a fully implemented language now comes with the sample! • Most of the “hard” code is handling events from the “named objects” provided by the Active Scripting host. • Not specific to this sample - just clone it!
Active Debugging Support • Completely new code • But I still attempted to keep the flavour of the Active Scripting support. • Nothing inherently difficult • Working out the relationships between all the objects is the hardest.
Concessions to Active Debugging • Changes made specifically because we were developing an Active Debugging Engine: • Uses COM from the ground up • Interpreter, “CodeBlock” (ie module), Token etc all have COM interfaces. • C++ virtuals were added that would not be necessary without Debugging • (eg, OnProcess[SourceCode]Block, On[SourceCode]BlockDone, etc)
Smart vs. Simple Hosts • Smart Hosts are Active Debugging aware • Know how to build a logical document model for the user. • Script Engines have a much easier time, as the host does much more work. • Simple Hosts are not Debugging aware • Language Engine takes up the slack, providing the necessary abstractions. • Life would be so much easier if all hosts where “smart”.
Initialization CodeSimple Hosts • Determine if the host is smart or simple • QI the ActiveScriptSite for ActiveScriptSiteDebug • Failure means simple host. • Simple Hosts require extra work • Create a default application object. • Create a debugger node. • Add source code blocks Xref: DForthScriptEngine.cpp, CDebuggableForthScriptEngine::AddToScript
Initialization Code (cont.)Smart Hosts • Smart Hosts • All work already done by the host. • We simply remember the IActiveScriptSiteDebug interface for later use. Xref: DForthScriptEngine.cpp, CDebuggableForthScriptEngine::AddToScript
Debug Documents(1 of 3) • A family of IDebugDocument* interfaces that abstract a debuggable document. • Split into multiple interfaces to allow separation of instantiation from content. • Smart Hosts provide most document interfaces, but delegate some back to the engine. This allows Smart Hosts to define document hierarchy. • Simple Hosts provide the lot. This means the document hierarchy may not be optimal.
Debug Documents(2 of 3) • Smart Hosts use a “context cookie” to map arbitrary source code blocks • DWORD dwSourceContextCookie is passed by the debugger with all code • Later this context is used to get a CodeContext object for the previously added code Xref: DForthScriptEngine.cpp, CDebuggableForthScriptEngine::EnumCodeContextsOfPosition
Debug Documents(3 of 3) • Simple Hosts use their document interface • As the simple host provides all IDebugDocument* interfaces, CodeContext interfaces are provided directly. Xref: DebugSourceCodeBlock.cpp, CDebuggableSourceCodeBlock::EnumCodeContextsOfPosition
IDebugDocumentContext(1 of 2) • Conceptually a “range of text” in the debuggable document. • Normally not an arbitary range - one statement. • The debugger passes a character range, and is returned a DebugDocumentContext • Debugger passes the complete range of the text currently selected in the debugger. • Engine can choose to only use the portion it needs.
IDebugDocumentContext(2 of 2) • Engine should return the first debug document context in the selection • Debugger will then query the DebugDocumentContext for its real size, to obtain the correct size. Xref: DebugSourceCodeBlock.cpp, DebuggableSourceCodeBlock::GetContextOfPosition • DebugDocumentContext then is queried for the DebugCodeContext objects it contains.
IDebugCodeContext(1 of 2) • The smallest debuggable unit in a program. • Typically one per DocumentContext • This is true for ForthScript • Notable exceptions would be “#include/#import” statements in C, etc. • Breakpoints and stepping etc all occur at this level.
IDebugCodeContext(2 of 2) • ForthScript implements both interfaces on the same object. • Implemented on my “Token” object, as this is the executable item in ForthScript. Xref: DebugToken.h, DebugToken.cpp • BEGIN_COM_MAP(CDebugToken) COM_INTERFACE_ENTRY(IDebugDocumentContext) COM_INTERFACE_ENTRY(IDebugCodeContext) … • Again, note IDebugDocumentContext only provided for Simple Hosts.
BreakPointsBehind the scenes of a breakpoint • IDebugDocumentInfo::GetContextOfPosition provides a DebugDocumentContext. • IDebugDocumentContext::EnumCodeContexts returns a list of ICodeContexts • Typically exactly one IDebugCodeContext objects • ICodeContext::SetBreakpoint called for the CodeContexts. • Code runs as normal
Breakpoints(cont.) • Engine itself must detect the break-point being hit. • Engine calls back IDebugApplication::HandleBreakPoint • Debugger interacts with user, and returns the “resume action” (eg, “step in”, “step over” • Engine honours “resume action”, and if necessary repeats the above. • Eg, if “step-into”, Engine calls HandleBreakPoint again at next opportunity
StackFrameDescriptor • StackFrameDescriptor is a simple C structure • Engine provides an enumerator for them. • Only called when an engine (not necessarily this engine) is at a breakpoint. • Provides: • IDebugStackFrame object. • Physical address of the stack frame - used for sorting stack entries. • Generic IUnknown to help with reference count management.
IDebugStackFrame(1 of 2) • Encapsulates engine state at one stack frame. Provides: • Name of the language being debugged • Typically static - eg, “ForthScript” • The IDebugApplicationThread • Previously provided by the Host, so only requires remembering it
IDebugStackFrame(2 of 2) • Stack frames provide (cont.) • The IDebugCodeContext for the stack frame • As described in previous slides. • Asynchronous Expression Evaluation interfaces • Only IDebugExpression provided by Forth. Xref: DebugStackFrame.cpp, DebugStackFrame.h
IDebugExpression(1 of 2) • Used to parse and execute arbitrary code • ie, code entered in the “Command Window” while at a breakpoint. • Should understand the context at the stack frame - eg, local and global variables. • Forth has no concept of locals or globals, so this is quite trivial. Xref:DebugExpression.cpp, DebugExpression.h • Provided by the IDebugStackFrame.
IDebugExpression(2 of 2) • Interface assumes asynch evaluation • Allows debugger to remain responsive during expensive evaluations • ForthScript only supports synchronous, making for a trivial implementation. • Allows for result to be returned as a string, or an IDebugProperty interface. • IDebugProperty allows for much richer representation of results - eg, arrays or structures. • ForthScript only supports strings
Walkthough of a debug session • Host requests the language “ForthScript” by issuing a CoCreateInstance(CLSID_ForthScript); • Engine fires up as a normal COM object. (COleScript.cpp, DOleScript.cpp) • Host calls SetScriptSite(IActiveScriptSite) to let the engine know about its context • Engine does a QI(IID_IActiveScriptSiteDebug ) on the provided site. • (more…)
END OF TALK • What follows are additional slides which may assist you when perusing the ForthScript sample.
IDebugDocumentInfo objects • The “entry point” for static details about the code. • Provides the name, filename, URL, size, etc. • Maps between character offsets and line numbers • Debugger remembers and assumes nothing! • Maps between a range of text, and DebugDocumentContext objects.