00001 /* 00002 * Copyright 2006-2008 The FLWOR Foundation. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #ifndef ZORBA_DEBUGGER_CLIENT_H 00017 #define ZORBA_DEBUGGER_CLIENT_H 00018 00019 #include <map> 00020 #include <list> 00021 #include <vector> 00022 00023 #include <zorba/api_shared_types.h> 00024 #include <zorba/debugger_event_handler.h> 00025 #include <zorba/query_location.h> 00026 00027 namespace zorba { 00028 00029 /** 00030 * Representation of the runtime stack frame. 00031 */ 00032 class ZORBA_DLL_PUBLIC StackFrame 00033 { 00034 public: 00035 00036 virtual 00037 ~StackFrame() {} 00038 00039 virtual const std::string& 00040 getSignature() const = 0; 00041 00042 virtual const QueryLocation& 00043 getLocation() const = 0; 00044 }; 00045 00046 //string serialization of the query 00047 ZORBA_DLL_PUBLIC 00048 std::ostream& operator<< (std::ostream& os, const QueryLocation& aQuery); 00049 ZORBA_DLL_PUBLIC 00050 std::ostream& operator<< (std::ostream& os, const QueryLocation* aQuery); 00051 00052 /** 00053 * @brief A DBGP client implementation for commands. 00054 * 00055 * This is the client implementation for sending commands 00056 * according to the specification of DBGP. DBGP is used as 00057 * the default communication format in the Zorba debugger. 00058 */ 00059 class ZORBA_DLL_PUBLIC DebuggerClient { 00060 public: 00061 /** 00062 * @brief creates a new instance of a DebuggerClient implementation. 00063 * 00064 * @param aHandler The event handler, where answered should get delivered to. 00065 * @param aPort The port the client should listen to. 00066 * @param aHost the host the client should listen to 00067 * @return A DebuggerClient implementation. 00068 */ 00069 static DebuggerClient* createDebuggerClient(DebuggerEventHandler* aHandler, 00070 unsigned short aPort, 00071 const std::string& aHost); 00072 public: 00073 virtual ~DebuggerClient(); 00074 public: // Types 00075 typedef enum { 00076 Line, 00077 Call, 00078 Return, 00079 Exception, 00080 Conditional, 00081 Watch 00082 } BreakpointType; 00083 typedef enum { 00084 BiggerEqual, 00085 Equal, 00086 Multiple 00087 } HitCondition; 00088 typedef enum { 00089 Stdout, 00090 Stderr, 00091 Stdin 00092 } OutputStream; 00093 typedef enum { 00094 Disable, 00095 CopyData, 00096 Redirection 00097 } StreamBehaviour; 00098 public: // API 00099 /** 00100 * @brief Waits for a debug engine to attach. 00101 * 00102 * This method blocks until a debug engine attaches and sends the 00103 * init message. After that process, the appropriate method in the 00104 * DebugHandler gets called. 00105 */ 00106 virtual void accept() = 0; 00107 00108 /** 00109 * The status command is a simple way for the IDE to find out from 00110 * the debugger engine whether execution may be continued or not. no 00111 * body is required on request. If async support has been negotiated 00112 * using feature_get/set the status command may be sent while the 00113 * debugger engine is in a 'run state'. 00114 * 00115 * The status attribute values of the response may be: 00116 * 00117 * <ul> 00118 * <li> 00119 * starting: 00120 * State prior to execution of any code 00121 * </li> 00122 * <li> 00123 * stopping: 00124 * State after completion of code execution. 00125 * This typically happens at the end of code execution, allowing 00126 * the IDE to further interact with the debugger engine (for example, 00127 * to collect performance data, or use other extended commands). 00128 * </li> 00129 * <li> 00130 * stopped: 00131 * IDE is detached from process, no further interaction is possible. 00132 * </li> 00133 * <li> 00134 * running: 00135 * code is currently executing. Note that this state would only be 00136 * seen with async support turned on, otherwise the typical state during 00137 * IDE/debugger interaction would be 'break' 00138 * </li> 00139 * <li> 00140 * break: 00141 * code execution is paused, for whatever reason (see below), and the 00142 * IDE/debugger can pass information back and forth. 00143 * </li> 00144 * </ul> 00145 * The reason attribute value may be: 00146 * 00147 * <ul> 00148 * <li> 00149 * ok 00150 * </li> 00151 * <li> 00152 * error 00153 * </li> 00154 * <li> 00155 * aborted 00156 * </li> 00157 * <li> 00158 * exception 00159 * </li> 00160 * </ul> 00161 * 00162 * @return The id of the request. 00163 */ 00164 virtual std::size_t status() = 0; 00165 00166 /** 00167 * @brief Get the variables in all the contexts in the topmost stack frame. 00168 * 00169 * @return The id of the request. 00170 */ 00171 virtual std::size_t variables() = 0; 00172 00173 /** 00174 * @brief Query the debug engine for supported features. 00175 * 00176 * @param aFeatureName The name of the feature to query for. values that must be 00177 * supported by the debug engine are: 00178 * <ul> 00179 * <li> 00180 * language_supports_threads 00181 * </li> 00182 * <li> 00183 * language_name 00184 * </li> 00185 * <li> 00186 * language_version 00187 * </li> 00188 * <li> 00189 * encoding 00190 * </li> 00191 * <li> 00192 * protocol_version 00193 * </li> 00194 * <li> 00195 * supports_async 00196 * </li> 00197 * <li> 00198 * data_encoding 00199 * </li> 00200 * <li> 00201 * breakpoint_languages 00202 * </li> 00203 * <li> 00204 * breakpoint_types 00205 * </li> 00206 * </ul> 00207 * @return The id of this request 00208 */ 00209 virtual std::size_t feature_get(const std::string& aFeatureName) = 0; 00210 00211 /** 00212 * @brief Set a specific feature of the engine. 00213 * 00214 * @param aFeatureName The name of the feature to query for. Values 00215 * that must be supported by the debug engine are: 00216 * <ul> 00217 * <li> 00218 * encoding 00219 * </li> 00220 * <li> 00221 * multiple_sessions 00222 * </li> 00223 * <li> 00224 * max_children 00225 * </li> 00226 * <li> 00227 * max_children 00228 * </li> 00229 * <li> 00230 * max_depth 00231 * </li> 00232 * </ul> 00233 * @param aValue The value of the feature 00234 * @return The id of this request 00235 */ 00236 virtual std::size_t feature_set(const std::string& aFeatureName, 00237 const std::string& aValue) = 0; 00238 00239 /** 00240 * @brief Send the run command to the debug engine. 00241 * 00242 * Sending this command to the debug engine makes the debug engine 00243 * to start if possible. Otherwise it must report an error. 00244 * 00245 * @return The id of this request 00246 */ 00247 virtual std::size_t run() = 0; 00248 00249 /** 00250 * @brief Send the step into command to the debug engine. 00251 * 00252 * @return The id of this request 00253 */ 00254 virtual std::size_t step_into() = 0; 00255 00256 /** 00257 * @brief Send the step out command to the debug engine. 00258 * 00259 * @return The id of this request 00260 */ 00261 virtual std::size_t step_out() = 0; 00262 00263 /** 00264 * @brief Send the step over command to the debug engine. 00265 * 00266 * @return The id of this request 00267 */ 00268 virtual std::size_t step_over() = 0; 00269 00270 /** 00271 * @brief Send the stop command to the debug engine. 00272 * 00273 * This command tells the debug engine, that it should 00274 * break the execution at the next point possible. 00275 * 00276 * @param withQuit This is a Zorba extension of the DBGP protocol that 00277 * controls if the client should terminate execution and quit (true) 00278 * or only terminate execution but not quit (false). This is used 00279 * by command line clients that implement multiple query runs. 00280 * @return The id of this request 00281 */ 00282 virtual std::size_t stop(bool withQuit) = 0; 00283 00284 /** 00285 * @brief Send the detach command to the debug engine. 00286 * 00287 * @return The id of this request 00288 */ 00289 virtual std::size_t detach() = 0; 00290 00291 /** 00292 * @brief Send a command to the debug engine to set a new breakpoint. 00293 * 00294 * @param aType The type of the breakpoint (line, call, return etc.). 00295 * @param aEnabled Should the breakpoint be enabled? 00296 * @param aLinenumber The line number where to set the breakpoint. 00297 * @param aFilename The file where a breakpoint should be set. 00298 * @param aFunctionName The name of the function where to break (only 00299 * to be used if aType == Call || aType == Return) 00300 * @param aExceptionName The name of the exception to break (only to be used 00301 * if aType == Exception) 00302 * @param hit_value A numeric value used together with the hit_condition 00303 * to determine if the breakpoint should pause execution 00304 * or be skipped. 00305 * @param aCondition The condition used together with 'hit_value' (default 00306 * is '>=') 00307 * @param aIsTemporary Flag to define if breakpoint is temporary. A 00308 * temporary breakpoint is one that is deleted after 00309 * its first use. This is useful for features like "Run 00310 * to Cursor". Once the debugger engine uses a temporary 00311 * breakpoint, it should automatically remove the 00312 * breakpoint from it's list of valid breakpoints. 00313 * @param aExpression code expression, in the language of the debugger engine. 00314 * The breakpoint should activate when the evaluated code 00315 * evaluates to true. (required for conditional breakpoint 00316 * types) 00317 * @return The id of this request 00318 */ 00319 virtual std::size_t breakpoint_set(BreakpointType aType, 00320 bool aEnabled = true, 00321 const std::string& aFilename = "", 00322 int aLinenumber = -1, 00323 const std::string& aFunctionName = "", 00324 const std::string& aExceptionName = "", 00325 unsigned hit_value = 0, 00326 HitCondition aCondition = BiggerEqual, 00327 bool aIsTemporary = false, 00328 const std::string& aExpression = "") = 0; 00329 00330 /** 00331 * @brief Get information about a breakpoint. 00332 * 00333 * @param aBreakpointId The id of the breakpoint. 00334 * @return The id of this request 00335 */ 00336 virtual std::size_t breakpoint_get(std::size_t aBreakpointId) = 0; 00337 00338 /** 00339 * @brief Send a command to the debug engine to update a breakpoint. 00340 * 00341 * @param aBreakpointId The id of the breakpoint. 00342 * @param aEnabled Should the breakpoint be enabled? 00343 * @param aLinenumber The line number where to set the breakpoint. 00344 * @param hit_value A numeric value used together with the hit_condition 00345 * to determine if the breakpoint should pause execution 00346 * or be skipped. 00347 * @param aCondition The condition used together with 'hit_value' (default 00348 * is '>=') 00349 * @return The id of this request 00350 */ 00351 virtual std::size_t breakpoint_update(std::size_t aBreakpointId, 00352 bool aEnabled = true, 00353 int aLinenumber = -1, 00354 unsigned hit_value = 0, 00355 HitCondition aCondition = BiggerEqual) = 0; 00356 00357 /** 00358 * @brief Remove a breakpoint. 00359 * 00360 * @param aBreakpointId The id of the breakpoint. 00361 * @return The id of this request 00362 */ 00363 virtual std::size_t breakpoint_remove(std::size_t aBreakpointId) = 0; 00364 00365 /** 00366 * @brief Query all breakpoints. 00367 * 00368 * @return The id of this request 00369 */ 00370 virtual std::size_t breakpoint_list() = 0; 00371 00372 /** 00373 * @brief Get the depth of the stack. 00374 * 00375 * @return The id of this request 00376 */ 00377 virtual std::size_t stack_depth() = 0; 00378 00379 /** 00380 * @brief Get information about the stack at a given depth. 00381 * 00382 * @param depth The depth on which to quey (optional) 00383 * @return The id of this request 00384 */ 00385 virtual std::size_t stack_get(int depth = -1) = 0; 00386 00387 /** 00388 * @brief Get the context names at a given stack depth. 00389 * 00390 * The context names are the names in which variables are 00391 * (like global, local etc.). 00392 * 00393 * @param depth The depth on which to quey (optional) 00394 * @return The id of this request 00395 */ 00396 virtual std::size_t context_names(int depth = -1) = 0; 00397 00398 /** 00399 * @brief Get the context at a given stack depth. 00400 * 00401 * Returns an array of properties in a given context at a given 00402 * stack depth. If the stack depth is omitted, the current stack 00403 * depth is used. If the context name is omitted, the context 00404 * with an id zero is used (generally the 'locals' context). 00405 * 00406 * @param depth The depth on which to quey (optional) 00407 * @param contextId The contextId (optional) 00408 * @return The id of this request 00409 */ 00410 virtual std::size_t context_get(int depth = -1, int contextId = -1) = 0; 00411 00412 /** 00413 * @brief Get a mapping of types. 00414 * 00415 * The IDE calls this command to get information on how to map 00416 * language specific type names (as received in the property 00417 * element returned by the context_get, and property_* commands). 00418 * The debugger engine returns all data types that it supports. There 00419 * may be multiple map elements with the same type attribute value, 00420 * but the name value must be unique. This allows a language to map 00421 * multiple language specific types into one of the common data types 00422 * (eg. float and double can both be mapped to float). 00423 * 00424 * @return The id of this request 00425 */ 00426 virtual std::size_t typemap_get() = 0; 00427 00428 /** 00429 * @brief Get a property 00430 * 00431 * @param aPropertyLongName roperty long name (required) 00432 * @param aStackDepth stack depth (optional) 00433 * @param aContextId The context id for which to query. 00434 * @param aMaxDataSize The maximal size of the data sent back 00435 * from the debug engine. 00436 * @param aDatapage 00437 * @param aPropertyKey 00438 * @return The id of this request 00439 */ 00440 virtual std::size_t property_get(const std::string& aPropertyLongName, 00441 int aStackDepth = -1, 00442 int aContextId = -1, 00443 std::size_t aMaxDataSize = 0, 00444 int aDatapage = -1, 00445 const std::string& aPropertyKey = "") = 0; 00446 00447 /** 00448 * @brief Set a property 00449 * 00450 * @param aPropertyLongName roperty long name (required) 00451 * @param aStackDepth stack depth (optional) 00452 * @param aContextId The context id for which to query. 00453 * @param aMaxDataSize The maximal size of the data sent back 00454 * from the debug engine. 00455 * @param aPropertyAddress property address as retrieved in a 00456 * property element (optional). 00457 * @return The id of this request 00458 */ 00459 virtual std::size_t property_set(const std::string& aPropertyLongName, 00460 int aStackDepth = -1, 00461 int aContextId = -1, 00462 std::size_t aMaxDataSize = 0, 00463 const std::string& aPropertyAddress = "") = 0; 00464 00465 /** 00466 * @brief Get the value of a property 00467 * 00468 * @param aPropertyLongName roperty long name (required) 00469 * @param aStackDepth stack depth (optional) 00470 * @param aContextId The context id for which to query. 00471 * @param aMaxDataSize The maximal size of the data sent back 00472 * from the debug engine. 00473 * @param aDatapage 00474 * @param aPropertyKey property key as retrieved in a property 00475 * element (optional) 00476 * @param aPropertyAddress property address as retrieved in a 00477 * property element (optional). 00478 * @return The id of this request 00479 */ 00480 virtual std::size_t property_value(const std::string& aPropertyLongName, 00481 int aStackDepth = -1, 00482 int aContextId = -1, 00483 std::size_t aMaxDataSize = 0, 00484 int aDatapage = -1, 00485 const std::string& aPropertyKey = "", 00486 const std::string& aPropertyAddress = "") = 0; 00487 00488 /** 00489 * @brief List the source code at a given position. 00490 * 00491 * @param aFile The URI of the file the debug engine should deliver. 00492 * @param aBeginLine The starting point on which line the debug engine 00493 * should start to read. 00494 * @param aEndLine The line number where the debug engine should stop 00495 * reading from the file. 00496 * @return The id of this request. 00497 */ 00498 virtual std::size_t source(const std::string& aFile, unsigned aBeginLine = 0, unsigned aEndLine = 0) = 0; 00499 00500 /** 00501 * @brief Setting a stream option. 00502 * 00503 * This method is used to tell the debug engine how to handle I/O. The debug 00504 * engine either reads and writes from/to stdin/stdout or it can also copy it 00505 * to the client or it can read/write everything from the client. 00506 * 00507 * @param aStream Specifies for which stream the option should be changed. 00508 * @param aBehaviour Specifies which behaviour the debug client should have 00509 * for reading/writing. 00510 * @return The id of this request 00511 */ 00512 virtual std::size_t stream_option(OutputStream aStream, StreamBehaviour aBehaviour) = 0; 00513 00514 /** 00515 * @brief Tell the debug engine to stop execution as fast as possible. 00516 * 00517 * @return The id of this request 00518 */ 00519 virtual std::size_t do_break() = 0; 00520 00521 /** 00522 * @brief Evaluates an expression. 00523 * 00524 * @param aExpr The expression to evaluate. 00525 * @return The id of this request 00526 */ 00527 virtual std::size_t eval(const std::string& aExpr) = 0; 00528 00529 /** 00530 * @brief Tells the client to quit. This method blocks until the client quit 00531 * successfully. 00532 */ 00533 virtual void quit() = 0; 00534 }; 00535 00536 }//end of namespace 00537 00538 #endif