clang specific define in Runtime.cc
[deliverable/titan.core.git] / core / Debugger.hh
1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 *
10 * Baranyi, Botond – initial implementation
11 *
12 ******************************************************************************/
13
14 #ifndef DEBUGGER_HH
15 #define DEBUGGER_HH
16
17 #include "Vector.hh"
18 #include "Basetype.hh"
19 #include "Charstring.hh"
20 #ifdef TITAN_RUNTIME_2
21 #include "RT2/PreGenRecordOf.hh"
22 #else
23 #include "RT1/PreGenRecordOf.hh"
24 #endif
25 #include <regex.h>
26
27 /** alias for record of charstring */
28 typedef PreGenRecordOf::PREGEN__RECORD__OF__CHARSTRING charstring_list;
29
30 // forward declarations
31 class TTCN3_Debug_Scope;
32 class TTCN3_Debug_Function;
33
34
35 //////////////////////////////////////////////////////
36 ////////////////// TTCN3_Debugger ////////////////////
37 //////////////////////////////////////////////////////
38
39 /** main debugger class
40 *
41 * instantiated once per process at the beginning of the current process,
42 * destroyed at the end of the current process */
43 class TTCN3_Debugger {
44 public:
45
46 /** type for keeping track of a variable */
47 struct variable_t {
48 /** pointer to the variable object, not owned */
49 const void* value;
50 /** variable name (used for looking up variables), not owned */
51 const char* name;
52 /** name of the variable's type, not owned */
53 const char* type_name;
54 /** variable printing function (using the variable object's log() function) */
55 CHARSTRING (*print_function)(const variable_t&);
56 };
57
58 /** this type pairs a debug scope with a name, used for storing global and
59 * component scopes */
60 struct named_scope_t {
61 /** scope name (module name for global scopes, or component type name for
62 * component scopes), not owned */
63 const char* name;
64 /** scope pointer, owned */
65 TTCN3_Debug_Scope* scope;
66 };
67
68 /** type for storing breakpoints */
69 struct breakpoint_t {
70 /** module name, owned */
71 char* module;
72 /** line number */
73 int line;
74 // const char* batch_file;
75 };
76
77 /** special breakpoint types, passed to breakpoint_entry() as the line parameter,
78 * so these need to be 0 or negative, to never conflict with any line number */
79 enum special_breakpoint_t {
80 /** triggered when the local verdict is set to ERROR (by dynamic test case errors) */
81 SBP_ERROR_VERDICT = 0,
82 /** triggered when the local verdict is set to FAIL (by the user) */
83 SBP_FAIL_VERDICT = -1
84 };
85
86 private:
87
88 /** indicates whether the debugger has been activated, meaning that the debugger's
89 * command line option (-n) was used during the build (switched automatically
90 * by generated code) */
91 bool enabled;
92
93 /** the debugger's on/off switch (switched by the user) */
94 bool active;
95
96 /** true if test execution has been halted (by a breakpoint or by the user) */
97 bool halted;
98
99 /** the debugger's output file handler (NULL if the debugger's output is only
100 * sent to the console) */
101 FILE* output_file;
102
103 /** name of the debugger's output file (NULL if the debugger's output is only
104 * sent to the console) */
105 char* output_file_name;
106
107 /** indicates whether the debugger's output should be sent to the console */
108 bool send_to_console;
109
110 /** list of all global and component variables, elements are owned */
111 Vector<variable_t*> variables;
112
113 /** list of global scopes */
114 Vector<named_scope_t> global_scopes;
115
116 /** list of component scopes */
117 Vector<named_scope_t> component_scopes;
118
119 /** pointers to debug function objects (resembling a call stack), elements are not owned
120 * the current function is always the last element in the array (the top element in the stack) */
121 Vector<TTCN3_Debug_Function*> call_stack;
122
123 /** list of breakpoints */
124 Vector<breakpoint_t> breakpoints;
125
126 /** string containing function call snapshots, owned */
127 char* snapshots;
128
129 /** stores the last line hit by breakpoint_entry() */
130 breakpoint_t last_breakpoint_entry;
131
132 /** current stack level (reset when test execution is halted or resumed) */
133 int stack_level;
134
135 /** behavior triggered by setting the local verdict to FAIL
136 * (a breakpoint is activated if set to true) */
137 bool fail_behavior;
138
139 /** behavior triggered by setting the local verdict to ERROR
140 * (a breakpoint is activated if set to true) */
141 bool error_behavior;
142
143 /** result of the last executed or currently executing command */
144 char* command_result;
145
146 //////////////////////////////////////////////////////
147 ///////////////// internal functions /////////////////
148 //////////////////////////////////////////////////////
149
150 /** switches the debugger on or off
151 * handles the D_SWITCH command */
152 void switch_state(const char* p_state_str);
153
154 /** adds a new breakpoint at the specified module and line
155 * handles the D_ADD_BREAKPOINT command */
156 void add_breakpoint(const char* p_module, int p_line /*const char* batch_file*/);
157
158 /** removes the breakpoint from the specified module/line, if it exists
159 * handles the D_REMOVE_BREAKPOINT command */
160 void remove_breakpoint(const char* p_module, int p_line);
161
162 /** sets the behavior of a special breakpoint type
163 * @param p_state_str "yes" turns the special breakpoint on (as if it was an
164 * actual breakpoint), "no" turns it off
165 * handles the D_SET_ERROR_BEHAVIOR and D_SET_FAIL_BEHAVIOR commands */
166 void set_special_breakpoint(special_breakpoint_t p_type, const char* p_state_str);
167
168 /** prints the current call stack
169 * handles the D_PRINT_CALL_STACK command */
170 void print_call_stack();
171
172 /** sets the current stack level to the specified value
173 * handles the D_SET_STACK_LEVEL command */
174 void set_stack_level(int new_level);
175
176 /** prints the specified variable
177 * handles (one parameter of) the D_PRINT_VARIABLE command */
178 void print_variable(const variable_t* p_var);
179
180 /** sets the debugger's output to the console and/or a text file
181 * handles the D_SET_OUTPUT command
182 * @param p_output_type "console", "file" or "both"
183 * @param p_file_name output file name or NULL */
184 void set_output(const char* p_output_type, const char* p_file_name);
185
186 /** halts test execution, processing only debug commands
187 * handles the D_HALT command */
188 void halt();
189
190 /** resumes the halted test execution
191 * handles the D_CONTINUE command */
192 void resume();
193
194 /** exits the current test or the execution of all tests
195 * handles the D_EXIT command */
196 void exit_(const char* p_what);
197
198 /** returns the index of the specified breakpoint, if found,
199 * otherwise returns breakpoints.size() */
200 size_t find_breakpoint(const char* p_module, int p_line) const;
201
202 /** returns the specified variable, if found, otherwise returns NULL */
203 TTCN3_Debugger::variable_t* find_variable(const void* p_value) const;
204
205 /** handles metacharacters in the specified file name skeleton
206 * @return final file name (must be freed by caller) */
207 static char* finalize_file_name(const char* p_file_name_skeleton);
208
209 public:
210 /** constructor - called once per process (at the beginning) */
211 TTCN3_Debugger();
212
213 /** destructor - called once per process (at the end) */
214 ~TTCN3_Debugger();
215
216 //////////////////////////////////////////////////////
217 ////// methods called from TITAN generated code //////
218 //////////////////////////////////////////////////////
219
220 /** activates the debugger */
221 void activate() { enabled = true; }
222
223 /** creates, stores and returns a new global scope for the specified module
224 * (this scope contains all global variables visible in the module) */
225 TTCN3_Debug_Scope* add_global_scope(const char* p_module);
226
227 /** creates, stores and returns a new component scope for the specified component
228 * type (this scope contains all variables declared in the component type) */
229 TTCN3_Debug_Scope* add_component_scope(const char* p_component);
230
231 /** stores the string representation of the current function's return value
232 * (only if the debugger is switched on) */
233 void set_return_value(const CHARSTRING& p_value);
234
235 /** activates a breakpoint if the specified line and the current function's module
236 * match any of the breakpoints stored in the debugger
237 * the special parameter values (SBP_ERROR_VERDICT and SBP_FAIL_VERDICT) only
238 * trigger a breakpoint if their respective behaviors have been set to do so
239 * (does nothing if the debugger is switched off) */
240 void breakpoint_entry(int p_line /*bool p_stepping_helper*/);
241
242 /** variable printing function for base types */
243 static CHARSTRING print_base_var(const variable_t& p_var);
244
245 /** variable printing function for value arrays */
246 template <typename T_type, unsigned int array_size, int index_offset>
247 static CHARSTRING print_value_array(const variable_t& p_var)
248 {
249 TTCN_Logger::begin_event_log2str();
250 ((VALUE_ARRAY<T_type, array_size, index_offset>*)p_var.value)->log();
251 return TTCN_Logger::end_event_log2str();
252 }
253
254 /** variable printing function for template arrays */
255 template <typename T_value_type, typename T_template_type,
256 unsigned int array_size, int index_offset>
257 static CHARSTRING print_template_array(const variable_t& p_var)
258 {
259 TTCN_Logger::begin_event_log2str();
260 ((TEMPLATE_ARRAY<T_value_type, T_template_type, array_size,
261 index_offset>*)p_var.value)->log();
262 return TTCN_Logger::end_event_log2str();
263 }
264
265 /** variable printing function for port arrays */
266 template <typename T_type, unsigned int array_size, int index_offset>
267 static CHARSTRING print_port_array(const variable_t& p_var)
268 {
269 TTCN_Logger::begin_event_log2str();
270 ((PORT_ARRAY<T_type, array_size, index_offset>*)p_var.value)->log();
271 return TTCN_Logger::end_event_log2str();
272 }
273
274 /** variable printing function for timer arrays */
275 template <typename T_type, unsigned int array_size, int index_offset>
276 static CHARSTRING print_timer_array(const variable_t& p_var)
277 {
278 TTCN_Logger::begin_event_log2str();
279 ((TIMER_ARRAY<T_type, array_size, index_offset>*)p_var.value)->log();
280 return TTCN_Logger::end_event_log2str();
281 }
282
283 /** variable printing function for lazy parameters */
284 template <typename EXPR_TYPE>
285 static CHARSTRING print_lazy_param(const variable_t& p_var)
286 {
287 TTCN_Logger::begin_event_log2str();
288 ((Lazy_Param<EXPR_TYPE>*)p_var.value)->log();
289 return TTCN_Logger::end_event_log2str();
290 }
291
292 //////////////////////////////////////////////////////
293 ////// methods called by other debugger classes //////
294 //////////////////////////////////////////////////////
295
296 /** returns true if the debugger is activated (through the compiler switch) */
297 bool is_activated() const { return enabled; }
298
299 /** returns true if the debugger is switched on */
300 bool is_on() const { return active; }
301
302 /** returns true if test execution has been halted by the debugger */
303 bool is_halted() const { return halted; }
304
305 /** prints the formatted string to the console and/or output file
306 * (used for printing notifications or error messages) */
307 void print(int return_type, const char* fmt, ...) const;
308
309 /** adds the formatted string to the currently executed command's result string */
310 void add_to_result(const char* fmt, ...);
311
312 /** adds the specified function object pointer to the call stack
313 * (only if the debugger is switched on) */
314 void add_function(TTCN3_Debug_Function* p_function);
315
316 /** adds the specified scope object pointer to the current function's scope list
317 * (only if the debugger is switched on and the call stack is not empty) */
318 void add_scope(TTCN3_Debug_Scope* p_scope);
319
320 /** removes the specified function object pointer from the call stack, if it is
321 * the function at the top of the stack */
322 void remove_function(TTCN3_Debug_Function* p_function);
323
324 /** removes the specified scope object pointer from the current function's scope list
325 * (only if the call stack is not empty) */
326 void remove_scope(TTCN3_Debug_Scope* p_scope);
327
328 /** finds or creates, and returns the variable entry specified by the parameters
329 *
330 * if the call stack is empty, an entry for a global or component variable is
331 * created and stored in the main debugger object (if it doesn't already exist);
332 * if the call stack is not empty (and if the debugger is switched on), the
333 * variable entry for a local variable is created and stored by the current function */
334 const variable_t* add_variable(const void* p_value, const char* p_name, const char* p_type,
335 CHARSTRING (*p_print_function)(const variable_t&));
336
337 /** removes the variable entry for the specified local variable in the current
338 * function (only if the call stack is not empty) */
339 void remove_variable(const variable_t* p_var);
340
341 /** returns the global scope object associated with the specified module */
342 const TTCN3_Debug_Scope* get_global_scope(const char* p_module) const;
343
344 /** returns the component scope object associated with the specified component type */
345 const TTCN3_Debug_Scope* get_component_scope(const char* p_component) const;
346
347 /** appends the specified function call snapshot to the end of the snapshot string */
348 void add_snapshot(const char* p_snapshot);
349
350 /** executes a command received from the user interface */
351 void execute_command(int p_command, int p_argument_count, char** p_arguments);
352
353 /** opens the debugger's output file for writing (if one has been set, but not
354 * opened, in the HC process) */
355 void open_output_file();
356 };
357
358 /** the main debugger object */
359 extern TTCN3_Debugger ttcn3_debugger;
360
361
362 //////////////////////////////////////////////////////
363 //////////////// TTCN3_Debug_Scope ///////////////////
364 //////////////////////////////////////////////////////
365
366 /** debugger scope class
367 *
368 * instantiated at the beginning of every code block in the TTCN-3 code (except
369 * for the code blocks of functions), plus one (global scope) instance is created
370 * for every module and one (component scope) for every component type
371 *
372 * the class' main purpose is to track which local variables were created in the
373 * current code block or to track which of the main debugger object's variables
374 * belong to which global or component scope */
375 class TTCN3_Debug_Scope {
376
377 /** list of pointers to local variable entries from the current function object or
378 * global or component variable entries from the main debugger object
379 * (the elements are not owned)*/
380 Vector<const TTCN3_Debugger::variable_t*> variables;
381
382 public:
383
384 /** constructor - lets the current function know of this new scope */
385 TTCN3_Debug_Scope();
386
387 /** destructor - tells the current function to delete the variable entries listed
388 * in this instance */
389 ~TTCN3_Debug_Scope();
390
391 //////////////////////////////////////////////////////
392 ////// methods called from TITAN generated code //////
393 //////////////////////////////////////////////////////
394
395 /** passes the parameters to the main debugger or current function object to
396 * create and store a variable entry from them, and tracks this new variable
397 * by storing a pointer to it
398 * (local variables are only created and stored if the debugger is switched on) */
399 void add_variable(const void* p_value, const char* p_name, const char* p_type,
400 CHARSTRING (*p_print_function)(const TTCN3_Debugger::variable_t&));
401
402 //////////////////////////////////////////////////////
403 ////// methods called by other debugger classes //////
404 //////////////////////////////////////////////////////
405
406 /** returns true if there is at least one variable in the scope object */
407 bool has_variables() const { return !variables.empty(); }
408
409 /** returns the specified variable, if found, otherwise returns NULL */
410 const TTCN3_Debugger::variable_t* find_variable(const char* p_name) const;
411
412 /** prints the names of variables in this scope that match the specified
413 * @param p_posix_regexp the pattern converted into a POSIX regex structure
414 * @param p_first true if no variables have been printed yet */
415 void list_variables(regex_t* p_posix_regexp, bool& p_first) const;
416 };
417
418
419 //////////////////////////////////////////////////////
420 /////////////// TTCN3_Debug_Function /////////////////
421 //////////////////////////////////////////////////////
422
423 /** debugger function class
424 *
425 * instantiated at the beginning of every function, destroyed when function execution ends
426 *
427 * tracks all variables created during the function's execution (local variables),
428 * including the function's parameters, and stores the function's return value */
429 class TTCN3_Debug_Function {
430
431 /** name of the function, not owned */
432 const char* function_name;
433
434 /** the TTCN-3 keyword(s) used to define the function ("function", "testcase",
435 * "altstep", "template" or "external function"), not owned */
436 const char* function_type;
437
438 /** name of the module this function is defined in, not owned */
439 const char* module_name;
440
441 /** names of the function's parameters (in the order of their declaration), owned */
442 charstring_list* parameter_names;
443
444 /** types (directions) of the function's parameters ("in", "inout" or "out"), owned */
445 charstring_list* parameter_types;
446
447 /** list of local variables tracked by this object, the array elements are owned */
448 Vector<TTCN3_Debugger::variable_t*> variables;
449
450 /** list of pointers to the scope objects of code blocks in the function,
451 * the elements are not owned
452 * (currently not used for anything) */
453 Vector<TTCN3_Debug_Scope*> scopes;
454
455 /** pointer to the global scope object, not owned
456 * (may be NULL, if the module's global scope is empty) */
457 const TTCN3_Debug_Scope* global_scope;
458
459 /** pointer to the runs-on component's scope object, not owned
460 * (may be NULL, if the component's scope is empty or if the function has no runs-on clause) */
461 const TTCN3_Debug_Scope* component_scope;
462
463 /** the function's return value (unbound if the return value has not been set yet,
464 * or if the function doesn't return anything)
465 *
466 * since this is only set right before the function ends, it is only accessible
467 * from the destructor */
468 CHARSTRING return_value;
469
470 public:
471
472 /** constructor - initializes the instance with the specified parameters,
473 * retrieves the global scope and component scope from the main debugger object */
474 TTCN3_Debug_Function(const char* p_name, const char* p_type, const char* p_module,
475 const charstring_list& p_parameter_names, const charstring_list& p_parameter_types, const char* p_component_name);
476
477 /** destructor - frees resources and saves the function's ending snapshot
478 * (including the values of 'out' and 'inout' parameters and the return value)
479 * in the main debugger object (only if the debugger is switched on) */
480 ~TTCN3_Debug_Function();
481
482 //////////////////////////////////////////////////////
483 ////// methods called from TITAN generated code //////
484 //////////////////////////////////////////////////////
485
486 /** creates, stores and returns the variable entry of the local variable
487 * specified by the parameters (only if the debugger is switched on) */
488 const TTCN3_Debugger::variable_t* add_variable(const void* p_value, const char* p_name,
489 const char* p_type, CHARSTRING (*p_print_function)(const TTCN3_Debugger::variable_t&));
490
491 /** stores the string representation of the value returned by the function */
492 void set_return_value(const CHARSTRING& p_value);
493
494 /** saves the function's initial snapshot (including the values of 'in' and
495 * 'inout' parameters) in the main debugger object
496 * (only if the debugger is switched on) */
497 void initial_snapshot() const;
498
499 //////////////////////////////////////////////////////
500 ////// methods called by other debugger classes //////
501 //////////////////////////////////////////////////////
502
503 /** adds the specified scope object pointer to the function's scope list */
504 void add_scope(TTCN3_Debug_Scope* p_scope);
505
506 /** removes the specified scope object pointer from the function's scope list,
507 * if it is the last scope in the list */
508 void remove_scope(TTCN3_Debug_Scope* p_scope);
509
510 /** removes the specified variable from the variable list */
511 void remove_variable(const TTCN3_Debugger::variable_t* p_var);
512
513 /** searches for the variable entry with the specified name in the function's
514 * local variable list, the global scope (if any) and the component scope (if any),
515 * returns NULL, if the variable was not found */
516 const TTCN3_Debugger::variable_t* find_variable(const char* p_name) const;
517
518 /** prints the function's type, name and current values of parameters */
519 void print_function() const;
520
521 /** returns the name of the module the function was defined in */
522 const char* get_module_name() const { return module_name; }
523
524 /** prints the names of variables specified by the parameters (separated by spaces)
525 * handles the D_LIST_VARIABLES debugger command
526 * @param p_scope specifies which scope to print variables from:
527 * - "local" - the function's local variables (including variables in code blocks)
528 * - "global" - variables in the module's global scope
529 * - "comp" or "component" - variables in the function's runs-on component scope
530 * - "all" - all variables visible in the function (i.e. all of the above)
531 * @param p_filter a pattern to filter variable names further */
532 void list_variables(const char* p_scope, const char* p_filter) const;
533 };
534
535 /** This macro stores a function's return value in the current function.
536 * The returned value might be an expression, so it is copied to a temporary first,
537 * to avoid being evaluated twice. */
538 #define DEBUGGER_STORE_RETURN_VALUE(tmp, ret_val) \
539 (tmp = (ret_val), \
540 ttcn3_debugger.set_return_value((TTCN_Logger::begin_event_log2str(), \
541 tmp.log(), \
542 TTCN_Logger::end_event_log2str())), \
543 tmp)
544
545 #endif /* DEBUGGER_HH */
546
This page took 0.041073 seconds and 5 git commands to generate.