11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#include "tools/v8windbg/base/dbgext.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <crtdbg.h>
81cb0ef41Sopenharmony_ci#include <wrl/module.h>
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#include "tools/v8windbg/base/utilities.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci// See
131cb0ef41Sopenharmony_ci// https://docs.microsoft.com/en-us/visualstudio/debugger/crt-debugging-techniques
141cb0ef41Sopenharmony_ci// for the memory leak and debugger reporting macros used from <crtdbg.h>
151cb0ef41Sopenharmony_ci_CrtMemState mem_old, mem_new, mem_diff;
161cb0ef41Sopenharmony_ciint original_crt_dbg_flag = 0;
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciWRL::ComPtr<IDataModelManager> sp_data_model_manager;
191cb0ef41Sopenharmony_ciWRL::ComPtr<IDebugHost> sp_debug_host;
201cb0ef41Sopenharmony_ciWRL::ComPtr<IDebugControl5> sp_debug_control;
211cb0ef41Sopenharmony_ciWRL::ComPtr<IDebugHostMemory2> sp_debug_host_memory;
221cb0ef41Sopenharmony_ciWRL::ComPtr<IDebugHostSymbols> sp_debug_host_symbols;
231cb0ef41Sopenharmony_ciWRL::ComPtr<IDebugHostExtensibility> sp_debug_host_extensibility;
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ciextern "C" {
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciHRESULT
281cb0ef41Sopenharmony_ci__stdcall DebugExtensionInitialize(PULONG /*pVersion*/, PULONG /*pFlags*/) {
291cb0ef41Sopenharmony_ci  original_crt_dbg_flag = _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF);
301cb0ef41Sopenharmony_ci  _CrtMemCheckpoint(&mem_old);
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  WRL::ComPtr<IDebugClient> sp_debug_client;
331cb0ef41Sopenharmony_ci  WRL::ComPtr<IHostDataModelAccess> sp_data_model_access;
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(DebugCreate(__uuidof(IDebugClient), &sp_debug_client));
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_debug_client.As(&sp_data_model_access));
381cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_debug_client.As(&sp_debug_control));
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_data_model_access->GetDataModel(&sp_data_model_manager,
411cb0ef41Sopenharmony_ci                                                    &sp_debug_host));
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_debug_host.As(&sp_debug_host_memory));
441cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_debug_host.As(&sp_debug_host_symbols));
451cb0ef41Sopenharmony_ci  RETURN_IF_FAIL(sp_debug_host.As(&sp_debug_host_extensibility));
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  return CreateExtension();
481cb0ef41Sopenharmony_ci}
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_civoid __stdcall DebugExtensionUninitialize() {
511cb0ef41Sopenharmony_ci  DestroyExtension();
521cb0ef41Sopenharmony_ci  sp_debug_host = nullptr;
531cb0ef41Sopenharmony_ci  sp_data_model_manager = nullptr;
541cb0ef41Sopenharmony_ci  sp_debug_host_memory = nullptr;
551cb0ef41Sopenharmony_ci  sp_debug_host_symbols = nullptr;
561cb0ef41Sopenharmony_ci  sp_debug_host_extensibility = nullptr;
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_ci  _CrtMemCheckpoint(&mem_new);
591cb0ef41Sopenharmony_ci  if (_CrtMemDifference(&mem_diff, &mem_old, &mem_new)) {
601cb0ef41Sopenharmony_ci    _CrtMemDumpStatistics(&mem_diff);
611cb0ef41Sopenharmony_ci  }
621cb0ef41Sopenharmony_ci  _CrtSetDbgFlag(original_crt_dbg_flag);
631cb0ef41Sopenharmony_ci}
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ciHRESULT __stdcall DebugExtensionCanUnload(void) {
661cb0ef41Sopenharmony_ci  if (!WRL::Module<WRL::InProc>::GetModule().Terminate()) {
671cb0ef41Sopenharmony_ci    _RPTF0(_CRT_WARN, "Failed to unload WRL\n");
681cb0ef41Sopenharmony_ci    return S_FALSE;
691cb0ef41Sopenharmony_ci  }
701cb0ef41Sopenharmony_ci  return S_OK;
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_civoid __stdcall DebugExtensionUnload() { return; }
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci}  // extern "C"
76