#ifndef LIB_DBG_DEBUG_DEFINITIONS_MQH_INCLUDED #define LIB_DBG_DEBUG_DEFINITIONS_MQH_INCLUDED #property version "5.10" /********************************************************************************** * Copyright (C) 2020 Dominik Egert * * This file is the debugger main user macros include file. * * Lisence applied: GPLv2 * https://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Author Dominik Egert / Freie Netze UG. ********************************************************************************** * * Version: 5.10 * State: public * * File information * ================ * */ //*********************************************************************************************************************************************************/ // BEGIN Debugging macros // ///////////////////////////////////////////////////////////////////////////////////////////////////// // // Debugger mode // #undef DBG_DEBUGGER_FLAG_STATE #undef DBG_STR_EX45_FILEINFO #undef DBG_ASSERT #undef DBG_ASSERT_LOG #undef DBG_ASSERT_RETURN #undef DBG_ASSERT_RETURN_VAR #undef DBG_BREAK_ARRAY_OUT_OF_RANGE #undef DBG_SLEEP_SECONDS #undef DBG_SOFT_BREAKPOINT #undef DBG_SOFT_BREAKPOINT_TS #undef DBG_SOFT_BREAKPOINT_CONDITION #undef DBG_SOFT_BREAKPOINT_EXEC_TIME #undef DBG_BREAK_CONDITION_CREATE #undef DBG_BREAK_CONDITION_ACTIVATE #undef DBG_BREAK_CONDITION_DEACTIVATE #undef DBG_BREAK_CONDITION_ON_ID #undef DBG_BREAK_CONDITION_ON_ID_RESET #undef DBG_TRACE_LOOP_BEGIN #undef DBG_TRACE_LOOP_START #undef DBG_TRACE_LOOP_FINISH #undef DBG_TRACE_LOOP_END #undef DBG_TRACE_LOOP_BEGIN_ID #undef DBG_TRACE_LOOP_START_ID #undef DBG_TRACE_LOOP_FINISH_ID #undef DBG_TRACE_LOOP_END_ID #undef LIB_DBG_GETTICKCOUNT #undef DBG_ERR_SUCCESS #undef typename_raw #undef LIB_DBG_INCLUDE_COMPLEX_TYPE #undef __DBG_STRINGIFY_MACRO #undef DBG_SLEEP_MILLISECONDS #undef DBG_SLEEP_SECONDS #undef DBG_TRACE_EXEC_DELAY #undef DBG_STR_TRACE_EXEC_DELAY_INFO #undef DBG_DEBUGGER_RUNTIME_STATE #undef DBG_GENERIC_ASSERT // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // Auto enable/disable by environment // // Enable debugging support #ifdef LIB_DEBUG_LOGFILE #ifndef LIB_DEBUG #define LIB_DEBUG #endif #ifndef LIB_DBG_LOG_TO_FILE #define LIB_DBG_LOG_TO_FILE #endif #endif // Autoenable #ifndef _DEBUG #ifdef LIB_DEBUG #define _DEBUG true #endif #endif #ifdef _DEBUG #ifdef LIB_DEBUG_AUTOENABLE #ifndef LIB_DEBUG #define LIB_DEBUG #endif #endif #ifndef DBG_DEBUGGER_FLAG #define DBG_DEBUGGER_FLAG ((LIB_DBG_NAMESPACE(dbg_lib, dbg_MQLInfoInteger)(MQL_DEBUG)) ? "MQL_DEBUG set" : "_DEBUG defined") #endif #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // Initial setup // // Environment check #ifndef __MQL5__ #ifndef __MQL4_COMPATIBILITY_CODE__ #ifndef __NO_MQL4_COMPATIBILITY_CODE__ #define __NO_MQL4_COMPATIBILITY_CODE__ #endif #endif #ifndef LIB_DBG_NAMESPACE #define LIB_DBG_NAMESPACE(x, y) x##_##y #endif #ifndef LIB_DBG_NAMESPACE_DEF #define LIB_DBG_NAMESPACE_DEF(x, y) LIB_DBG_NAMESPACE(x, y) #endif #else #ifndef LIB_DBG_NAMESPACE #define LIB_DBG_NAMESPACE(x, y) x::y #endif #ifndef LIB_DBG_NAMESPACE_DEF #define LIB_DBG_NAMESPACE_DEF(x, y) y #endif #endif // Force enable by MQLAPI #ifdef LIB_MQLAPI_TRACE #ifndef LIB_DEBUG_MQLAPI_ALL_CALLS #define LIB_DEBUG_MQLAPI_ALL_CALLS #endif #endif #ifdef LIB_DEBUG_MQLAPI_ALL_CALLS #ifndef LIB_DEBUG_MQLAPI #define LIB_DEBUG_MQLAPI #endif #endif #ifdef LIB_DEBUG_MQLAPI_TRACE #ifndef LIB_DEBUG_MQLAPI #define LIB_DEBUG_MQLAPI #endif #endif #ifdef LIB_DEBUG_MQLAPI #ifndef LIB_DEBUG #define LIB_DEBUG #define LIB_DEBUG_INCLUDE_STUB #endif #endif // By default disable mql api tracing #ifndef LIB_DEBUG_MQLAPI #ifndef LIB_MQLAPI_CALL_TRACING_DISABLE #define LIB_MQLAPI_CALL_TRACING_DISABLE #endif #else #ifndef LIB_MQLAPI_CALL_TRACING_ENABLED #define LIB_MQLAPI_CALL_TRACING_ENABLED #endif #endif // Custom MQLplus expert remove reason #ifndef REASON_MQLPLUS_EXPERT_KILL #define REASON_MQLPLUS_EXPERT_KILL 0xFF01 #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // Debugger default configuration loader // // Code location string #ifndef DBG_CODE_LOCATION_STRING #define DBG_CODE_LOCATION_STRING file, function, line #endif // Output message format definition #ifndef DBG_OUTPUT_STRING #define DBG_OUTPUT_STRING "%s >%s< %s(){ @%i: %s }" #endif // Output trace begin format definition #ifndef DBG_OUTPUT_TRACE_BEGIN_FORMAT #ifdef __MQL5__ #define DBG_OUTPUT_TRACE_BEGIN_FORMAT " V-V-V-V-V [ Chart-ID: %llu :: Call depth: %-3i] V-V-V-V-V [ %s() BEGIN - Call counter: %-3i ] V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V" #else #define DBG_OUTPUT_TRACE_BEGIN_FORMAT " A-A-A-A-A [ Chart-ID: %llu :: Call depth: %-3i] A-A-A-A-A [ %s() BEGIN - Call counter: %-3i ] A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A" #endif #endif // Output trace end format definition #ifndef DBG_OUTPUT_TRACE_END_FORMAT #ifdef __MQL5__ #define DBG_OUTPUT_TRACE_END_FORMAT " A-A-A-A-A [ Call depth: %-3i] A-A-A-A-A [ %s() END ] A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A-A" #else #define DBG_OUTPUT_TRACE_END_FORMAT " V-V-V-V-V [ Call depth: %-3i] V-V-V-V-V [ %s() END ] V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V-V" #endif #endif // Output alignemnt for right column spacing #ifndef DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER #define DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER 120 #endif // Set default api tracing behaviour #ifdef LIB_MQLAPI_CALL_TRACING_ENABLED #ifndef LIB_DBG_API_CALL_TRACE_DEFAULT #define LIB_DBG_API_CALL_TRACE_DEFAULT true #endif #else #define LIB_DBG_API_CALL_TRACE_DEFAULT false #endif // Check type of API-Tracing #ifdef LIB_DEBUG_MQLAPI_ALL_CALLS #ifndef LIB_MQLAPI_CALL_TRACING_ENABLED #define LIB_MQLAPI_CALL_TRACING_ENABLED #endif #endif // Force MQL-API call tracing on all functions #ifdef LIB_MQLAPI_CALL_TRACING_ENABLED #ifdef LIB_DEBUG_MQLAPI_ALL_CALLS #ifndef LIB_DBG_API_CALL_TRACE_FORCE_ON #define LIB_DBG_API_CALL_TRACE_FORCE_ON true #endif #endif #endif #ifndef LIB_DBG_API_CALL_TRACE_FORCE_ON #define LIB_DBG_API_CALL_TRACE_FORCE_ON false #endif // Force disable mql api tracing #ifdef LIB_MQLAPI_CALL_TRACING_DISABLE #undef LIB_MQLAPI_CALL_TRACING_ENABLED #undef LIB_DBG_API_CALL_TRACE_DEFAULT #define LIB_DBG_API_CALL_TRACE_DEFAULT false #endif // Pause execution after vardump call #ifndef DBG_VARDUMP_PAUSE #define DBG_VARDUMP_PAUSE 0 #endif // Hexadecimal output of vairables #define DBG_HEX_OUTPUT true #ifdef DBG_BINARY_BIT_REPRESENTATION #undef DBG_HEX_OUTPUT #define DBG_HEX_OUTPUT false #endif // Crash code definition #ifndef DBG_CRASH_CODE #define DBG_CRASH_CODE { int arr[1]; int i = 1; i = (arr[1] / (i - i)); } #endif // Maximum variable name length #ifndef DBG_PRINT_VARNAME_MAX_LENGTH #define DBG_PRINT_VARNAME_MAX_LENGTH 45 #endif // Vardump array element limiter #ifndef DBG_MSG_VAR_ARRAY_LIMIT #define DBG_MSG_VAR_ARRAY_LIMIT(x) ((LIB_DBG_NAMESPACE(dbg_lib, dbg_ArraySize)(x) > 25) ? 10 : LIB_DBG_NAMESPACE(dbg_lib, dbg_ArraySize)(x)) #endif // Set default assert message #ifndef DBG_ASSERT_MSG_TXT #define DBG_ASSERT_MSG_TXT "### --- Assertion failed!" #endif // Set default trace begin messages #ifndef DBG_TRACE_BEGIN_MSG_TXT #define DBG_TRACE_BEGIN_MSG_TXT ">>>Function begin<<<" #endif // Set default trace end messages #ifndef DBG_TRACE_END_MSG_TXT #define DBG_TRACE_END_MSG_TXT ">>>Function end<<<" #endif // Set default MQL-API Version string #ifdef __MQL5__ #ifndef DBG_MQLAPI_VERSION #define DBG_MQLAPI_VERSION "MQL5-API" #endif #else #ifndef DBG_MQLAPI_VERSION #define DBG_MQLAPI_VERSION "MQL4-API" #endif #endif // Default output prefix #ifndef DBG_OUTPUT_PREFIX #define DBG_OUTPUT_PREFIX " " #endif // Right column spacing printf variables #ifndef DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER #ifdef DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER #define DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER #else #define DBG_MSG_FORMAT_RIGHT_COLUMN_SPACER 120 #endif #endif // Overwrite mode #ifndef DBG_DEBUGGER_FLAG #define DBG_DEBUGGER_FLAG "LIB_DEBUG overwrite mode" #define DBG_DEBUGGER_OVERWRITE #endif // Soft breakpoint timeout in seconds #ifndef DBG_SOFT_BKP_TIMEOUT #define DBG_SOFT_BKP_TIMEOUT 120 #endif // Turn off execution profiler #ifdef LIB_PERF_PROFILING #undef LIB_PERF_PROFILING #endif // Define log filename for file logging #ifdef LIB_DBG_LOG_TO_FILE #ifndef DBG_LOG_FILENAME #define DBG_LOG_FILENAME LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("debug_log/%s/%llu%s", LIB_DBG_NAMESPACE(dbg_lib, dbg_MQLInfoString)(MQL_PROGRAM_NAME), LIB_DBG_NAMESPACE(dbg_lib, dbg_true_system_time)(), ".txt") #endif #endif #ifdef LIB_DEBUG_NO_JOURNAL_OUTPUT #define LIB_DBG_NO_JOURNAL #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////// // // Internal helper definitions // // Select availabel GetTickCount function #ifdef __MQL5__ #define LIB_DBG_GETTICKCOUNT GetTickCount64 #define DBG_ERR_SUCCESS ERR_SUCCESS #else #define LIB_DBG_GETTICKCOUNT GetTickCount #define DBG_ERR_SUCCESS ERR_NO_ERROR #endif // Original typename functionality #ifndef typename_raw #ifdef __MQL4_COMPATIBILITY_CODE__ #define typename_raw(x) typename((x)) #else #define typename_raw(x) (__MQL5BUILD__ < 3510) ? typename((x)) : LIB_DBG_NAMESPACE(dbg_lib, dbg_typename_to_string)(typename((x))) #endif #endif // Include complex type #ifndef __MQL5__ #ifdef __MQL4_COMPATIBILITY_CODE__ #define LIB_DBG_INCLUDE_COMPLEX_TYPE #endif #else #define LIB_DBG_INCLUDE_COMPLEX_TYPE #endif // Stringify cleaner macro #ifdef LIB_MQLAPI_CALL_TRACING_ENABLED #define __DBG_STRINGIFY_MACRO(x) LIB_DBG_NAMESPACE(dbg_lib, dbg_extract_mqlfunction_name)(#x) #else #define __DBG_STRINGIFY_MACRO(x) #x #endif // Soft breakpoint timeout command #define DBG_SLEEP_MILLISECONDS(x) { ulong dbg_sleep_seconds_delay = (LIB_DBG_NAMESPACE(dbg_lib, dbg_GetTickCount)() + (x)); while((!_DEBUG) && (!_StopFlag) && (dbg_sleep_seconds_delay > LIB_DBG_NAMESPACE(dbg_lib, dbg_GetTickCount)())); } #define DBG_SLEEP_SECONDS(x) DBG_SLEEP_MILLISECONDS((x * 1000)) // Execution delay #ifdef DBG_TRACE_EXEC_DELAY_MS #define DBG_TRACE_EXEC_DELAY DBG_SLEEP_MILLISECONDS(DBG_TRACE_EXEC_DELAY_MS) #define DBG_STR_TRACE_EXEC_DELAY_INFO LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("Debug trace execution delay: %i ms", DBG_TRACE_EXEC_DELAY_MS) #else #define DBG_TRACE_EXEC_DELAY #define DBG_STR_TRACE_EXEC_DELAY_INFO "" #endif // Debugger state string #define DBG_DEBUGGER_FLAG_STATE "[DEBUG]" // Debugger runtime flag state #define DBG_DEBUGGER_RUNTIME_STATE LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("IS_DEBUG_MODE = %s\r\n %s", (IS_DEBUG_MODE) ? "true" : "false", DBG_STR_TRACE_EXEC_DELAY_INFO) // EX5 and terminal info string #ifdef __MQL5__ #define DBG_STR_EX45_FILEINFO LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("MQL5 compiler build: %i %s\r\n compiled@%s\r\n => %s\r\n %s\r\n %s", __MQL5BUILD__, DBG_DEBUGGER_FLAG_STATE, LIB_DBG_NAMESPACE(dbg_lib, dbg_TimeToString)(__DATETIME__), DBG_DEBUGGER_FLAG_STATE, DBG_DEBUGGER_FLAG, DBG_DEBUGGER_RUNTIME_STATE) #else #define DBG_STR_EX45_FILEINFO LIB_DBG_NAMESPACE(dbg_lib, dbg_StringFormat)("MQL4 Terminal build: %i\n compiler build: %i %s\n compiled@%s\n => %s\n %s\n %s", LIB_DBG_NAMESPACE(dbg_lib, dbg_TerminalInfoInteger)(TERMINAL_BUILD), __MQL4BUILD__, DBG_DEBUGGER_FLAG_STATE, LIB_DBG_NAMESPACE(dbg_lib, dbg_TimeToString)(__DATETIME__), DBG_DEBUGGER_FLAG_STATE, DBG_DEBUGGER_FLAG, DBG_DEBUGGER_RUNTIME_STATE) #endif // ///////////////////////////////////////////////////////////////////////////////////////////////////// // // END Debugging support //*********************************************************************************************************************************************************/ #endif // LIB_DBG_DEBUG_DEFINITIONS_MQH_INCLUDED