diff --git a/pykd/dbgevent.cpp b/pykd/dbgevent.cpp
index 0644d59..3817522 100644
--- a/pykd/dbgevent.cpp
+++ b/pykd/dbgevent.cpp
@@ -1,15 +1,18 @@
-///////////////////////////////////////////////////////////////////////////////////
-//// Load/Unload module events
-///////////////////////////////////////////////////////////////////////////////////
-//
+////////////////////////////////////////////////////////////////////////////////
+// User-customizing debug event handler
+////////////////////////////////////////////////////////////////////////////////
+
 #include "stdafx.h"
 #include "dbgevent.h"
 #include "dbgclient.h"
 
+////////////////////////////////////////////////////////////////////////////////
+
+std::wstring fetchPythonExceptionStrings( python::object &tracebackModule );
 
 namespace pykd {
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 EventHandler::EventHandler()
 {
@@ -26,7 +29,7 @@ EventHandler::EventHandler()
      m_parentClient = g_dbgClient;
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 EventHandler::EventHandler( DebugClientPtr  &client )
 {
@@ -43,14 +46,14 @@ EventHandler::EventHandler( DebugClientPtr  &client )
      m_parentClient = client;
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 EventHandler::~EventHandler()
 {
     m_handlerClient->SetEventCallbacks( NULL );
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 HRESULT EventHandler::GetInterestMask(
     __out PULONG Mask
@@ -67,79 +70,24 @@ HRESULT EventHandler::GetInterestMask(
     return S_OK;
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 HRESULT EventHandler::Breakpoint(
     __in PDEBUG_BREAKPOINT Bp
 )
 {
-//    boost::python::dict bpParameters;
-//
-//    HRESULT hres;
-//    ULONG Value = 0;
-//    ULONG Value2 = 0;
-//    ULONG64 Value64 = 0;
-//    std::string str;
-//
-//#define _ADD_BP_ULONG(x)                                        \
-//    hres = Bp->Get##x(&Value);                                  \
-//    BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
-//    if (SUCCEEDED( hres ))                                      \
-//        bpParameters[#x] = Value;
-//
-//#define _ADD_BP_ULONG2(x, n1, n2)                               \
-//    hres = Bp->Get##x(&Value, &Value2);                         \
-//    BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
-//    if (SUCCEEDED( hres ))                                      \
-//    {                                                           \
-//        bpParameters[n1] = Value; bpParameters[n2] = Value2;    \
-//    }
-//
-//#define _ADD_BP_ULONG64(x)                                      \
-//    hres = Bp->Get##x(&Value64);                                \
-//    BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
-//    if (SUCCEEDED( hres ))                                      \
-//        bpParameters[#x] = Value64;
-//
-//#define _ADD_BP_STR(x)                                          \
-//    Value = 0;                                                  \
-//    Bp->Get##x(NULL, 0, &Value);                                \
-//    if (Value)                                                  \
-//    {                                                           \
-//        str.resize(Value + 1);                                  \
-//        BOOST_VERIFY( SUCCEEDED(                                \
-//            Bp->Get##x(&str[0], (ULONG)str.size(), NULL)        \
-//        ) );                                                    \
-//        if (!str.empty()) bpParameters[#x] = str.c_str();       \
-//    }
-//
-//    _ADD_BP_ULONG(Id);
-//    _ADD_BP_ULONG2(Type, "BreakType", "ProcType");
-//    _ADD_BP_ULONG(Flags);
-//    _ADD_BP_ULONG64(Offset);
-//    _ADD_BP_ULONG2(DataParameters, "Size", "AccessType");
-//    _ADD_BP_ULONG(PassCount);
-//    _ADD_BP_ULONG(CurrentPassCount);
-//    _ADD_BP_ULONG(MatchThreadId);
-//    _ADD_BP_STR(Command);
-//    _ADD_BP_STR(OffsetExpression);
-//
-//#undef  _ADD_BP_ULONG
-//#undef  _ADD_BP_ULONG2
-//#undef  _ADD_BP_ULONG64
-//#undef  _ADD_BP_STR
-//
-    //PyThread_StateSave pyThreadSave;
+    ULONG Id;
+    HRESULT hres = Bp->GetId(&Id);
+    if (S_OK == hres)
+    {
+        PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
+        return onBreakpoint(Id);
+    }
 
-    boost::python::dict         bpParameters;
-
-    return onBreakpoint( bpParameters );
-
-    //onException(bpParameters);
-    //return S_OK;
+    return DEBUG_STATUS_NO_CHANGE;
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 HRESULT EventHandler::Exception(
     __in PEXCEPTION_RECORD64 Exception,
@@ -151,7 +99,7 @@ HRESULT EventHandler::Exception(
 
    // build list of parameters
     for (ULONG i = 0; i < Exception->NumberParameters; ++i)
-        exceptParams.append(Exception->ExceptionInformation[i]);
+        exceptParams.append( Exception->ExceptionInformation[i] );
 
     exceptData["Code"] = Exception->ExceptionCode;
     exceptData["Flags"] = Exception->ExceptionFlags;
@@ -165,7 +113,7 @@ HRESULT EventHandler::Exception(
     return onException(exceptData);
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 HRESULT EventHandler::LoadModule(
     __in ULONG64 ImageFileHandle,
@@ -181,7 +129,7 @@ HRESULT EventHandler::LoadModule(
     return onLoadModule( m_parentClient->loadModuleByOffset(BaseOffset) );
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 HRESULT EventHandler::UnloadModule(
     __in PCSTR ImageBaseName,
@@ -193,7 +141,7 @@ HRESULT EventHandler::UnloadModule(
     return onUnloadModule( BaseOffset );
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 HRESULT EventHandler::SessionStatus(
         __in ULONG  Status
@@ -205,7 +153,7 @@ HRESULT EventHandler::SessionStatus(
     return S_OK;
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 HRESULT EventHandler::ChangeDebuggeeState(
         __in ULONG  Flags,
@@ -218,229 +166,14 @@ HRESULT EventHandler::ChangeDebuggeeState(
     return S_OK;
 }
 
-///////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+void EventHandlerWrap::onHandlerException()
+{
+    // TODO: some logging, alerting....
+}
+
+////////////////////////////////////////////////////////////////////////////////
 
 
 }; // end pykd namespace
-
-
-
-
-
-
-
-
-
-
-//#include "dbgevent.h"
-//#include "dbgio.h"
-//#include "dbgexcept.h"
-//#include "pyaux.h"
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
-//debugEvent::debugEvent()
-//{
-//     HRESULT    hres;
-//    
-//     hres = dbgExt->client->CreateClient( &m_debugClient );
-//     if ( FAILED( hres ) )
-//        throw DbgException( "IDebugClient::CreateClient" );    
-//     
-//     hres = m_debugClient->SetEventCallbacks(this);
-//     if (FAILED(hres))
-//        throw DbgException( "IDebugClient::SetEventCallbacks" );      
-//}
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
-//debugEvent::~debugEvent()
-//{
-//    m_debugClient->SetEventCallbacks( NULL );
-//    
-//    m_debugClient->Release();
-//}
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
-//HRESULT debugEvent::GetInterestMask(
-//    __out PULONG Mask
-//)    
-//{
-//    *Mask = 0;
-//
-//    *Mask |= DEBUG_EVENT_LOAD_MODULE;
-//    *Mask |= DEBUG_EVENT_UNLOAD_MODULE;
-//    *Mask |= DEBUG_EVENT_SESSION_STATUS;
-//    *Mask |= DEBUG_EVENT_EXCEPTION;
-//    *Mask |= DEBUG_EVENT_BREAKPOINT;
-//
-//    return S_OK;
-//}
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
-//HRESULT debugEvent::Breakpoint(
-//    __in PDEBUG_BREAKPOINT Bp
-//)
-//{
-//    boost::python::dict bpParameters;
-//
-//    HRESULT hres;
-//    ULONG Value = 0;
-//    ULONG Value2 = 0;
-//    ULONG64 Value64 = 0;
-//    std::string str;
-//
-//#define _ADD_BP_ULONG(x)                                        \
-//    hres = Bp->Get##x(&Value);                                  \
-//    BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
-//    if (SUCCEEDED( hres ))                                      \
-//        bpParameters[#x] = Value;
-//
-//#define _ADD_BP_ULONG2(x, n1, n2)                               \
-//    hres = Bp->Get##x(&Value, &Value2);                         \
-//    BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
-//    if (SUCCEEDED( hres ))                                      \
-//    {                                                           \
-//        bpParameters[n1] = Value; bpParameters[n2] = Value2;    \
-//    }
-//
-//#define _ADD_BP_ULONG64(x)                                      \
-//    hres = Bp->Get##x(&Value64);                                \
-//    BOOST_ASSERT( SUCCEEDED( hres ) || hres == E_NOINTERFACE ); \
-//    if (SUCCEEDED( hres ))                                      \
-//        bpParameters[#x] = Value64;
-//
-//#define _ADD_BP_STR(x)                                          \
-//    Value = 0;                                                  \
-//    Bp->Get##x(NULL, 0, &Value);                                \
-//    if (Value)                                                  \
-//    {                                                           \
-//        str.resize(Value + 1);                                  \
-//        BOOST_VERIFY( SUCCEEDED(                                \
-//            Bp->Get##x(&str[0], (ULONG)str.size(), NULL)        \
-//        ) );                                                    \
-//        if (!str.empty()) bpParameters[#x] = str.c_str();       \
-//    }
-//
-//    _ADD_BP_ULONG(Id);
-//    _ADD_BP_ULONG2(Type, "BreakType", "ProcType");
-//    _ADD_BP_ULONG(Flags);
-//    _ADD_BP_ULONG64(Offset);
-//    _ADD_BP_ULONG2(DataParameters, "Size", "AccessType");
-//    _ADD_BP_ULONG(PassCount);
-//    _ADD_BP_ULONG(CurrentPassCount);
-//    _ADD_BP_ULONG(MatchThreadId);
-//    _ADD_BP_STR(Command);
-//    _ADD_BP_STR(OffsetExpression);
-//
-//#undef  _ADD_BP_ULONG
-//#undef  _ADD_BP_ULONG2
-//#undef  _ADD_BP_ULONG64
-//#undef  _ADD_BP_STR
-//
-//    PyThread_StateSave pyThreadSave;
-//    return onException(bpParameters);
-//}
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
-//HRESULT debugEvent::Exception(
-//    __in PEXCEPTION_RECORD64 Exception,
-//    __in ULONG FirstChance
-//)
-//{
-//    boost::python::list exceptParams;
-//    boost::python::dict exceptData;
-//
-//    // build list of parameters
-//    for (ULONG i = 0; i < Exception->NumberParameters; ++i)
-//        exceptParams.append(Exception->ExceptionInformation[i]);
-//
-//    // build dict of exception data
-//#define _ADD_EXCEPTION_ENTRY(x) exceptData[#x] = Exception->Exception##x
-//    _ADD_EXCEPTION_ENTRY(Code);
-//    _ADD_EXCEPTION_ENTRY(Flags);
-//    _ADD_EXCEPTION_ENTRY(Record);
-//    _ADD_EXCEPTION_ENTRY(Address);
-//#undef  _ADD_EXCEPTION_ENTRY
-//
-//    exceptData["Parameters"] = exceptParams;
-//
-//    exceptData["FirstChance"] = (0 != FirstChance);
-//
-//    PyThread_StateSave pyThreadSave;
-//    return onException(exceptData);
-//}
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
-//HRESULT debugEvent::LoadModule(
-//    __in ULONG64 ImageFileHandle,
-//    __in ULONG64 BaseOffset,
-//    __in ULONG ModuleSize,
-//    __in PCSTR ModuleName,
-//    __in PCSTR ImageName,
-//    __in ULONG CheckSum,
-//    __in ULONG TimeDateStamp
-//)
-//{
-//    std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
-//
-//    ULONG64         moduleBase;
-//    ULONG           moduleSize;
-//    std::string     moduleName;       
-//    
-//    queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
-//    dbgModuleClass module(moduleName, moduleBase, moduleSize);
-//    silentMode.reset(); 
-//
-//    PyThread_StateSave pyThreadSave;
-//    return onLoadModule( module );
-//}
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
-//HRESULT debugEvent::UnloadModule(
-//    __in PCSTR ImageBaseName,
-//    __in ULONG64 BaseOffset
-//)
-//{
-//    std::auto_ptr<OutputReader> silentMode( new OutputReader(dbgExt->client) );
-//
-//    ULONG64         moduleBase;
-//    ULONG           moduleSize;
-//    std::string     moduleName;       
-//    
-//    queryModuleParams(BaseOffset, moduleName, moduleBase, moduleSize);
-//    dbgModuleClass module(moduleName, moduleBase, moduleSize);
-//    silentMode.reset(); 
-//
-//    PyThread_StateSave pyThreadSave;
-//    return onUnloadModule( module );
-//}
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
-//HRESULT debugEvent::SessionStatus(
-//        __in ULONG  Status
-//)
-//{
-//    PyThread_StateSave pyThreadSave;
-//    return onChangeSessionStatus( Status );
-//}
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
-//HRESULT debugEvent::ChangeDebuggeeState(
-//        __in ULONG  Flags,
-//        __in ULONG64 Argument
-//)
-//{
-//    PyThread_StateSave pyThreadSave;
-//    return onChangeDebugeeState();
-//}
-//
-/////////////////////////////////////////////////////////////////////////////////////
-//
diff --git a/pykd/dbgevent.h b/pykd/dbgevent.h
index d20a127..b8d1a18 100644
--- a/pykd/dbgevent.h
+++ b/pykd/dbgevent.h
@@ -1,6 +1,6 @@
-/////////////////////////////////////////////////////////////////////////////////
-//  user-customizing debug event handler
-/////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+// User-customizing debug event handler
+////////////////////////////////////////////////////////////////////////////////
 
 #pragma once
 
@@ -13,7 +13,7 @@
 
 namespace pykd {
 
-/////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 class EventHandler : public DebugBaseEventCallbacks
 {
@@ -69,7 +69,7 @@ protected:
 
 protected:
 
-    virtual ULONG onBreakpoint(const python::dict &/*bpParameters*/) = 0;
+    virtual ULONG onBreakpoint(ULONG Id) = 0;
 
     virtual ULONG onException(const python::dict &/*exceptData*/) = 0;
 
@@ -88,7 +88,7 @@ protected:
     DebugClientPtr              m_parentClient;
 };
 
-/////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 class EventHandlerWrap : public python::wrapper<EventHandler>, public EventHandler
 {
@@ -101,8 +101,8 @@ public:
     EventHandlerWrap( DebugClientPtr  &client ) : EventHandler( client )
     {}
 
-    ULONG onBreakpoint(const python::dict &bpParameters) {
-        return handler<const python::dict&>("onBreakpoint", bpParameters);
+    ULONG onBreakpoint(ULONG Id) {
+        return handler("onBreakpoint", Id);
     }
 
     ULONG onException(const python::dict &exceptData) {
@@ -125,163 +125,41 @@ public:
         return handler( "onChangeDebugeeState" );
     }
 
+    void onHandlerException();
+
 private:
 
     template<typename Arg1Type>
     ULONG handler( const char* handlerName, Arg1Type  arg1 )
     {
         if (python::override pythonHandler = get_override( handlerName ))
-            return pythonHandler(arg1);
-
+        {
+            try {
+                return pythonHandler(arg1);
+            }
+            catch (const python::error_already_set &)  {
+                onHandlerException();
+            }
+        }
         return DEBUG_STATUS_NO_CHANGE;
     }
 
     ULONG handler( const char* handlerName )
     {
         if (python::override pythonHandler = get_override( handlerName ))
-            return pythonHandler();
+        {
+            try {
+                return pythonHandler();
+            }
+            catch (const python::error_already_set &) {
+                onHandlerException();
+            }
+        }
 
         return DEBUG_STATUS_NO_CHANGE;
     }
 }; 
 
-/////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
 
 }; // end namespace pykd
-
-
-
-
-
-
-
-
-
-
-
-
-//#include "dbgeventcb.h"
-//#include "dbgmodule.h"
-//#include "pyaux.h"
-//
-///////////////////////////////////////////////////////////////////////////////////
-//
-//class debugEvent : public DebugBaseEventCallbacks
-//{
-//public:
-//
-//    debugEvent();
-//
-//    virtual ~debugEvent();
-//
-//    virtual ULONG onBreakpoint(boost::python::dict &/*bpParameters*/) = 0;
-//
-//    virtual ULONG onException(boost::python::dict &/*exceptData*/) = 0;
-//
-//    virtual ULONG onLoadModule(const dbgModuleClass &/* module */)  = 0;
-//
-//    virtual ULONG onUnloadModule(const dbgModuleClass &/* module */)  = 0;
-//    
-//    virtual ULONG onChangeSessionStatus( ULONG status ) = 0;
-//    
-//    virtual ULONG onChangeDebugeeState() = 0;
-//    
-//private:
-//
-//    STDMETHOD_(ULONG, AddRef)() { return 1; }
-//    STDMETHOD_(ULONG, Release)() { return 1; }
-//
-//    STDMETHOD(GetInterestMask)(
-//        __out PULONG Mask
-//    );
-//
-//    STDMETHOD(Breakpoint)(
-//        __in PDEBUG_BREAKPOINT Bp
-//    );
-//
-//
-//    STDMETHOD(Exception)(
-//        __in PEXCEPTION_RECORD64 Exception,
-//        __in ULONG FirstChance
-//    );
-//
-//    STDMETHOD(LoadModule)(
-//        __in ULONG64 ImageFileHandle,
-//        __in ULONG64 BaseOffset,
-//        __in ULONG ModuleSize,
-//        __in PCSTR ModuleName,
-//        __in PCSTR ImageName,
-//        __in ULONG CheckSum,
-//        __in ULONG TimeDateStamp
-//    );
-//
-//    STDMETHOD(UnloadModule)(
-//        __in PCSTR ImageBaseName,
-//        __in ULONG64 BaseOffset
-//    );  
-//
-//    STDMETHOD(SessionStatus)(
-//        __in ULONG  Status
-//    );
-//
-//    STDMETHOD(ChangeDebuggeeState)(
-//        __in ULONG  Flags,
-//        __in ULONG64 Argument );
-//
-//private:
-//
-//    IDebugClient       *m_debugClient;
-//};
-//
-///////////////////////////////////////////////////////////////////////////////////
-//
-//class debugEventWrap : public boost::python::wrapper<debugEvent>, public debugEvent
-//{
-//
-//public:
-//
-//    ULONG onBreakpoint(boost::python::dict &bpParameters) {
-//        return handler<boost::python::dict &>("onBreakpoint", bpParameters);
-//    }
-//
-//    ULONG onException(boost::python::dict &exceptData) {
-//        return handler<boost::python::dict &>("onException", exceptData);
-//    }
-//
-//    ULONG onLoadModule(const dbgModuleClass &module) {
-//        return handler<const dbgModuleClass &>("onLoadModule", module );
-//    }
-//
-//    ULONG onUnloadModule(const dbgModuleClass &module) {
-//        return handler<const dbgModuleClass &>("onUnloadModule", module );
-//    }
-//
-//    ULONG onChangeSessionStatus( ULONG status ) {
-//        return handler( "onChangeSessionStatus", status );
-//    }
-//
-//    ULONG onChangeDebugeeState() {
-//        return handler( "onChangeDebugeeState" );
-//    }
-//
-//private:
-//
-//    template<typename Arg1Type>
-//    ULONG handler( const char* handlerName, Arg1Type  arg1 )
-//    {
-//        if (boost::python::override pythonHandler = get_override( handlerName ))
-//            return pythonHandler(arg1);
-//
-//        return DEBUG_STATUS_NO_CHANGE;
-//    }
-//
-//    ULONG handler( const char* handlerName )
-//    {
-//        if (boost::python::override pythonHandler = get_override( handlerName ))
-//            return pythonHandler();
-//
-//        return DEBUG_STATUS_NO_CHANGE;
-//    }
-//};
-//
-///////////////////////////////////////////////////////////////////////////////////
diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index d47a17b..f10a4c3 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -569,11 +569,7 @@ BOOST_PYTHON_MODULE( pykd )
         .def( python::init<>() )
         .def( python::init<DebugClientPtr&>() )
         .def( "onBreakpoint", &pykd::EventHandlerWrap::onBreakpoint,
-            "Triggered breakpoint event. Parameter is dict:\n"
-            "{\"Id\":int, \"BreakType\":int, \"ProcType\":int, \"Flags\":int, \"Offset\":int,"
-            " \"Size\":int, \"AccessType\":int, \"PassCount\":int, \"CurrentPassCount\":int,"
-            " \"MatchThreadId\":int, \"Command\":str, \"OffsetExpression\":str}\n"
-            "Detailed information: http://msdn.microsoft.com/en-us/library/ff539284(VS.85).aspx \n"
+            "Triggered breakpoint event. Parameter is int: ID of breakpoint\n"
             "For ignore event method must return DEBUG_STATUS_NO_CHANGE value" )
         .def( "onException", &pykd::EventHandlerWrap::onException,
             "Exception event. Parameter is dict:\n"
@@ -837,6 +833,30 @@ BOOST_PYTHON_MODULE( pykd )
     DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_SMALL_DUMP );
     DEF_PY_CONST_ULONG( DEBUG_USER_WINDOWS_DUMP );
 
+    // exception codes
+    DEF_PY_CONST_ULONG(EXCEPTION_ACCESS_VIOLATION);
+    DEF_PY_CONST_ULONG(EXCEPTION_DATATYPE_MISALIGNMENT);
+    DEF_PY_CONST_ULONG(EXCEPTION_BREAKPOINT);
+    DEF_PY_CONST_ULONG(EXCEPTION_SINGLE_STEP);
+    DEF_PY_CONST_ULONG(EXCEPTION_ARRAY_BOUNDS_EXCEEDED);
+    DEF_PY_CONST_ULONG(EXCEPTION_FLT_DENORMAL_OPERAND);
+    DEF_PY_CONST_ULONG(EXCEPTION_FLT_DIVIDE_BY_ZERO);
+    DEF_PY_CONST_ULONG(EXCEPTION_FLT_INEXACT_RESULT);
+    DEF_PY_CONST_ULONG(EXCEPTION_FLT_INVALID_OPERATION);
+    DEF_PY_CONST_ULONG(EXCEPTION_FLT_OVERFLOW);
+    DEF_PY_CONST_ULONG(EXCEPTION_FLT_STACK_CHECK);
+    DEF_PY_CONST_ULONG(EXCEPTION_FLT_UNDERFLOW);
+    DEF_PY_CONST_ULONG(EXCEPTION_INT_DIVIDE_BY_ZERO);
+    DEF_PY_CONST_ULONG(EXCEPTION_INT_OVERFLOW);
+    DEF_PY_CONST_ULONG(EXCEPTION_PRIV_INSTRUCTION);
+    DEF_PY_CONST_ULONG(EXCEPTION_IN_PAGE_ERROR);
+    DEF_PY_CONST_ULONG(EXCEPTION_ILLEGAL_INSTRUCTION);
+    DEF_PY_CONST_ULONG(EXCEPTION_NONCONTINUABLE_EXCEPTION);
+    DEF_PY_CONST_ULONG(EXCEPTION_STACK_OVERFLOW);
+    DEF_PY_CONST_ULONG(EXCEPTION_INVALID_DISPOSITION);
+    DEF_PY_CONST_ULONG(EXCEPTION_GUARD_PAGE);
+    DEF_PY_CONST_ULONG(EXCEPTION_INVALID_HANDLE);
+
     // debug status
     DEF_PY_CONST_ULONG(DEBUG_STATUS_NO_CHANGE);
     DEF_PY_CONST_ULONG(DEBUG_STATUS_GO);
@@ -859,30 +879,30 @@ BOOST_PYTHON_MODULE( pykd )
 ////////////////////////////////////////////////////////////////////////////////
 
 WindbgGlobalSession::WindbgGlobalSession() {
-                 
+
     PyImport_AppendInittab("pykd", initpykd ); 
 
     PyEval_InitThreads();
 
-    Py_Initialize();    
+    Py_Initialize();
 
     main = boost::python::import("__main__");
-    
+
     python::object   main_namespace = main.attr("__dict__");
 
-    // ������ ������ from pykd import *        
+    // ������ ������ from pykd import *
     python::object   pykd = boost::python::import( "pykd" );
-    
+
     python::dict     pykd_namespace( pykd.attr("__dict__") ); 
-    
+
     python::list     iterkeys( pykd_namespace.iterkeys() );
-    
+
     for (int i = 0; i < boost::python::len(iterkeys); i++)
     {
         std::string     key = boost::python::extract<std::string>(iterkeys[i]);
-               
+
         main_namespace[ key ] = pykd_namespace[ key ];
-    }   
+    }
 
     pyState = PyEval_SaveThread();
 }
@@ -941,23 +961,23 @@ py( PDEBUG_CLIENT4 client, PCSTR args )
         // ����������� ����/����� ( ����� � ������� ����� ���� ������ print )
 
         python::object       sys = python::import("sys");
-       
+
         sys.attr("stdout") = python::object( dbgClient->dout() );
         sys.attr("stderr") = python::object( dbgClient->dout() );
         sys.attr("stdin") = python::object( dbgClient->din() );
 
         // ����������� ������ ��������� ���������� ( ����� ��� ������ traceback � )
         boost::python::object       tracebackModule = python::import("traceback");
-        
+
         // ������ ����������
         typedef  boost::escaped_list_separator<char>    char_separator_t;
         typedef  boost::tokenizer< char_separator_t >   char_tokenizer_t;  
-        
+
         std::string                 argsStr( args );
-        
+
         char_tokenizer_t            token( argsStr , char_separator_t( "", " \t", "\"" ) );
         std::vector<std::string>    argsList;
-        
+
         for ( char_tokenizer_t::iterator   it = token.begin(); it != token.end(); ++it )
         {
             if ( *it != "" )
@@ -971,31 +991,31 @@ py( PDEBUG_CLIENT4 client, PCSTR args )
      
         for ( size_t  i = 0; i < argsList.size(); ++i )
             pythonArgs[i] = const_cast<char*>( argsList[i].c_str() );
-            
+
         PySys_SetArgv( (int)argsList.size(), pythonArgs );
 
-        delete[]  pythonArgs;       
+        delete[]  pythonArgs;
 
        // ����� ���� � �����
         std::string     fullScriptName;
-        DbgPythonPath   dbgPythonPath;        
+        DbgPythonPath   dbgPythonPath;
         
         if ( !dbgPythonPath.getFullFileName( argsList[0], fullScriptName ) )
         {
-            dbgClient->eprintln( L"script file not found" );            
+            dbgClient->eprintln( L"script file not found" );
         }
         else
-        try {             
-      
+        try {
+
             python::object       result;
-    
+
             result =  python::exec_file( fullScriptName.c_str(), global, global );
-        }                
+        }
         catch( boost::python::error_already_set const & )
         {
             // ������ � �������
             PyObject    *errtype = NULL, *errvalue = NULL, *traceback = NULL;
-            
+
             PyErr_Fetch( &errtype, &errvalue, &traceback );
 
             PyErr_NormalizeException( &errtype, &errvalue, &traceback );
@@ -1013,15 +1033,14 @@ py( PDEBUG_CLIENT4 client, PCSTR args )
 
             for ( long i = 0; i < python::len(lst); ++i )
                 sstr << std::wstring( python::extract<std::wstring>(lst[i]) ) << std::endl;
-
             dbgClient->eprintln( sstr.str() );
-        }  
+        }
 
     }
     catch(...)
-    {      
+    {
         dbgClient->eprintln( L"unexpected error" );
-    }    
+    }
 
     Py_EndInterpreter( localInterpreter ); 
     PyThreadState_Swap( globalInterpreter );
diff --git a/test/scripts/ehexcepttest.py b/test/scripts/ehexcepttest.py
new file mode 100644
index 0000000..8d8cb52
--- /dev/null
+++ b/test/scripts/ehexcepttest.py
@@ -0,0 +1,65 @@
+"""Debug events handler: test exceptions and debug breaks"""
+
+import unittest
+import target
+import pykd
+
+class BreakExceptionHandler(pykd.eventHandler):
+    """Track load/unload module implementation"""
+    def __init__(self, client):
+        pykd.eventHandler.__init__(self, client)
+
+        self.client = client
+
+        self.wasSecondChance = False
+
+        self.wasBreakpoint = False
+
+        self.bpLastModuleName = ""
+        self.bpCount = 0
+
+        self.firstChanceAccessAddresses = []
+        self.secondChanceAccessAddresses = []
+
+    def onBreakpoint(self, bpId):
+        """Breakpoint handler"""
+        self.wasBreakpoint = True
+        return pykd.DEBUG_STATUS_NO_CHANGE
+
+    def onException(self, exceptParams):
+        """Exception handler"""
+
+        self.wasSecondChance = not exceptParams["FirstChance"]
+
+        if exceptParams["Code"] == pykd.EXCEPTION_ACCESS_VIOLATION:
+            if self.wasSecondChance:
+                print exceptParams["Parameters"]
+                self.secondChanceAccessAddresses.append( exceptParams["Parameters"][1] )
+            else:
+                self.firstChanceAccessAddresses.append( exceptParams["Parameters"][1] )
+        elif exceptParams["Code"] == pykd.EXCEPTION_BREAKPOINT:
+            self.bpCount += 1
+
+        return pykd.DEBUG_STATUS_BREAK if self.wasSecondChance else pykd.DEBUG_STATUS_NO_CHANGE
+
+class EhExceptionBreakpointTest(unittest.TestCase):
+    """Unit tests of exceptions end breakpoint handling"""
+
+    def testBreakpointException(self):
+        """Start new process and track exceptions/breakpoints"""
+        testClient = pykd.createDbgClient()
+        testClient.startProcess( target.appPath + " -testExceptions" )
+
+        testClient.dbgCommand( ".reload /f; bp targetapp!doExeptions" )
+
+        breakExceptionHandler = BreakExceptionHandler( testClient )
+        while not breakExceptionHandler.wasSecondChance:
+            testClient.go()
+
+        self.assertTrue( breakExceptionHandler.wasBreakpoint )
+
+        self.assertEqual( [2, 3], breakExceptionHandler.firstChanceAccessAddresses  )
+
+        self.assertEqual( 2, breakExceptionHandler.bpCount ) # main and doExeptions
+
+        self.assertEqual( [3, ], breakExceptionHandler.secondChanceAccessAddresses )
diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py
index ae731de..18bc71f 100644
--- a/test/scripts/pykdtest.py
+++ b/test/scripts/pykdtest.py
@@ -26,6 +26,7 @@ import synsymtest
 import ehloadtest
 import thrdctxtest
 import localstest
+import ehexcepttest
 
 def getTestSuite( singleName = "" ):
     if singleName == "":
@@ -43,7 +44,8 @@ def getTestSuite( singleName = "" ):
                unittest.TestLoader().loadTestsFromTestCase( synsymtest.SynSymTest ),
                unittest.TestLoader().loadTestsFromTestCase( thrdctxtest.ThreadContextTest ),
                unittest.TestLoader().loadTestsFromTestCase( ehloadtest.EhLoadTest ),
-               unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest )
+               unittest.TestLoader().loadTestsFromTestCase( localstest.LocalVarsTest ),
+               unittest.TestLoader().loadTestsFromTestCase( ehexcepttest.EhExceptionBreakpointTest )
            ] ) 
     else:
        return unittest.TestSuite( unittest.TestLoader().loadTestsFromName( singleName ) )
@@ -73,4 +75,4 @@ if __name__ == "__main__":
 
     unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( suite )
 
-    #raw_input("\npress return\n")
+    # raw_input("\npress return\n")
diff --git a/test/targetapp/targetapp.vcproj b/test/targetapp/targetapp.vcproj
index d726ee9..a03833a 100644
--- a/test/targetapp/targetapp.vcproj
+++ b/test/targetapp/targetapp.vcproj
@@ -416,6 +416,10 @@
 				RelativePath="..\scripts\diatest.py"
 				>
 			</File>
+			<File
+				RelativePath="..\scripts\ehexcepttest.py"
+				>
+			</File>
 			<File
 				RelativePath="..\scripts\ehloadtest.py"
 				>