Example #1
0
HRESULT
CALLBACK
DebugExtensionInitialize(PULONG Version, PULONG Flags)
{
    IDebugClient *DebugClient = NULL;
    HRESULT Hr= S_OK;

    *Version = DEBUG_EXTENSION_VERSION(1, 0);
    *Flags = 0;

    // Connect to client
    if ((Hr = DebugCreate(__uuidof(IDebugClient),
                          (void **)&DebugClient)) != S_OK)
    {
        return Hr;
    }

    // Get the windbg-style extension APIS
    PDEBUG_CONTROL DebugControl;
    if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
                                          (void **)&DebugControl)) == S_OK)
    {
        ExtensionApis.nSize = sizeof (ExtensionApis);
        Hr = DebugControl->GetWindbgExtensionApis64(&ExtensionApis);

        DebugControl->Release();
    }

    // done
    DebugClient->Release();
    return Hr;
}
Example #2
0
static bool openDumpFile(JNIEnv* env, jobject obj, jstring coreFileName) {
  // open the dump file
  jboolean isCopy;
  const char* buf = env->GetStringUTFChars(coreFileName, &isCopy);
  CHECK_EXCEPTION_(false);
  AutoJavaString coreFile(env, coreFileName, buf);
  if (setImageAndSymbolPath(env, obj) == false) {
     return false;
  }

  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,
                                                      ptrIDebugClient_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugClient->OpenDumpFile(coreFile) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: OpenDumpFile failed!", false);
  }

  IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj,
                                                     ptrIDebugControl_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false);
  }

  return true;
}
Example #3
0
/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    detach0
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_detach0
  (JNIEnv *env, jobject obj) {
  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,
                                                      ptrIDebugClient_ID);
  CHECK_EXCEPTION;
  ptrIDebugClient->DetachProcesses();
  releaseWindbgInterfaces(env, obj);
}
Example #4
0
void
CALLBACK
DebugExtensionNotify(ULONG Notify, ULONG64 Argument)
{
    UNREFERENCED_PARAMETER(Argument);

    //
    // The first time we actually connect to a target
    //
	/*
	 *New debugger extensions get new debugger interfaces by calling
	 *DebugCreate(__uuidof (IDebugClient), &DebugClient))
	 *DebugClient->QueryInterface(_uuidof(Interface_you_want)
	*/ 
    if ((Notify == DEBUG_NOTIFY_SESSION_ACCESSIBLE) && (!Connected))
    {
        IDebugClient *DebugClient;
        HRESULT Hr;
        PDEBUG_CONTROL DebugControl;

        if ((Hr = DebugCreate(__uuidof(IDebugClient),
                              (void **)&DebugClient)) == S_OK)
        {
            //
            // Get the architecture type.
            //

            if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
                                       (void **)&DebugControl)) == S_OK)
            {
				//jc:QueryInterface must fill in DebugControl
                if ((Hr = DebugControl->GetActualProcessorType(
                                             &TargetMachine)) == S_OK)
                {
                    Connected = TRUE;
                }


                DebugControl->Release();
            }

            DebugClient->Release();
        }
    }


    if (Notify == DEBUG_NOTIFY_SESSION_INACTIVE)
    {
        Connected = FALSE;
        TargetMachine = 0;
    }

    return;
}
Example #5
0
static bool releaseWindbgInterfaces(JNIEnv* env, jobject obj) {
  IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj,
                                                      ptrIDebugDataSpaces_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugDataSpaces != 0) {
     ptrIDebugDataSpaces->Release();
  }

  IDebugOutputCallbacks* ptrIDebugOutputCallbacks = (IDebugOutputCallbacks*)
                          env->GetLongField(obj, ptrIDebugOutputCallbacks_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugOutputCallbacks != 0) {
     ptrIDebugOutputCallbacks->Release();
  }

  IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj,
                                                      ptrIDebugAdvanced_ID);
  CHECK_EXCEPTION_(false);

  if (ptrIDebugAdvanced != 0) {
     ptrIDebugAdvanced->Release();
  }

  IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,
                                                      ptrIDebugSymbols_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugSymbols != 0) {
     ptrIDebugSymbols->Release();
  }

  IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj,
                                                      ptrIDebugSystemObjects_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugSystemObjects != 0) {
     ptrIDebugSystemObjects->Release();
  }

  IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj,
                                                     ptrIDebugControl_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugControl != 0) {
     ptrIDebugControl->Release();
  }

  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,
                                                      ptrIDebugClient_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugClient != 0) {
     ptrIDebugClient->Release();
  }

  return true;
}
Example #6
0
void
CALLBACK
DebugExtensionNotify(ULONG Notify, ULONG64 Argument)
{
    static BOOL    Connected;

    UNREFERENCED_PARAMETER(Argument);

    // The first time we actually connect to a target
    if ((Notify == DEBUG_NOTIFY_SESSION_ACCESSIBLE) && (!Connected))
    {
        IDebugClient *DebugClient = NULL;
        HRESULT Hr;
        PDEBUG_CONTROL DebugControl = NULL;

        if ((Hr = DebugCreate(__uuidof(IDebugClient),
                              (void **)&DebugClient)) == S_OK)
        {
            //
            // Get the architecture type.
            //
            if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
                                                  (void **)&DebugControl)) == S_OK)
            {
                ULONG   TargetMachine;
                if ((Hr = DebugControl->GetActualProcessorType(
                              &TargetMachine)) == S_OK)
                {
                    Connected = TRUE;
                }

                //NotifyOnTargetAccessible(DebugControl);
                DebugControl->Release();
            }

            DebugClient->Release();
        }
    }

    // The target is gone
    if (Notify == DEBUG_NOTIFY_SESSION_INACTIVE)
        Connected = FALSE;

    return;
}
Example #7
0
/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    consoleExecuteCommand0
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_consoleExecuteCommand0
  (JNIEnv *env, jobject obj, jstring cmd) {
  jboolean isCopy = JNI_FALSE;
  const char* buf = env->GetStringUTFChars(cmd, &isCopy);
  CHECK_EXCEPTION_(0);
  AutoJavaString command(env, cmd, buf);

  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, ptrIDebugClient_ID);
  CHECK_EXCEPTION_(0);

  IDebugClient*  tmpClientPtr = 0;
  if (ptrIDebugClient->CreateClient(&tmpClientPtr) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: CreateClient failed!", 0);
  }
  AutoCOMPtr<IDebugClient> tmpClient(tmpClientPtr);

  IDebugControl* tmpControlPtr = 0;
  if (tmpClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &tmpControlPtr) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: QueryInterface (IDebugControl) failed", 0);
  }
  AutoCOMPtr<IDebugControl> tmpControl(tmpControlPtr);

  SAOutputCallbacks* saOutputCallbacks = (SAOutputCallbacks*) env->GetLongField(obj,
                                                                   ptrIDebugOutputCallbacks_ID);
  CHECK_EXCEPTION_(0);

  saOutputCallbacks->clearBuffer();

  if (tmpClient->SetOutputCallbacks(saOutputCallbacks) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetOutputCallbacks failed!", 0);
  }

  tmpControl->Execute(DEBUG_OUTPUT_VERBOSE, command, DEBUG_EXECUTE_DEFAULT);

  const char* output = saOutputCallbacks->getBuffer();
  if (output == 0) {
     output = "";
  }

  jstring res = env->NewStringUTF(output);
  saOutputCallbacks->clearBuffer();
  return res;
}
Example #8
0
DWORD WINAPI OpenUiSecondThread(void* parameter)
{
	OpenUiSecondThreadParameters* p = (OpenUiSecondThreadParameters*)parameter;
	IDebugClient* Client = p->Client;
	char* Args = p->Args;
	CAutoComPtr<IDebugClient> client2;

	CHECKCOM(Client->CreateClient(&client2));

	wstringstream ss;

	ss << Args;
	clr.InitializeContext(client2);
	HRESULT result = clr.OpenUI(ss.str().c_str());

	delete[] p->Args;
	delete p;
	return result;
}
Example #9
0
HRESULT
CALLBACK
DebugExtensionInitialize(PULONG Version, PULONG Flags)
{
    HRESULT hRes=S_OK;
    IDebugClient *DebugClient;
    PDEBUG_CONTROL DebugControl;

    *Version = DEBUG_EXTENSION_VERSION(EXT_MAJOR_VER, EXT_MINOR_VER);
    *Flags = 0;

    if (FAILED(hRes=DebugCreate(__uuidof(IDebugClient), (void **)&DebugClient)))
        return hRes;

    if (SUCCEEDED(hRes=DebugClient->QueryInterface(__uuidof(IDebugControl),  (void **)&DebugControl)))
    {
        // Get the windbg-style extension APIS
        ExtensionApis.nSize = sizeof (ExtensionApis);
        hRes = DebugControl->GetWindbgExtensionApis64(&ExtensionApis);
        DebugControl->Release();
        dprintf("[sync] DebugExtensionInitialize, ExtensionApis loaded\n");
    }

    DebugClient->Release();
    g_ExtClient = NULL;
    g_Synchronized = FALSE;

    g_hPollCompleteEvent = CreateEvent(NULL, true, false, NULL);
    if (g_hPollCompleteEvent == NULL)
    {
        dprintf("[sync] Command polling feature init failed\n");
        return E_FAIL;
    }

    InitializeCriticalSection(&g_CritSectPollRelease);

    if(SUCCEEDED(LoadConfigurationFile()))
        dprintf("[sync] Configuration file loaded\n       -> set HOST to %s:%s\n", g_DefaultHost, g_DefaultPort);

    return hRes;
}
Example #10
0
//jc: this in the init routine. Runs on load.
HRESULT
CALLBACK
DebugExtensionInitialize(PULONG Version, PULONG Flags)
{
    IDebugClient *DebugClient;
    PDEBUG_CONTROL DebugControl;
    HRESULT Hr;

    *Version = DEBUG_EXTENSION_VERSION(1, 0);
    *Flags = 0;
    Hr = S_OK;

	

    if ((Hr = DebugCreate(__uuidof(IDebugClient),
                          (void **)&DebugClient)) != S_OK)
    {
        return Hr;
    }

    if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
                                  (void **)&DebugControl)) == S_OK)
    {

        //
        // Get the windbg-style extension APIS
        //
        ExtensionApis.nSize = sizeof (ExtensionApis);
        Hr = DebugControl->GetWindbgExtensionApis64(&ExtensionApis);

        DebugControl->Release();

    }
	
	dprintf("[Byakugan] Successfully loaded!\n");
    DebugClient->Release();


    return (Hr);
}
Example #11
0
static bool attachToProcess(JNIEnv* env, jobject obj, jint pid) {
  if (setImageAndSymbolPath(env, obj) == false) {
     return false;
  }
  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,
                                                      ptrIDebugClient_ID);
  CHECK_EXCEPTION_(false);

  /***********************************************************************************

     We are attaching to a process in 'read-only' mode. i.e., we do not want to
     put breakpoints, suspend/resume threads etc. For read-only JDI and HSDB kind of
     usage this should suffice. We are not intending to use this for full-fledged
     ProcessControl implementation to be used with BugSpotAgent.

     Please refer to DEBUG_ATTACH_NONINVASIVE mode source comments from dbgeng.h.
     In this mode, debug engine does not call DebugActiveProrcess. i.e., we are not
     actually debugging at all. We can safely 'detach' from the process anytime
     we want and debuggee process is left as is on all Windows variants.

     This also makes JDI-on-SA installation/usage simpler because with this we would
     not need a tool like ServiceInstaller from http://www.kcmultimedia.com/smaster.

  ***********************************************************************************/


  if (ptrIDebugClient->AttachProcess(0, pid, DEBUG_ATTACH_NONINVASIVE) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: AttachProcess failed!", false);
  }

  IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj,
                                                     ptrIDebugControl_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false);
  }

  return true;
}
Example #12
0
void LateSymbolInfo::loadMinidump(std::wstring& dumppath, bool delete_when_done)
{
	// Method credit to http://stackoverflow.com/a/8119364/21501

	if (debugClient5 || debugControl4 || debugSymbols3)
	{
		//throw SleepyException(L"Minidump symbols already loaded.");

		// maybe the user moved a .pdb to somewhere where we can now find it?
		unloadMinidump();
	}

	IDebugClient *debugClient = NULL;

	SetLastError(0);
	comenforce(DebugCreate(__uuidof(IDebugClient), (void**)&debugClient), "DebugCreate");
	comenforce(debugClient->QueryInterface(__uuidof(IDebugClient5 ), (void**)&debugClient5 ), "QueryInterface(IDebugClient5)" );
	comenforce(debugClient->QueryInterface(__uuidof(IDebugControl4), (void**)&debugControl4), "QueryInterface(IDebugControl4)");
	comenforce(debugClient->QueryInterface(__uuidof(IDebugSymbols3), (void**)&debugSymbols3), "QueryInterface(IDebugSymbols3)");
	comenforce(debugClient5->SetOutputCallbacksWide(debugOutputCallbacks), "IDebugClient5::SetOutputCallbacksWide");
	comenforce(debugSymbols3->SetSymbolOptions(SYMOPT_UNDNAME | SYMOPT_LOAD_LINES | SYMOPT_OMAP_FIND_NEAREST | SYMOPT_AUTO_PUBLICS | SYMOPT_DEBUG), "IDebugSymbols::SetSymbolOptions");

	std::wstring sympath;
	prefs.AdjustSymbolPath(sympath, true);

	comenforce(debugSymbols3->SetSymbolPathWide(sympath.c_str()), "IDebugSymbols::SetSymbolPath");
	comenforce(debugClient5->OpenDumpFileWide(dumppath.c_str(), NULL), "IDebugClient4::OpenDumpFileWide");
	comenforce(debugControl4->WaitForEvent(0, INFINITE), "IDebugControl::WaitForEvent");

	// Since we can't just enumerate all symbols in all modules referenced by the minidump,
	// we have to keep the debugger session open and query symbols as requested by the
	// profiler GUI.

	debugClient->Release(); // but keep the other ones

	// If we are given a temporary file, clean it up later
	if (delete_when_done)
		file_to_delete = dumppath;
}
Example #13
0
extern "C" HRESULT CALLBACK DebugExtensionInitialize(PULONG Version, PULONG Flags)
{
	IDebugClient *DebugClient;
	PDEBUG_CONTROL DebugControl;
	HRESULT Hr;

	*Version = DEBUG_EXTENSION_VERSION(1, 0);
	*Flags = 0;
	Hr = S_OK;

	if ((Hr = DebugCreate(__uuidof(IDebugClient), (void **)&DebugClient)) != S_OK)
	{
		return Hr;
	}
	if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),	(void **)&DebugControl)) == S_OK)
	{
		ExtensionApis.nSize = sizeof(ExtensionApis);
		Hr = DebugControl->GetWindbgExtensionApis64(&ExtensionApis);
		DebugControl->Release();
	}
	DebugClient->Release();
	return Hr;
}
Example #14
0
static bool getWindbgInterfaces(JNIEnv* env, jobject obj) {
  // get windbg interfaces ..

  IDebugClient* ptrIDebugClient = 0;
  if (DebugCreate(__uuidof(IDebugClient), (PVOID*) &ptrIDebugClient) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to create IDebugClient object!", false);
  }
  env->SetLongField(obj, ptrIDebugClient_ID, (jlong) ptrIDebugClient);

  IDebugControl* ptrIDebugControl = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &ptrIDebugControl)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugControl", false);
  }
  env->SetLongField(obj, ptrIDebugControl_ID, (jlong) ptrIDebugControl);

  IDebugDataSpaces* ptrIDebugDataSpaces = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugDataSpaces), (PVOID*) &ptrIDebugDataSpaces)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugDataSpaces object!", false);
  }
  env->SetLongField(obj, ptrIDebugDataSpaces_ID, (jlong) ptrIDebugDataSpaces);

  SAOutputCallbacks* ptrIDebugOutputCallbacks = new SAOutputCallbacks();
  ptrIDebugOutputCallbacks->AddRef();
  env->SetLongField(obj, ptrIDebugOutputCallbacks_ID, (jlong) ptrIDebugOutputCallbacks);
  CHECK_EXCEPTION_(false);

  IDebugAdvanced* ptrIDebugAdvanced = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugAdvanced), (PVOID*) &ptrIDebugAdvanced)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugAdvanced object!", false);
  }
  env->SetLongField(obj, ptrIDebugAdvanced_ID, (jlong) ptrIDebugAdvanced);

  IDebugSymbols* ptrIDebugSymbols = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSymbols), (PVOID*) &ptrIDebugSymbols)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSymbols object!", false);
  }
  env->SetLongField(obj, ptrIDebugSymbols_ID, (jlong) ptrIDebugSymbols);

  IDebugSystemObjects* ptrIDebugSystemObjects = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSystemObjects), (PVOID*) &ptrIDebugSystemObjects)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSystemObjects object!", false);
  }
  env->SetLongField(obj, ptrIDebugSystemObjects_ID, (jlong) ptrIDebugSystemObjects);

  return true;
}
Example #15
0
void
CALLBACK
DebugExtensionNotify(ULONG Notify, ULONG64 /*Argument*/)
{
    //
    // The first time we actually connect to a target, get the page size
    //

    if ((Notify == DEBUG_NOTIFY_SESSION_ACCESSIBLE) && (!Connected))
    {
        IDebugClient *DebugClient;
        PDEBUG_DATA_SPACES DebugDataSpaces;
        PDEBUG_CONTROL DebugControl;
        HRESULT Hr;
        ULONG64 Page;

        if ((Hr = DebugCreate(__uuidof(IDebugClient),
                              (void **)&DebugClient)) == S_OK)
        {
            //
            // Get the page size and PAE enable flag
            //

            if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugDataSpaces),
                                       (void **)&DebugDataSpaces)) == S_OK)
            {
                if ((Hr = DebugDataSpaces->ReadDebuggerData(
                    DEBUG_DATA_MmPageSize, &Page,
                    sizeof(Page), NULL)) == S_OK)
                {
                    PageSize = (ULONG)(ULONG_PTR)Page;
                }

                DebugDataSpaces->Release();
            }
            //
            // Get the architecture type.
            //

            if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
                                                  (void **)&DebugControl)) == S_OK)
            {
                if ((Hr = DebugControl->GetActualProcessorType(
                    &TargetMachine)) == S_OK)
                {
                    Connected = TRUE;
                }
                ULONG Qualifier;
                if ((Hr = DebugControl->GetDebuggeeType(&g_TargetClass, &Qualifier)) == S_OK)
                {
                }

                DebugControl->Release();
            }

            DebugClient->Release();
        }
    }


    if (Notify == DEBUG_NOTIFY_SESSION_INACTIVE)
    {
        Connected = FALSE;
        PageSize = 0;
        TargetMachine = 0;
    }

    return;
}
Example #16
0
HRESULT
CALLBACK
DebugExtensionInitialize(PULONG Version, PULONG Flags)
{
    IDebugClient *DebugClient;
    PDEBUG_CONTROL DebugControl;
    HRESULT Hr;

    *Version = DEBUG_EXTENSION_VERSION(1, 0);
    *Flags = 0;

    if (g_Initialized)
    {
        return S_OK;
    }
    g_Initialized = true;

    if ((Hr = DebugCreate(__uuidof(IDebugClient),
                          (void **)&DebugClient)) != S_OK)
    {
        return Hr;
    }
    if ((Hr = DebugClient->QueryInterface(__uuidof(IDebugControl),
                                              (void **)&DebugControl)) != S_OK)
    {
        return Hr;
    }

    ExtensionApis.nSize = sizeof (ExtensionApis);
    if ((Hr = DebugControl->GetWindbgExtensionApis64(&ExtensionApis)) != S_OK)
    {
        return Hr;
    }
    
    // Fixes the "Unable to read dynamic function table entries" error messages by disabling the WinDbg security
    // feature that prevents the loading of unknown out of proc tack walkers.
    DebugControl->Execute(DEBUG_OUTCTL_IGNORE, ".settings set EngineInitialization.VerifyFunctionTableCallbacks=false", 
        DEBUG_EXECUTE_NOT_LOGGED | DEBUG_EXECUTE_NO_REPEAT);

    ExtQuery(DebugClient);
    if (IsMiniDumpFileNODAC())
    {
        ExtOut (
            "----------------------------------------------------------------------------\n"
            "The user dump currently examined is a minidump. Consequently, only a subset\n"
            "of sos.dll functionality will be available. If needed, attaching to the live\n"
            "process or debugging a full dump will allow access to sos.dll's full feature\n"
            "set.\n"
            "To create a full user dump use the command: .dump /ma <filename>\n"
            "----------------------------------------------------------------------------\n");
    }
    ExtRelease();
    
    OnUnloadTask::Register(CleanupEventCallbacks);
    g_pCallbacksClient = DebugClient;
    EventCallbacks* pCallbacksObj = new EventCallbacks(DebugClient);
    IDebugEventCallbacks* pCallbacks = NULL;
    pCallbacksObj->QueryInterface(__uuidof(IDebugEventCallbacks), (void**)&pCallbacks);
    pCallbacksObj->Release();

    if(FAILED(Hr = g_pCallbacksClient->SetEventCallbacks(pCallbacks)))
    {
        ExtOut ("SOS: Failed to register callback events\n");
        pCallbacks->Release();
        return Hr;
    }
    pCallbacks->Release();

#ifndef _ARM_
    // Make sure we do not tear down the debugger when a security function fails
    // Since we link statically against CRT this will only affect the SOS module.
    _set_invalid_parameter_handler(_SOS_invalid_parameter);
#endif
    
    DebugControl->Release();
    return S_OK;
}