Index: trunk/src/tools/qsysxcpt_pm.cpp
===================================================================
--- trunk/src/tools/qsysxcpt_pm.cpp	(revision 150)
+++ trunk/src/tools/qsysxcpt_pm.cpp	(revision 151)
@@ -61,10 +61,137 @@
 /** @class QtOS2SysXcptMainHandler qt_os2.h
  *
- *  @todo (r=dmik) describe...
+ *  The QtOS2SysXcptMainHandler class is used to install the OS2/ system
+ *  exception handler on the main thread of the Qt application.
  *
- *  - must be instantiated on the stack of the main thread only
- *  - should be instantiated before a QAplication instance is created
- *    (does nothing otherwise)
- *  - note that callback can be called on any thread
+ *  The installed exception handler will catch most fatal exceptions (commonly
+ *  referred to as traps), such as memory access violation, and create a
+ *  detailed report about the state of the failed application (process name,
+ *  loaded modules, thread states and call stacks). The created report is saved
+ *  in the user home directory and is supposed to be sent to the application
+ *  developer (which makes it much easier to find a reason of the trap and
+ *  therefore gives a better chance that the problem will be fixed).
+ *
+ *  In order to install the exception handler, an instance of this class is
+ *  created on the stack of the main thread. The best place for it is the
+ *  first line of the application's main() function, before doing anything else.
+ *  One doesn't need (and <b>should not</b>) create a QApplication instance
+ *  before installing the exception handler. If you do so, then QApplication
+ *  will install the same exception handler on its own, which is not a preferred
+ *  way for two reasons:
+ *  <ul>
+ *  <li>QApplication uses a hack to attach the exception handler to the
+ *      exception handler installed by the compiler's C Library (LIBC). This
+ *      hack will not work if there is no exception handler provided by LIBC
+ *      or it may work incorrectly if there are other exception handlers
+ *      installed after it using the same (or similar hack).
+ *  <li>There is no way to specify the exception handler callback (see below).
+ *  </ul>
+ *
+ *  There may be only one instance of this class and it must be created only on
+ *  the main (UI) thread. All other threads started by Qt using the QThread
+ *  class will have the exception handler installed authomatically before the
+ *  QThread::run() method starts execution, so there is no need to install it
+ *  explicitly.
+ *
+ *  Note that QtOS2SysXcptMainHandler is a stack-based class, which means that
+ *  you cannot create an instance using the new operator (you will get a
+ *  compile time error). You might want to create it as a static variable (for
+ *  example, if you want to catch exceptions happening before main() is entered,
+ *  such as initialization of other static variables), however this is not
+ *  currently supported and may work incorrectly because the OS/2 system
+ *  documentation clearly states that the exception handler data must be
+ *  allocated on the stack. Here is a typical usage pattern for installing the
+ *  exception handler:
+ *
+ *  \code
+ *  int main (int argc, char **argv)
+ *  {
+ *      QtOS2SysXcptMainHandler sysXcptHandler( psiOS2SysXcptCallback );
+ *
+ *      QApplication app;
+ *      MyWidget wgt;
+ *      app.setMainWidget (&wgt);
+ *      wgt.show();
+ *      return app.exec(); 
+ *  }
+ *  \endcode
+ *
+ *  The exception report is an XML file with the well-defined structure and
+ *  contains enough information to find symbols corresponding to execution
+ *  points on the call stack (provided that there is a .SYM file for a program
+ *  or a library module). This file is always created in the SysTraps
+ *  subdirectory of the user's home directory (or of the root directory of the
+ *  boot drive if no home directory exists). Currently there is no way to
+ *  specify a different location. A separate report file is created per every
+ *  trap.
+ *
+ *  In order to store application-specific information in the report file,
+ *  an application can install the exception handler callback that is
+ *  called at certain points during exception handling. This callback is
+ *  specified as an argument to the QtOS2SysXcptMainHandler constructor, but
+ *  it will be called on any Qt thread that caught an exception, not
+ *  necessarily the main one.
+ *
+ *  The callback function has the following prototype:
+ *  \code
+ *  int XcptCallback( QtOS2SysXcptReq req, QtOS2SysXcptWriter writer, int reserved );
+ *  \endcode
+ *  \a req is one of the QtOS2SysXcptReq values describing what type of
+ *  information the exception handler wants to get from the callback, \a writer
+ *  is the function used by the callback to write the requested information to
+ *  the report file and \a reserved is a reserved value which is currently
+ *  always zero.
+ *
+ *  The callback can be called by the exception handler in two modes: \em ask
+ *  mode or \em let mode. In the "ask" mode (indicated by the NULL \a writer
+ *  argument), the handler asks whether the callback supports the requested
+ *  bit of information, as defined by the \a req argument. In the "let" mode
+ *  (where \a writer is not NULL), it lets the callback to write the requested
+ *  information to the report file using the supplied \a writer. Note that the
+ *  callback should not deal with any structural report details (such as XML
+ *  tags or character escaping) -- the string it writes is just an arbitrary
+ *  character value for the requested attribute. The meaning of different
+ *  QtOS2SysXcptReq values can be easily explained with an example: 
+ *
+ *  \code
+    QString PROG_NAME = "MyApp";
+    QString PROG_VERSION = "0.1";
+ 
+    int psiOS2SysXcptCallback( QtOS2SysXcptReq req, QtOS2SysXcptWriter writer, int )
+    {
+        switch( req )
+        {
+            // application name
+            case QtOS2SysXcptReq_AppName:
+                if ( writer ) writer( PROG_NAME.latin1() );
+                return TRUE;
+
+            // application version
+            case QtOS2SysXcptReq_AppVer:
+                if ( writer ) writer( PROG_VERSION.latin1() );
+                return TRUE;
+
+            // e-mail to send generated trap reports to
+            // (can be used by trap report handling utilities to assist the
+            // user to compose and send trap reports to the developer) 
+            case QtOS2SysXcptReq_ReportTo:
+                if ( writer ) writer( "my-traps@some.where" );
+                return TRUE;
+
+            // recommended subject of the generated e-mail message  
+            // (same purpose as above) 
+            case QtOS2SysXcptReq_ReportSubj:
+                // we don't need to provide this kind of information,
+                // so simply return FALSE
+                return TRUE;
+
+            default:
+                break;
+        }
+
+        // we don't support any other information requests
+        return FALSE;
+    }
+ *  \endcode
  */
 
@@ -75,5 +202,7 @@
 
 /**
- *  @todo (r=dmik) describe...        
+ *  Installs the exception handler on the main thread and registers \a cb
+ *  as the exception handler callback. If \a cb is NULL (by default), then no
+ *  user-supplied exception callback will be registered.
  */
 QtOS2SysXcptMainHandler::QtOS2SysXcptMainHandler (QtOS2SysXcptCallback cb)
@@ -108,5 +237,5 @@
 
 /**
- *  @todo (r=dmik) describe...        
+ *  Uninstalls the exception handler installed by the constructor.        
  */
 QtOS2SysXcptMainHandler::~QtOS2SysXcptMainHandler()
@@ -942,5 +1071,5 @@
 
     char szFileName[CCHMAXPATH];
-    char szDir[] = "\\.systrap";
+    char szDir[] = "\\SysTraps";
     char szFile[] = "\\12345678.123";
     enum { cbFileName = sizeof(szFileName) };
@@ -1082,4 +1211,5 @@
         case XCPT_INVALID_LOCK_SEQUENCE:
         case XCPT_INTEGER_OVERFLOW:
+        case XCPT_BREAKPOINT:
         {
             /* "real" exceptions: */
