⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assert.cxx

📁 pwlib源码库
💻 CXX
字号:
/* * assert.cxx * * Function to implement assert clauses. * * Portable Windows Library * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * $Log: assert.cxx,v $ * Revision 1.39  2004/07/06 10:12:55  csoutheren * Added static integer o factory template to assist in ensuring factories are instantiated * * Revision 1.38  2004/04/03 06:54:30  rjongbloed * Many and various changes to support new Visual C++ 2003 * * Revision 1.37  2002/09/25 00:54:50  robertj * Fixed memory leak on assertion. * * Revision 1.36  2002/09/23 07:17:24  robertj * Changes to allow winsock2 to be included. * * Revision 1.35  2002/06/25 02:25:29  robertj * Improved assertion system to allow C++ class name to be displayed if *   desired, especially relevant to container classes. * * Revision 1.34  2001/08/17 19:18:15  yurik * Fixed compile error in release mode * * Revision 1.33  2001/08/16 18:38:05  yurik * Fixed assert function * * Revision 1.32  2001/04/26 06:07:34  yurik * UI improvements * * Revision 1.31  2001/03/29 23:33:00  robertj * Added missing structure initialisation, thanks Victor H. * * Revision 1.30  2001/03/02 06:54:04  yurik * Rephrased pragma message * * Revision 1.29  2001/01/24 06:56:03  yurik * Correcting a typo in WinCE related code * * Revision 1.28  2001/01/24 06:34:44  yurik * Windows CE port-related changes * * Revision 1.27  2000/05/23 05:50:43  robertj * Attempted to fix stack dump, still refuses to work even though used to work perfectly. * * Revision 1.26  2000/03/04 08:07:07  robertj * Fixed problem with window not appearing when assert on GUI based win32 apps. * * Revision 1.25  1999/02/16 08:08:06  robertj * MSVC 6.0 compatibility changes. * * Revision 1.24  1999/02/12 01:01:57  craigs * Fixed problem with linking static versions of libraries * * Revision 1.23  1998/12/04 10:10:45  robertj * Added virtual for determining if process is a service. Fixes linkage problem. * * Revision 1.22  1998/11/30 05:33:08  robertj * Fixed duplicate debug stream class, ther can be only one. * * Revision 1.21  1998/11/30 04:48:38  robertj * New directory structure * * Revision 1.20  1998/09/24 03:30:39  robertj * Added open software license. * * Revision 1.19  1997/03/18 21:22:31  robertj * Display error message if assert stack dump fails * * Revision 1.18  1997/02/09 01:27:18  robertj * Added stack dump under NT. * * Revision 1.17  1997/02/05 11:49:40  robertj * Changed current process function to return reference and validate objects descendancy. * * Revision 1.16  1997/01/04 06:52:04  robertj * Removed the press a key to continue under win  '95. * * Revision 1.15  1996/11/18 11:30:00  robertj * Removed int 3 on non-debug versions. * * Revision 1.14  1996/11/16 10:51:51  robertj * Changed assert to display message and break if in debug mode service. * * Revision 1.13  1996/11/10 21:02:08  robertj * Fixed bug in assertion when as a service, string buffer not big enough. * * Revision 1.12  1996/10/08 13:00:46  robertj * Changed default for assert to be ignore, not abort. * * Revision 1.11  1996/07/27 04:08:13  robertj * Changed SystemLog to be stream based rather than printf based. * * Revision 1.10  1996/05/30 11:48:28  robertj * Fixed press a key to continue to only require one key. * * Revision 1.9  1996/05/23 10:03:20  robertj * Windows 95 support. * * Revision 1.8  1996/03/04 12:39:35  robertj * Fixed Win95 support for console tasks. * * Revision 1.7  1996/01/28 14:13:04  robertj * Made PServiceProcess special case global not just WIN32. * * Revision 1.6  1995/12/10 11:55:09  robertj * Numerous fixes for WIN32 service processes. * * Revision 1.5  1995/04/25 11:32:34  robertj * Fixed Borland compiler warnings. * * Revision 1.4  1995/03/12 05:00:04  robertj * Re-organisation of DOS/WIN16 and WIN32 platforms to maximise common code. * Used built-in equate for WIN32 API (_WIN32). * * Revision 1.3  1994/10/30  11:25:09  robertj * Added error number to assert. * * Revision 1.2  1994/06/25  12:13:01  robertj * Synchronisation. * * Revision 1.1  1994/04/01  14:39:35  robertj * Initial revision */#define P_DISABLE_FACTORY_INSTANCES#include <ptlib.h>#include <ptlib/svcproc.h>#include <errno.h>///////////////////////////////////////////////////////////////////////////////// PProcess#if defined(_WIN32)#ifndef _WIN32_WCE#include <imagehlp.h>static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM thisProcess){  char wndClassName[100];  GetClassName(hWnd, wndClassName, sizeof(wndClassName));  if (strcmp(wndClassName, "ConsoleWindowClass") != 0)    return TRUE;  DWORD wndProcess;  GetWindowThreadProcessId(hWnd, &wndProcess);  if (wndProcess != (DWORD)thisProcess)    return TRUE;  cerr << "\nPress a key to continue . . .";  cerr.flush();  HANDLE in = GetStdHandle(STD_INPUT_HANDLE);  SetConsoleMode(in, ENABLE_PROCESSED_INPUT);  FlushConsoleInputBuffer(in);  char dummy;  DWORD readBytes;  ReadConsole(in, &dummy, 1, &readBytes, NULL);  return FALSE;}#endif // _WIN32_WCEvoid PWaitOnExitConsoleWindow(){#ifndef _WIN32_WCE  EnumWindows(EnumWindowsProc, GetCurrentProcessId());#else#endif // _WIN32_WCE}#ifndef _WIN32_WCEclass PImageDLL : public PDynaLink{  PCLASSINFO(PImageDLL, PDynaLink)  public:    PImageDLL();  BOOL (__stdcall *SymInitialize)(    IN HANDLE   hProcess,    IN LPSTR    UserSearchPath,    IN BOOL     fInvadeProcess    );  BOOL (__stdcall *SymCleanup)(    IN HANDLE hProcess    );  DWORD (__stdcall *SymGetOptions)();  DWORD (__stdcall *SymSetOptions)(    DWORD options    );  DWORD (__stdcall *SymLoadModule)(    HANDLE hProcess,    HANDLE hFile,         PSTR   ImageName,      PSTR   ModuleName,     DWORD  BaseOfDll,      DWORD  SizeOfDll       );  BOOL (__stdcall *StackWalk)(    DWORD                             MachineType,    HANDLE                            hProcess,    HANDLE                            hThread,    LPSTACKFRAME                      StackFrame,    LPVOID                            ContextRecord,    PREAD_PROCESS_MEMORY_ROUTINE      ReadMemoryRoutine,    PFUNCTION_TABLE_ACCESS_ROUTINE    FunctionTableAccessRoutine,    PGET_MODULE_BASE_ROUTINE          GetModuleBaseRoutine,    PTRANSLATE_ADDRESS_ROUTINE        TranslateAddress    );  BOOL (__stdcall *SymGetSymFromAddr)(    IN  HANDLE              hProcess,    IN  DWORD               dwAddr,    OUT PDWORD              pdwDisplacement,    OUT PIMAGEHLP_SYMBOL    Symbol    );  PFUNCTION_TABLE_ACCESS_ROUTINE SymFunctionTableAccess;  PGET_MODULE_BASE_ROUTINE       SymGetModuleBase;  BOOL (__stdcall *SymGetModuleInfo)(    IN  HANDLE              hProcess,    IN  DWORD               dwAddr,    OUT PIMAGEHLP_MODULE    ModuleInfo    );};PImageDLL::PImageDLL()  : PDynaLink("IMAGEHLP.DLL"){  if (!GetFunction("SymInitialize", (Function &)SymInitialize) ||      !GetFunction("SymCleanup", (Function &)SymCleanup) ||      !GetFunction("SymGetOptions", (Function &)SymGetOptions) ||      !GetFunction("SymSetOptions", (Function &)SymSetOptions) ||      !GetFunction("SymLoadModule", (Function &)SymLoadModule) ||      !GetFunction("StackWalk", (Function &)StackWalk) ||      !GetFunction("SymGetSymFromAddr", (Function &)SymGetSymFromAddr) ||      !GetFunction("SymFunctionTableAccess", (Function &)SymFunctionTableAccess) ||      !GetFunction("SymGetModuleBase", (Function &)SymGetModuleBase) ||      !GetFunction("SymGetModuleInfo", (Function &)SymGetModuleInfo))    Close();}#endif#endifvoid PAssertFunc(const char * msg){#ifndef _WIN32_WCE  ostrstream str;  str << msg;#if defined(_WIN32) && defined(_M_IX86)  PImageDLL imagehlp;  if (imagehlp.IsLoaded()) {    // Turn on load lines.    imagehlp.SymSetOptions(imagehlp.SymGetOptions()|SYMOPT_LOAD_LINES);    HANDLE hProcess;    OSVERSIONINFO ver;    ver.dwOSVersionInfoSize = sizeof(ver);    ::GetVersionEx(&ver);    if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT)      hProcess = GetCurrentProcess();    else      hProcess = (HANDLE)GetCurrentProcessId();    if (imagehlp.SymInitialize(hProcess, NULL, TRUE)) {      HANDLE hThread = GetCurrentThread();      // The thread information.      CONTEXT threadContext;      threadContext.ContextFlags = CONTEXT_FULL ;      if (GetThreadContext(hThread, &threadContext)) {        STACKFRAME frame;        memset(&frame, 0, sizeof(frame));#if defined (_M_IX86)#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_I386        frame.AddrPC.Offset    = threadContext.Eip;        frame.AddrPC.Mode      = AddrModeFlat;        frame.AddrStack.Offset = threadContext.Esp;        frame.AddrStack.Mode   = AddrModeFlat;        frame.AddrFrame.Offset = threadContext.Ebp;        frame.AddrFrame.Mode   = AddrModeFlat;#elif defined (_M_ALPHA)#define IMAGE_FILE_MACHINE IMAGE_FILE_MACHINE_ALPHA        frame.AddrPC.Offset = (unsigned long)threadContext.Fir;        frame.AddrPC.Mode   = AddrModeFlat;#else#error ( "Unknown machine!" )#endif        int frameCount = 0;        while (frameCount++ < 16 &&               imagehlp.StackWalk(IMAGE_FILE_MACHINE,                                  hProcess,                                  hThread,                                  &frame,                                  &threadContext,                                  NULL, // ReadMemoryRoutine                                  imagehlp.SymFunctionTableAccess,                                  imagehlp.SymGetModuleBase,                                  NULL)) {          if (frameCount > 1 && frame.AddrPC.Offset != 0) {            char buffer[sizeof(IMAGEHLP_SYMBOL)+100];            PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL)buffer;            symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);            symbol->MaxNameLength = sizeof(buffer)-sizeof(IMAGEHLP_SYMBOL);            DWORD displacement = 0;            if (imagehlp.SymGetSymFromAddr(hProcess,                                           frame.AddrPC.Offset,                                           &displacement,                                           symbol)) {              str << "\n    " << symbol->Name;            }            else {              str << "\n    0x"                  << hex << setfill('0')                  << setw(8) << frame.AddrPC.Offset                  << dec << setfill(' ');            }            str << '(' << hex << setfill('0');            for (PINDEX i = 0; i < PARRAYSIZE(frame.Params); i++) {              if (i > 0)                str << ", ";              if (frame.Params[i] != 0)                str << "0x";              str << frame.Params[i];            }            str << setfill(' ') << ')';            if (displacement != 0)              str << " + 0x" << displacement;          }        }        if (frameCount <= 2) {          DWORD e = ::GetLastError();          str << "\n    No stack dump: IMAGEHLP.DLL StackWalk failed: error=" << e;        }      }      else {        DWORD e = ::GetLastError();        str << "\n    No stack dump: IMAGEHLP.DLL GetThreadContext failed: error=" << e;      }      imagehlp.SymCleanup(hProcess);    }    else {      DWORD e = ::GetLastError();      str << "\n    No stack dump: IMAGEHLP.DLL SymInitialise failed: error=" << e;    }  }  else {    DWORD e = ::GetLastError();    str << "\n    No stack dump: IMAGEHLP.DLL could not be loaded: error=" << e;  }#endif  str << ends;  const char * pstr = str.str();  // Unfreeze str so frees memory  str.rdbuf()->freeze(0);  // Must do nothing to str after this or it invalidates pstr  if (PProcess::Current().IsServiceProcess()) {    PSystemLog::Output(PSystemLog::Fatal, pstr);#if defined(_MSC_VER) && defined(_DEBUG)    if (PServiceProcess::Current().debugMode)      __asm int 3;#endif    return;  }#if defined(_WIN32)  static HANDLE mutex = CreateSemaphore(NULL, 1, 1, NULL);  WaitForSingleObject(mutex, INFINITE);#endif  if (PProcess::Current().IsGUIProcess()) {    switch (MessageBox(NULL, pstr, "Portable Windows Library",                              MB_ABORTRETRYIGNORE|MB_ICONHAND|MB_TASKMODAL)) {      case IDABORT :        FatalExit(1);  // Never returns      case IDRETRY :        DebugBreak();    }#if defined(_WIN32)    ReleaseSemaphore(mutex, 1, NULL);#endif    return;  }  for (;;) {    cerr << pstr << "\n<A>bort, <B>reak, <I>gnore? ";    cerr.flush();    switch (cin.get()) {      case 'A' :      case 'a' :        cerr << "Aborted" << endl;        _exit(100);              case 'B' :      case 'b' :        cerr << "Break" << endl;#if defined(_WIN32)        ReleaseSemaphore(mutex, 1, NULL);#endif#ifdef _MSC_VER        __asm int 3;#endif      case 'I' :      case 'i' :      case EOF :        cerr << "Ignored" << endl;#if defined(_WIN32)        ReleaseSemaphore(mutex, 1, NULL);#endif        return;    }  }#else#ifdef _DEBUG    do    { 		if ( AfxAssertFailedLine(file, line) )			AfxDebugBreak();     } while (0);#endif // _DEBUG#endif // _WIN32_WCE}// End Of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -