/usr/include/titan/Debugger.hh is in eclipse-titan 6.3.1-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | /******************************************************************************
* Copyright (c) 2000-2017 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*
* Baranyi, Botond – initial implementation
*
******************************************************************************/
#ifndef DEBUGGER_HH
#define DEBUGGER_HH
#include "Vector.hh"
#include "Basetype.hh"
#include "Charstring.hh"
#ifdef TITAN_RUNTIME_2
#include "RT2/PreGenRecordOf.hh"
#else
#include "RT1/PreGenRecordOf.hh"
#endif
#include <regex.h>
/** alias for record of charstring */
typedef PreGenRecordOf::PREGEN__RECORD__OF__CHARSTRING charstring_list;
// debugger forward declarations
class TTCN3_Debug_Scope;
class TTCN3_Debug_Function;
// other forward declarations
class Module_Param;
//////////////////////////////////////////////////////
////////////////// TTCN3_Debugger ////////////////////
//////////////////////////////////////////////////////
/** main debugger class
*
* instantiated once per process at the beginning of the current process,
* destroyed at the end of the current process */
class TTCN3_Debugger {
public:
struct variable_t;
typedef CHARSTRING (*print_function_t)(const variable_t&);
typedef boolean (*set_function_t)(variable_t&, Module_Param&);
/** type for keeping track of a variable */
struct variable_t {
/** pointer to the variable object, not owned */
union {
/** container for non-constant variable objects */
void* value;
/** container for constant variable objects */
const void* cvalue;
};
/** variable name (used for looking up variables), not owned */
const char* name;
/** name of the variable's type, not owned */
const char* type_name;
/** name of the module the variable was declared in (only set for global
* variables, otherwise NULL), not owned */
const char* module;
/** variable printing function (using the variable object's log() function) */
print_function_t print_function;
/** variable setting (overwriting) function (using the variable object's
* set_param() function) - set to NULL for constant variables */
set_function_t set_function;
};
/** this type pairs a debug scope with a name, used for storing global and
* component scopes */
struct named_scope_t {
/** scope name (module name for global scopes, or component type name for
* component scopes), not owned */
const char* name;
/** scope pointer, owned */
TTCN3_Debug_Scope* scope;
};
/** type for storing a function call in the call stack */
struct function_call_t {
/** pointer to the debug function object */
TTCN3_Debug_Function* function;
/** TTCN-3 line number, where the function was called from */
int caller_line;
};
/** type for storing breakpoints */
struct breakpoint_t {
/** module name, owned */
char* module;
/** line number (if it's a line breakpoint, otherwise 0) */
int line;
/** function name (if it's a function breakpoint, otherwise NULL), owned */
char* function;
/** batch file to be executed when the breakpoint is reached (optional), owned */
char* batch_file;
};
/** type for storing data related to a breakpoint entry */
struct breakpoint_entry_t {
/** module name, not owned */
const char* module;
/** line number */
int line;
/** size of the call stack */
size_t stack_size;
};
/** special breakpoint types, passed to breakpoint_entry() as the line parameter,
* so these need to be 0 or negative, to never conflict with any line number */
enum special_breakpoint_t {
/** triggered when the local verdict is set to ERROR (by dynamic test case errors) */
SBP_ERROR_VERDICT = 0,
/** triggered when the local verdict is set to FAIL (by the user) */
SBP_FAIL_VERDICT = -1
};
/** type for storing the settings of automatic breakpoints */
struct automatic_breakpoint_behavior_t {
/** indicates whether the breakpoint should be triggered by the associated event */
boolean trigger;
/** batch file to be executed if the breakpoint is triggered (optional), owned */
char* batch_file;
};
/** possible function call data handling configurations */
enum function_call_data_config_t {
/** function call data is printed directly to file and not stored by the
* debugger */
CALLS_TO_FILE,
/** function call data is stored in a ring buffer of a set size
* (i.e. when the buffer is full, adding a new function call automatically
* deletes the oldest function call)
* the buffer size can be zero, in which case no calls are stored */
CALLS_RING_BUFFER,
/** function call data is stored in a buffer of variable length (i.e. when
* the buffer is full, its size is increased) */
CALLS_STORE_ALL
};
/** structure containing the function call data and information related to
* their handling */
struct function_call_data_t {
/** current function call data configuration (this also indicates which
* field of the following union is selected) */
function_call_data_config_t cfg;
union {
/** information related to the file, that function calls are printed to
* (in case of CALLS_TO_FILE) */
struct {
/** name of the target file (may contain metacharacters), owned */
char* name;
/** the target file's handler, owned */
FILE* ptr;
} file;
/** information related to the storing of function calls
* (in case of CALLS_RING_BUFFER or CALLS_STORE_ALL) */
struct {
/** size of the buffer used for storing function calls (this value is
* fixed in case of CALLS_RING_BUFFER and dynamic in case of CALLS_STORE_ALL) */
int size;
/** stores the index of the first function call in the buffer
* (is always 0 in case of CALLS_STORE_ALL) */
int start;
/** stores the index of the last function call in the buffer
* (its value is -1 if no function calls are currently stored) */
int end;
/** buffer containing the function call data, owned */
char** ptr;
} buffer;
};
};
/** stepping type */
enum stepping_t {
NOT_STEPPING,
STEP_OVER,
STEP_INTO,
STEP_OUT
};
private:
/** indicates whether the debugger has been activated, meaning that the debugger's
* command line option (-n) was used during the build (switched automatically
* by generated code) */
boolean enabled;
/** the debugger's on/off switch (switched by the user) */
boolean active;
/** true if test execution has been halted (by a breakpoint or by the user) */
boolean halted;
/** the debugger's output file handler (NULL if the debugger's output is only
* sent to the console); owned */
FILE* output_file;
/** name of the debugger's output file (NULL if the debugger's output is only
* sent to the console); may contain metacharacters; owned */
char* output_file_name;
/** indicates whether the debugger's output should be sent to the console */
boolean send_to_console;
/** list of all global and component variables, elements are owned */
Vector<variable_t*> variables;
/** list of global scopes */
Vector<named_scope_t> global_scopes;
/** list of component scopes */
Vector<named_scope_t> component_scopes;
/** pointers to debug function objects and the lines they were called from
* (resembling a call stack), the current function is always the last element
* in the array (the top element in the stack) */
Vector<function_call_t> call_stack;
/** list of breakpoints */
Vector<breakpoint_t> breakpoints;
/** structure containing function call data */
function_call_data_t function_calls;
/** stores the last line hit by breakpoint_entry() */
breakpoint_entry_t last_breakpoint_entry;
/** current stack level (reset when test execution is halted or resumed) */
int stack_level;
/** automatic breakpoint triggered by setting the local verdict to FAIL */
automatic_breakpoint_behavior_t fail_behavior;
/** automatic breakpoint triggered by setting the local verdict to ERROR */
automatic_breakpoint_behavior_t error_behavior;
/** batch file executed automatically when test execution is halted
* NULL if switched off (owned)
* is overridden by breakpoint-specific batch files */
char* global_batch_file;
/** result of the currently executing command, owned */
char* command_result;
/** result of the last D_LIST_VARIABLES command, owned */
char* last_variable_list;
/** stores which stepping option was requested by the user (if any) */
stepping_t stepping_type;
/** stores the size of the call stack when the last stepping operation was
* initiated */
size_t stepping_stack_size;
/** temporary breakpoint set by the 'run to cursor' operation */
breakpoint_t temporary_breakpoint;
/** true if an 'exit all' command was issued
* switched to false when test execution is restarted */
boolean exiting;
/** test execution is automatically halted at start if set to true */
boolean halt_at_start;
/** batch file executed automatically at the start of test execution
* if not set to NULL (not owned) */
const char* initial_batch_file;
//////////////////////////////////////////////////////
///////////////// internal functions /////////////////
//////////////////////////////////////////////////////
/** switches the debugger on or off
* handles the D_SWITCH command */
void switch_state(const char* p_state_str);
/** adds a new breakpoint at the specified location (line or function) with the
* specified batch file (if not NULL), or changes the batch file of an existing
* breakpoint
* handles the D_SET_BREAKPOINT command */
void set_breakpoint(const char* p_module, const char* p_location,
const char* batch_file);
/** removes the breakpoint from the specified location, if it exists
* can also be used to remove all breakpoints from the specified module or
* all breakpoints in all modules
* handles the D_REMOVE_BREAKPOINT command */
void remove_breakpoint(const char* p_module, const char* p_location);
/** switches an automatic breakpoint related to the specified event on or off
* and/or sets the batch file to run when the breakpoint is triggered
* @param p_event_str string representation of the event that triggers the
* breakpoint (either "error" or "fail")
* @param p_state_str "on" or "off", indicates the new state of the breakpoint
* @param p_batch_file name of the batch file to execute (NULL means don't
* execute anything)
* handles the D_SET_AUTOMATIC_BREAKPOINT command */
void set_automatic_breakpoint(const char* p_event_str, const char* p_state_str,
const char* p_batch_file);
/** prints the debugger's settings
* handles the D_PRINT_SETTINGS command */
void print_settings();
/** prints the current call stack
* handles the D_PRINT_CALL_STACK command */
void print_call_stack();
/** sets the current stack level to the specified value
* handles the D_SET_STACK_LEVEL command */
void set_stack_level(int new_level);
/** finds the variable with the specified name, and prints its value or an
* error message
* the variable's value is printed using its log() function
* handles (one parameter of) the D_PRINT_VARIABLE command */
void print_variable(const char* p_var_name);
/** finds the variable with the specified name, and overwrites its value or
* displays an error message
* the new value is received in a string array; this is concatenated into one
* string (with one space separating each string element); then it is passed
* to the module parameter parser, which creates a Module_Param object from it
* (if its syntax is correct)
* the variable's value is overwritten by passing the Module_Param object to
* its set_param() function
* handles the D_OVERWRITE_VARIABLE command */
void overwrite_variable(const char* p_var_name, int p_value_element_count,
char** p_value_elements);
/** frees all resources related to the handling of function call data */
void clean_up_function_calls();
/** changes the method of handling function call data
* handles the D_FUNCTION_CALL_CONFIG command */
void configure_function_calls(const char* p_config, const char* p_file_name);
/** prints the last stored function calls
* handles the D_PRINT_FUNCTION_CALLS command
* @param p_amount amount of function calls to print or "all" */
void print_function_calls(const char* p_amount);
/** sets the debugger's output to the console and/or a text file
* handles the D_SET_OUTPUT command
* @param p_output_type "console", "file" or "both"
* @param p_file_name output file name or NULL */
void set_output(const char* p_output_type, const char* p_file_name);
/** switches the global batch file on or off
* handles the D_SET_GLOBAL_BATCH_FILE command */
void set_global_batch_file(const char* p_state_str, const char* p_file_name);
/** resumes execution until the next breakpoint entry (in the stack levels
* specified by the stepping type arguments) is reached (or until test execution
* is halted for any other reason)
* handles the D_STEP_OVER, D_STEP_INTO and D_STEP_OUT commands */
void step(stepping_t p_stepping_type);
/** resumes execution until the specified location (line or function) is reached
* (or until test execution is halted for any other reason)
* handles the D_RUN_TO_CURSOR command */
void run_to_cursor(const char* p_module, const char* p_location);
/** halts test execution, processing only debug commands
* @param p_batch_file batch file executed after the halt (if not NULL)
* @param p_run_global_batch indicates whether the global batch file should
* be executed after the halt (only if p_batch_file is NULL)
* handles the D_HALT command */
void halt(const char* p_batch_file, boolean p_run_global_batch);
/** resumes the halted test execution
* handles the D_CONTINUE command */
void resume();
/** exits the current test or the execution of all tests
* handles the D_EXIT command */
void exit_(const char* p_what);
/** returns the index of the specified breakpoint, if found,
* otherwise returns breakpoints.size() */
size_t find_breakpoint(const char* p_module, int p_line,
const char* p_function) const;
/** returns the specified variable, if found, otherwise returns NULL */
TTCN3_Debugger::variable_t* find_variable(const void* p_value) const;
/** handles metacharacters in the specified file name skeleton
* @return final file name (must be freed by caller) */
static char* finalize_file_name(const char* p_file_name_skeleton);
/** initialization function, called when the first function is added to the
* call stack */
void test_execution_started();
/** clean up function, called when the last function is removed from the
* call stack */
void test_execution_finished();
public:
/** constructor - called once per process (at the beginning) */
TTCN3_Debugger();
/** destructor - called once per process (at the end) */
~TTCN3_Debugger();
//////////////////////////////////////////////////////
////// methods called from TITAN generated code //////
//////////////////////////////////////////////////////
/** activates the debugger */
void activate() { enabled = TRUE; }
/** creates, stores and returns a new global scope for the specified module
* (this scope contains all global variables visible in the module) */
TTCN3_Debug_Scope* add_global_scope(const char* p_module);
/** creates, stores and returns a new component scope for the specified component
* type (this scope contains all variables declared in the component type) */
TTCN3_Debug_Scope* add_component_scope(const char* p_component);
/** stores the string representation of the current function's return value
* (only if the debugger is switched on) */
void set_return_value(const CHARSTRING& p_value);
/** activates a breakpoint if the specified line and the current function's module
* match any of the breakpoints stored in the debugger
* the special parameter values (SBP_ERROR_VERDICT and SBP_FAIL_VERDICT) only
* trigger a breakpoint if their respective behaviors have been set to do so
* (does nothing if the debugger is switched off) */
void breakpoint_entry(int p_line);
/** variable printing function for base types */
static CHARSTRING print_base_var(const variable_t& p_var);
/** variable setting function for base types */
static boolean set_base_var(variable_t& p_var, Module_Param& p_new_value);
/** variable printing function for value arrays */
template <typename T_type, unsigned int array_size, int index_offset>
static CHARSTRING print_value_array(const variable_t& p_var)
{
const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
TTCN_Logger::begin_event_log2str();
((VALUE_ARRAY<T_type, array_size, index_offset>*)ptr)->log();
return TTCN_Logger::end_event_log2str();
}
/** variable setting function for value arrays */
template <typename T_type, unsigned int array_size, int index_offset>
static boolean set_value_array(variable_t& p_var, Module_Param& p_new_value)
{
((VALUE_ARRAY<T_type, array_size, index_offset>*)p_var.value)->set_param(p_new_value);
return TRUE;
}
/** variable printing function for template arrays */
template <typename T_value_type, typename T_template_type,
unsigned int array_size, int index_offset>
static CHARSTRING print_template_array(const variable_t& p_var)
{
const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
TTCN_Logger::begin_event_log2str();
((TEMPLATE_ARRAY<T_value_type, T_template_type, array_size,
index_offset>*)ptr)->log();
return TTCN_Logger::end_event_log2str();
}
/** variable setting function for template arrays */
template <typename T_value_type, typename T_template_type,
unsigned int array_size, int index_offset>
static boolean set_template_array(variable_t& p_var, Module_Param& p_new_value)
{
((TEMPLATE_ARRAY<T_value_type, T_template_type, array_size,
index_offset>*)p_var.value)->set_param(p_new_value);
return TRUE;
}
/** variable printing function for port arrays */
template <typename T_type, unsigned int array_size, int index_offset>
static CHARSTRING print_port_array(const variable_t& p_var)
{
const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
TTCN_Logger::begin_event_log2str();
((PORT_ARRAY<T_type, array_size, index_offset>*)ptr)->log();
return TTCN_Logger::end_event_log2str();
}
/** variable printing function for timer arrays */
template <typename T_type, unsigned int array_size, int index_offset>
static CHARSTRING print_timer_array(const variable_t& p_var)
{
const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
TTCN_Logger::begin_event_log2str();
((TIMER_ARRAY<T_type, array_size, index_offset>*)ptr)->log();
return TTCN_Logger::end_event_log2str();
}
/** variable printing function for lazy parameters */
template <typename EXPR_TYPE>
static CHARSTRING print_lazy_param(const variable_t& p_var)
{
const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;
TTCN_Logger::begin_event_log2str();
((Lazy_Fuzzy_Expr<EXPR_TYPE>*)ptr)->log();
return TTCN_Logger::end_event_log2str();
}
static CHARSTRING print_fuzzy_param(const variable_t&)
{
return CHARSTRING("<fuzzy value>");
}
//////////////////////////////////////////////////////
////// methods called by other debugger classes //////
//////////////////////////////////////////////////////
/** returns true if the debugger is activated (through the compiler switch) */
boolean is_activated() const { return enabled; }
/** returns true if the debugger is switched on */
boolean is_on() const { return active; }
/** returns true if test execution has been halted by the debugger */
boolean is_halted() const { return halted; }
/** prints the formatted string to the console and/or output file
* (used for printing notifications or error messages) */
void print(int return_type, const char* fmt, ...) const;
/** adds the formatted string to the currently executed command's result string */
void add_to_result(const char* fmt, ...);
/** adds the specified function object pointer to the call stack
* (only if the debugger is switched on) */
void add_function(TTCN3_Debug_Function* p_function);
/** adds the specified scope object pointer to the current function's scope list
* (only if the debugger is switched on and the call stack is not empty) */
void add_scope(TTCN3_Debug_Scope* p_scope);
/** removes the specified function object pointer from the call stack, if it is
* the function at the top of the stack */
void remove_function(TTCN3_Debug_Function* p_function);
/** removes the specified scope object pointer from the current function's scope list
* (only if the call stack is not empty) */
void remove_scope(TTCN3_Debug_Scope* p_scope);
/** finds or creates, and returns the constant variable entry specified by
* the parameters
*
* if the call stack is empty, an entry for a global or component variable is
* created and stored in the main debugger object (if it doesn't already exist);
* if the call stack is not empty (and if the debugger is switched on), the
* variable entry for a local variable is created and stored by the current function */
variable_t* add_variable(const void* p_value, const char* p_name, const char* p_type,
const char* p_module, print_function_t p_print_function);
/** same as before, but for non-constant variables */
variable_t* add_variable(void* p_value, const char* p_name, const char* p_type,
const char* p_module, print_function_t p_print_function,
set_function_t p_set_function);
/** removes the variable entry for the specified local variable in the current
* function (only if the call stack is not empty) */
void remove_variable(const variable_t* p_var);
/** returns the global scope object associated with the specified module */
const TTCN3_Debug_Scope* get_global_scope(const char* p_module) const;
/** returns the component scope object associated with the specified component type */
const TTCN3_Debug_Scope* get_component_scope(const char* p_component) const;
/** stores the specified snapshot of a function call, together with a time stamp
* (the debugger is responsible for freeing the string parameter) */
void store_function_call(char* p_snapshot);
/** executes a command received from the user interface */
void execute_command(int p_command, int p_argument_count, char** p_arguments);
/** called when a PTC is forked from the HC process
* contains supplementary initializations (i.e. opening of file pointers and
* allocations of buffers) that the HC's debugger does not perform, but are
* needed by the PTC's debugger */
void init_PTC_settings();
/** indicates whether an 'exit all' command has been issued
* (this causes the execution of tests in the current queue to stop) */
boolean is_exiting() const { return exiting; }
/** sets the debugger to halt test execution at start (only in single mode) */
void set_halt_at_start() { halt_at_start = TRUE; }
/** sets the specified batch file to be executed at the start of test execution
* (only in single mode) */
void set_initial_batch_file(const char* p_batch_file) {
initial_batch_file = p_batch_file;
}
};
/** the main debugger object */
extern TTCN3_Debugger ttcn3_debugger;
//////////////////////////////////////////////////////
//////////////// TTCN3_Debug_Scope ///////////////////
//////////////////////////////////////////////////////
/** debugger scope class
*
* instantiated at the beginning of every code block in the TTCN-3 code (except
* for the code blocks of functions), plus one (global scope) instance is created
* for every module and one (component scope) for every component type
*
* the class' main purpose is to track which local variables were created in the
* current code block or to track which of the main debugger object's variables
* belong to which global or component scope */
class TTCN3_Debug_Scope {
/** list of pointers to local variable entries from the current function object or
* global or component variable entries from the main debugger object
* (the elements are not owned)*/
Vector<TTCN3_Debugger::variable_t*> variables;
public:
/** constructor - lets the current function know of this new scope */
TTCN3_Debug_Scope();
/** destructor - tells the current function to delete the variable entries listed
* in this instance */
~TTCN3_Debug_Scope();
//////////////////////////////////////////////////////
////// methods called from TITAN generated code //////
//////////////////////////////////////////////////////
/** passes the parameters to the main debugger or current function object to
* create and store a (constant) variable entry from them, and tracks this new
* variable by storing a pointer to it
* (local variables are only created and stored if the debugger is switched on) */
void add_variable(const void* p_value, const char* p_name, const char* p_type,
const char* p_module, TTCN3_Debugger::print_function_t p_print_function);
/** same as before, but for non-constant variables */
void add_variable(void* p_value, const char* p_name, const char* p_type,
const char* p_module, TTCN3_Debugger::print_function_t p_print_function,
TTCN3_Debugger::set_function_t p_set_function);
//////////////////////////////////////////////////////
////// methods called by other debugger classes //////
//////////////////////////////////////////////////////
/** returns true if there is at least one variable in the scope object */
boolean has_variables() const { return !variables.empty(); }
/** returns the specified variable, if found, otherwise returns NULL
* (the name searched for can also be prefixed with the module name in
* case of global variables) */
TTCN3_Debugger::variable_t* find_variable(const char* p_name) const;
/** prints the names of variables in this scope that match the specified;
* names of imported global variables are prefixed with their module's name
* @param p_posix_regexp the pattern converted into a POSIX regex structure
* @param p_first true if no variables have been printed yet
* @param p_module name of the current module, if it's a global scope,
* otherwise NULL */
void list_variables(regex_t* p_posix_regexp, bool& p_first,
const char* p_module) const;
};
//////////////////////////////////////////////////////
/////////////// TTCN3_Debug_Function /////////////////
//////////////////////////////////////////////////////
/** debugger function class
*
* instantiated at the beginning of every function, destroyed when function execution ends
*
* tracks all variables created during the function's execution (local variables),
* including the function's parameters, and stores the function's return value */
class TTCN3_Debug_Function {
/** name of the function, not owned */
const char* function_name;
/** the TTCN-3 keyword(s) used to define the function ("function", "testcase",
* "altstep", "template" or "external function"), not owned */
const char* function_type;
/** name of the module this function is defined in, not owned */
const char* module_name;
/** names of the function's parameters (in the order of their declaration), owned */
charstring_list* parameter_names;
/** types (directions) of the function's parameters ("in", "inout" or "out"), owned */
charstring_list* parameter_types;
/** list of local variables tracked by this object, the array elements are owned */
Vector<TTCN3_Debugger::variable_t*> variables;
/** list of pointers to the scope objects of code blocks in the function,
* the elements are not owned
* (currently not used for anything) */
Vector<TTCN3_Debug_Scope*> scopes;
/** pointer to the global scope object, not owned
* (may be NULL, if the module's global scope is empty) */
const TTCN3_Debug_Scope* global_scope;
/** pointer to the runs-on component's scope object, not owned
* (may be NULL, if the component's scope is empty or if the function has no runs-on clause) */
const TTCN3_Debug_Scope* component_scope;
/** the function's return value (unbound if the return value has not been set yet,
* or if the function doesn't return anything)
*
* since this is only set right before the function ends, it is only accessible
* from the destructor */
CHARSTRING return_value;
public:
/** constructor - initializes the instance with the specified parameters,
* retrieves the global scope and component scope from the main debugger object */
TTCN3_Debug_Function(const char* p_name, const char* p_type, const char* p_module,
const charstring_list& p_parameter_names, const charstring_list& p_parameter_types, const char* p_component_name);
/** destructor - frees resources and saves the function's ending snapshot
* (including the values of 'out' and 'inout' parameters and the return value)
* in the main debugger object (only if the debugger is switched on) */
~TTCN3_Debug_Function();
//////////////////////////////////////////////////////
////// methods called from TITAN generated code //////
//////////////////////////////////////////////////////
/** creates, stores and returns the variable entry of the local (constant) variable
* specified by the parameters (only if the debugger is switched on) */
TTCN3_Debugger::variable_t* add_variable(const void* p_value, const char* p_name,
const char* p_type, const char* p_module,
TTCN3_Debugger::print_function_t p_print_function);
/** same as before, but for non-constant variables */
TTCN3_Debugger::variable_t* add_variable(void* p_value, const char* p_name,
const char* p_type, const char* p_module,
TTCN3_Debugger::print_function_t p_print_function,
TTCN3_Debugger::set_function_t p_set_function);
/** stores the string representation of the value returned by the function */
void set_return_value(const CHARSTRING& p_value);
/** saves the function's initial snapshot (including the values of 'in' and
* 'inout' parameters) in the main debugger object
* (only if the debugger is switched on) */
void initial_snapshot() const;
//////////////////////////////////////////////////////
////// methods called by other debugger classes //////
//////////////////////////////////////////////////////
/** adds the specified scope object pointer to the function's scope list */
void add_scope(TTCN3_Debug_Scope* p_scope);
/** removes the specified scope object pointer from the function's scope list,
* if it is the last scope in the list */
void remove_scope(TTCN3_Debug_Scope* p_scope);
/** removes the specified variable from the variable list */
void remove_variable(const TTCN3_Debugger::variable_t* p_var);
/** searches for the variable entry with the specified name in the function's
* local variable list, the global scope (if any) and the component scope (if any),
* returns NULL, if the variable was not found */
TTCN3_Debugger::variable_t* find_variable(const char* p_name) const;
/** prints the function's type, name and current values of parameters */
void print_function() const;
/** returns the name of the function */
const char* get_function_name() const { return function_name; }
/** returns the name of the module the function was defined in */
const char* get_module_name() const { return module_name; }
/** prints the names of variables specified by the parameters (separated by spaces)
* handles the D_LIST_VARIABLES debugger command
* @param p_scope specifies which scope to print variables from:
* - "local" - the function's local variables (including variables in code blocks)
* - "global" - variables in the module's global scope
* - "comp" or "component" - variables in the function's runs-on component scope
* - "all" - all variables visible in the function (i.e. all of the above)
* @param p_filter a pattern to filter variable names further */
void list_variables(const char* p_scope, const char* p_filter) const;
/** returns true if this instance belongs to a control part */
boolean is_control_part() const;
/** returns true if this instance belongs to a test case */
boolean is_test_case() const;
};
/** This macro stores a function's return value in the current function.
* The returned value might be an expression, so it is copied to a temporary first,
* to avoid being evaluated twice. */
#define DEBUGGER_STORE_RETURN_VALUE(tmp, ret_val) \
(tmp = (ret_val), \
ttcn3_debugger.set_return_value((TTCN_Logger::begin_event_log2str(), \
tmp.log(), \
TTCN_Logger::end_event_log2str())), \
tmp)
#endif /* DEBUGGER_HH */
|