debug.ipp
来自「Boost provides free peer-reviewed portab」· IPP 代码 · 共 971 行 · 第 1/2 页
IPP
971 行
char const* cmnd_file_name = prepare_gdb_cmnd_file( dsi ); if( !cmnd_file_name ) return; char dbg_cmd_buff[500]; // !! ?? ::snprintf( dbg_cmd_buff, sizeof(dbg_cmd_buff), "(progn (gdb \"gdb -q -x %s\"))", cmnd_file_name ); start_debugger_in_emacs( dsi, "emacs", dbg_cmd_buff );}//____________________________________________________________________________//static voidstart_gdb_in_xemacs( dbg_startup_info const& ){ // !! ??}//____________________________________________________________________________//// ************************************************************************** //// ************** dbx starters ************** //// ************************************************************************** //static char const*prepare_dbx_cmd_line( dbg_startup_info const& dsi, bool list_source = true ){ static char cmd_line_buff[500]; // !! ?? ::snprintf( cmd_line_buff, sizeof(cmd_line_buff), "unlink %s;cont;%s%s", dsi.init_done_lock.begin(), dsi.break_or_continue ? "up 2;": "", list_source ? "echo \" \";list -w3;" : "" ); return cmd_line_buff;}//____________________________________________________________________________//static voidstart_dbx_in_console( dbg_startup_info const& dsi ){ char pid_buff[16]; ::snprintf( pid_buff, sizeof(pid_buff), "%ld", dsi.pid ); safe_execlp( "dbx", "-q", "-c", prepare_dbx_cmd_line( dsi ), dsi.binary_path.begin(), pid_buff, 0 );}//____________________________________________________________________________//static voidstart_dbx_in_xterm( dbg_startup_info const& dsi ){ char const* title = prepare_window_title( dsi ); if( !title ) return; char pid_buff[16]; // !! ?? ::snprintf( pid_buff, sizeof(pid_buff), "%ld", dsi.pid ); safe_execlp( "xterm", "-T", title, "-display", dsi.display.begin(), "-bg", "black", "-fg", "white", "-geometry", "88x30+10+10", "-fn", "9x15", "-e", "dbx", "-q", "-c", prepare_dbx_cmd_line( dsi ), dsi.binary_path.begin(), pid_buff, 0 );}//____________________________________________________________________________//static voidstart_dbx_in_emacs( dbg_startup_info const& /*dsi*/ ){// char dbg_cmd_buff[500]; // !! ??//// ::snprintf( dbg_cmd_buff, sizeof(dbg_cmd_buff), "(progn (dbx \"dbx -q -c cont %s %ld\"))", dsi.binary_path.begin(), dsi.pid );// start_debugger_in_emacs( dsi, "emacs", dbg_cmd_buff );}//____________________________________________________________________________//static voidstart_dbx_in_xemacs( dbg_startup_info const& ){ // !! ??}//____________________________________________________________________________//static voidstart_dbx_in_ddd( dbg_startup_info const& dsi ){ char const* title = prepare_window_title( dsi ); if( !title ) return; char pid_buff[16]; // !! ?? ::snprintf( pid_buff, sizeof(pid_buff), "%ld", dsi.pid ); safe_execlp( "ddd", "-display", dsi.display.begin(), "--dbx", "-q", "-c", prepare_dbx_cmd_line( dsi, false ), dsi.binary_path.begin(), pid_buff, 0 );}//____________________________________________________________________________//// ************************************************************************** //// ************** debug::info_t ************** //// ************************************************************************** //static struct info_t { // Constructor info_t(); // Public properties unit_test::readwrite_property<std::string> p_dbg; // Data members std::map<std::string,dbg_starter> m_dbg_starter_reg;} s_info;//____________________________________________________________________________//info_t::info_t(){ p_dbg.value = ::getenv( "DISPLAY" ) ? std::string( BOOST_STRINGIZE( BOOST_TEST_GUI_DBG ) ) : std::string( BOOST_STRINGIZE( BOOST_TEST_CNL_DBG ) ); m_dbg_starter_reg[std::string("gdb")] = &start_gdb_in_console; m_dbg_starter_reg[std::string("gdb-emacs")] = &start_gdb_in_emacs; m_dbg_starter_reg[std::string("gdb-xterm")] = &start_gdb_in_xterm; m_dbg_starter_reg[std::string("gdb-xemacs")] = &start_gdb_in_xemacs; m_dbg_starter_reg[std::string("dbx")] = &start_dbx_in_console; m_dbg_starter_reg[std::string("dbx-emacs")] = &start_dbx_in_emacs; m_dbg_starter_reg[std::string("dbx-xterm")] = &start_dbx_in_xterm; m_dbg_starter_reg[std::string("dbx-xemacs")] = &start_dbx_in_xemacs; m_dbg_starter_reg[std::string("dbx-ddd")] = &start_dbx_in_ddd;}//____________________________________________________________________________//#endif} // local namespace// ************************************************************************** //// ************** check if program is running under debugger ************** //// ************************************************************************** //boolunder_debugger(){#if defined(BOOST_WIN32_BASED_DEBUG) // *********************** WIN32 return !!s_info.m_is_debugger_present && s_info.m_is_debugger_present();#elif defined(BOOST_UNIX_BASED_DEBUG) // ********************** UNIX // !! ?? could/should we cache the result somehow? const_string dbg_list = BOOST_TEST_STRINGIZE( BOOST_TEST_DBG_LIST ); pid_t pid = ::getpid(); while( pid != 0 ) { process_info pi( pid ); // !! ?? should we use tokenizer here instead? if( dbg_list.find( pi.binary_name() ) != const_string::npos ) return true; pid = pi.parent_pid(); } return false;#else // ****************************************************** default return false;#endif}//____________________________________________________________________________//// ************************************************************************** //// ************** cause program to break execution ************** //// ************** in debugger at call point ************** //// ************************************************************************** //voiddebugger_break(){ // !! ?? auto-start debugger?#if defined(BOOST_WIN32_BASED_DEBUG) // *********************** WIN32#if BOOST_WORKAROUND(BOOST_MSVC, >= 1300) || \ BOOST_WORKAROUND(__GNUC__, >= 3) && !defined(__MINGW32__) || \ defined(__INTEL_COMPILER)# define BOOST_DEBUG_BREAK __debugbreak#else# define BOOST_DEBUG_BREAK DebugBreak#endif#ifndef __MINGW32__ if( !under_debugger() ) { __try { __try { BOOST_DEBUG_BREAK(); } __except( UnhandledExceptionFilter(GetExceptionInformation()) ) { // User opted to ignore the breakpoint return; } } __except (EXCEPTION_EXECUTE_HANDLER) { // If we got here, the user has pushed Debug. Debugger is already attached to our process and we // continue to let the another BOOST_DEBUG_BREAK to be called. } }#endif BOOST_DEBUG_BREAK();#elif defined(BOOST_UNIX_BASED_DEBUG) // ********************** UNIX ::kill( ::getpid(), SIGTRAP );#else // ****************************************************** default#endif}//____________________________________________________________________________//// ************************************************************************** //// ************** console debugger setup ************** //// ************************************************************************** //#if defined(BOOST_UNIX_BASED_DEBUG) // ************************ UNIXstd::stringset_debugger( unit_test::const_string dbg_id, dbg_starter s ){ std::string old = s_info.p_dbg; assign_op( s_info.p_dbg.value, dbg_id, 0 ); if( !!s ) s_info.m_dbg_starter_reg[s_info.p_dbg] = s; return old;}#else // ***************************************************** defaultstd::stringset_debugger( unit_test::const_string, dbg_starter ){ return std::string();}#endif//____________________________________________________________________________//// ************************************************************************** //// ************** attach debugger to the current process ************** //// ************************************************************************** //boolattach_debugger( bool break_or_continue ){ if( under_debugger() ) return false;#if defined(BOOST_WIN32_BASED_DEBUG) // *********************** WIN32 const int MAX_CMD_LINE = 200; // *************************************************** // // Debugger "ready" event SECURITY_ATTRIBUTES attr; attr.nLength = sizeof(attr); attr.lpSecurityDescriptor = NULL; attr.bInheritHandle = true; // manual resettable, initially non signaled, unnamed event, // that will signal me that debugger initialization is done HANDLE dbg_init_done_ev = ::CreateEvent( &attr, // pointer to security attributes true, // flag for manual-reset event false, // flag for initial state NULL // pointer to event-object name ); if( !dbg_init_done_ev ) return false; // *************************************************** // // Debugger command line format HKEY reg_key; if( !s_info.m_reg_open_key || (*s_info.m_reg_open_key)( HKEY_LOCAL_MACHINE, // handle of open key "Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", // name of subkey to open ®_key ) != ERROR_SUCCESS ) // address of handle of open key return false; char format[MAX_CMD_LINE]; DWORD format_size = MAX_CMD_LINE; DWORD type = REG_SZ; if( !s_info.m_reg_query_value || (*s_info.m_reg_query_value)( reg_key, // handle of open key "Debugger", // name of subkey to query 0, // reserved &type, // value type (LPBYTE)format, // buffer for returned string &format_size ) != ERROR_SUCCESS ) // in: buffer size; out: actual size of returned string return false; if( !s_info.m_reg_close_key || (*s_info.m_reg_close_key)( reg_key ) != ERROR_SUCCESS ) return false; // *************************************************** // // Debugger command line char cmd_line[MAX_CMD_LINE]; std::sprintf( cmd_line, format, ::GetCurrentProcessId(), dbg_init_done_ev ); // *************************************************** // // Debugger window parameters STARTUPINFOA startup_info; std::memset( &startup_info, 0, sizeof(startup_info) ); startup_info.cb = sizeof(startup_info); startup_info.dwFlags = STARTF_USESHOWWINDOW; startup_info.wShowWindow = SW_SHOWNORMAL; // debugger process s_info PROCESS_INFORMATION debugger_info; bool created = !!::CreateProcessA( NULL, // pointer to name of executable module; NULL - use the one in command line cmd_line, // pointer to command line string NULL, // pointer to process security attributes; NULL - debugger's handle couldn't be inherited NULL, // pointer to thread security attributes; NULL - debugger's handle couldn't be inherited true, // debugger inherit opened handles 0, // priority flags; 0 - normal priority NULL, // pointer to new environment block; NULL - use this process environment NULL, // pointer to current directory name; NULL - use this process correct directory &startup_info, // pointer to STARTUPINFO that specifies main window appearance &debugger_info // pointer to PROCESS_INFORMATION that will contain the new process identification ); if( created ) ::WaitForSingleObject( dbg_init_done_ev, INFINITE ); ::CloseHandle( dbg_init_done_ev ); if( !created ) return false; if( break_or_continue ) debugger_break(); return true;#elif defined(BOOST_UNIX_BASED_DEBUG) // ********************** UNIX char init_done_lock_fn[] = "/tmp/btl_dbg_init_done_XXXXXX"; fd_holder init_done_lock_fd( ::mkstemp( init_done_lock_fn ) ); if( init_done_lock_fd == -1 ) return false; pid_t child_pid = fork(); if( child_pid == -1 ) return false; if( child_pid != 0 ) { // parent process - here we will start the debugger dbg_startup_info dsi; process_info pi( child_pid ); if( pi.binary_path().is_empty() ) ::exit( -1 ); dsi.pid = child_pid; dsi.break_or_continue = break_or_continue; dsi.binary_path = pi.binary_path(); dsi.display = ::getenv( "DISPLAY" ); dsi.init_done_lock = init_done_lock_fn; dbg_starter starter = s_info.m_dbg_starter_reg[s_info.p_dbg]; if( !!starter ) starter( dsi ); ::perror( "Boost.Test execution monitor failed to start a debugger:" ); ::exit( -1 ); } // child process - here we will continue our test module execution ; // !! ?? should it be vice versa while( ::access( init_done_lock_fn, F_OK ) == 0 ) { struct timeval to = { 0, 100 }; ::select( 0, 0, 0, 0, &to ); }// char dummy;// while( ::read( init_done_lock_fd, &dummy, sizeof(char) ) == 0 ); if( break_or_continue ) debugger_break(); return true;#else // ****************************************************** default return false;#endif}//____________________________________________________________________________//// ************************************************************************** //// ************** switch on/off detect memory leaks feature ************** //// ************************************************************************** //voiddetect_memory_leaks( bool on_off ){ unit_test::ut_detail::ignore_unused_variable_warning( on_off );#ifdef BOOST_MS_CRT_BASED_DEBUG int flags = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); if( !on_off ) flags &= ~_CRTDBG_LEAK_CHECK_DF; else { flags |= _CRTDBG_LEAK_CHECK_DF; _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT); } _CrtSetDbgFlag ( flags );#endif // BOOST_MS_CRT_BASED_DEBUG}//____________________________________________________________________________//// ************************************************************************** //// ************** cause program to break execution in ************** //// ************** debugger at specific allocation point ************** //// ************************************************************************** //voidbreak_memory_alloc( long mem_alloc_order_num ){ unit_test::ut_detail::ignore_unused_variable_warning( mem_alloc_order_num );#ifdef BOOST_MS_CRT_BASED_DEBUG _CrtSetBreakAlloc( mem_alloc_order_num );#endif // BOOST_MS_CRT_BASED_DEBUG}} // namespace debug} // namespace boost//____________________________________________________________________________//#include <boost/test/detail/enable_warnings.hpp>#endif // BOOST_TEST_DEBUG_API_IPP_112006GER
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?