

以前、リサイズ可能なメモリDCでの不正終了について質問をしました。

[VC++/MFC メモリDCの破棄時に不正終了してしまう場合がある](https://ja.stackoverflow.com/q/83416)

申し訳ありません、登録したばかりで慣れておりません。  
どうぞよろしくお願いします。

①不正終了 DeleteMemDC()箇所 : map情報から  
②画面は5枚でなく2枚です。  
③ワーカースレッドにてメモリDCに再描画  
④OnPaint()にてスクリーンに転送してます。

**質問1**  
DeleteMemDC()にてハンドルがNULLでもAPIを実行してしまうので、NULL以外で実行するようにした方が良いのでしょうか？

**質問2**  
イベントビューアーでの終了レポートとVC++ map情報からDeleteMemDC()内で落ちているようですが、何が原因かまでは記録されません。  
こういった時調べる手立てとしてどのような施策ができるのか、ご指導いただければ幸いです。

以下がソースコードの抜粋になります。

[code]

    #define WM_USER_UPDATE_GRAPH    (WM_USER + 3)
    
    CRITICAL_SECTION csm;
    
    enum eLayer {
      L_Graph = 0,
      L_Splash,
      L_Max_Count,
    };
    
    // CFooDlg ダイアログ
    class CFooDlg : public CDialog
    {
    
      HANDLE hStartRedrawThread;
      HANDLE hKillRedrawThread;
    
      HANDLE hRedrawThreadStarted;
      HANDLE hRedrawThreadKilled;
    
      CWinThread* m_pRedrawThread;
    
      CStatic m_graphTemp;              //ダイアログ上のグラフ描画域
    
    };
    
    
    CFooDlg::CFooDlg(CWnd* pParent /*=NULL*/)
      : CDialog(CFooDlg::IDD, pParent)
    {
      m_bSplash = TRUE;
      m_bResized = FALSE;
        :
      m_pRedrawThread = NULL;
    
      InitializeCriticalSection(&csm);
    
    
    }
    
    CFooDlg::~CFooDlg()
    {
       :
      DeleteCriticalSection(&csm);
    }
    
    BEGIN_MESSAGE_MAP(CFooDlg, CDialog)
    {
    :
      ON_MESSAGE(WM_USER_REDRAW, &CFooDlg::OnUserRedraw)
    :
    
    }
    
    BOOL CFooDlg::OnInitDialog()
    {
    
      CDialog::OnInitDialog();
    
      // "バージョン情報..." メニューをシステム メニューに追加します。
    
      // IDM_ABOUTBOX は、システム コマンドの範囲内になければなりません。
      ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
      ASSERT(IDM_ABOUTBOX < 0xF000);
    
      g_hWnd = this->m_hWnd;
      SetHook();
    
    
      CMenu* pSysMenu = GetSystemMenu(FALSE);
      if (pSysMenu != NULL) {
        BOOL bNameValid;
        CString strAboutMenu;
        bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
        ASSERT(bNameValid);
        if (!strAboutMenu.IsEmpty()) {
          pSysMenu->AppendMenu(MF_SEPARATOR);
          pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
      }
    
      // このダイアログのアイコンを設定します。アプリケーションのメイン ウィンドウがダイアログでない場合、
      //  Framework は、この設定を自動的に行います。
      SetIcon(m_hIcon, TRUE);           // 大きいアイコンの設定
      SetIcon(m_hIcon, FALSE);      // 小さいアイコンの設定
    
      char vbuf[128];
      // タイトルバー表示(リソースより版数情報)
      CString ver = APP->GetVersionString();
      CString title;
      GetWindowText(title);
    
      RecalcLayout();
    
      CRect rect;
      m_graphTemp.GetClientRect(&rect);
    
      CDC* pDC = m_graphTemp.GetDC();
    
      for(int i=0;i<L_Max_Count;i++) {
        BOOL r = m_memDC[i].CreateCompatibleDC(pDC);
        r = m_bmp[i].CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
        m_pOldBmp[i] = m_memDC[i].SelectObject(&m_bmp[i]);
        dbg_printf("OnInitDialog::m_pOldBmp[%d] = %p\n", i, m_pOldBmp[i]);
        m_memDC[i].BitBlt(0,0,rect.Width(),rect.Height(),NULL,-1,-1,WHITENESS);
      }
    
      m_graphTemp.ReleaseDC(pDC);
    
    //  m_bSplash = TRUE;
      m_bSplash = ::GetPrivateProfileInt("Display", "Show_Splash",1,APP->GetIniPath());
      :
      :
      hRedrawThreadStarted = CreateEvent(NULL,TRUE,FALSE,NULL);
      hRedrawThreadKilled = CreateEvent(NULL,TRUE,FALSE,NULL);
    
      if(m_pRedrawThread ==NULL) {
        m_pRedrawThread = AfxBeginThread(Redraw_Thread, this);
        m_pRedrawThread->m_bAutoDelete = FALSE;
      } else {
        AfxMessageBox("プログラム起動時に問題が発生しました。");
        DestroyWindow();
        return FALSE;
      }
      SetEvent(hStartRedrawThread);
      if(WaitForSingleObject(hRedrawThreadStarted,5000L)==WAIT_TIMEOUT) {
        AfxMessageBox("画面更新スレッドが起動できませんでした");
        DestroyWindow();
        return FALSE;
      }
    
    }
    
    BOOL CFooDlg::DestroyWindow()
    {
      // TODO: Add your specialized code here and/or call the base class
      ::EnumWindows(EnumWindowsProc, (LPARAM)this );
    
      PlaySound(NULL, NULL, 0);
    
      UnHook(); 
    
      ReleaseCapture();
    
      for(int i=0;i<L_Max_Count;i++) {
        dbg_printf("m_pOldBmp[%d] = %p\n", i, m_pOldBmp[i]); //V1_6_8(408)
        m_memDC[i].SelectObject(m_pOldBmp[i]);
        m_bmp[i].DeleteObject();
        m_memDC[i].DeleteDC();
      }
    
    
      if(m_pRedrawThread) {
        SetEvent(hKillRedrawThread);
        Sleep(100L);
        WaitForSingleObject( m_pRedrawThread->m_hThread , INFINITE );
        delete m_pRedrawThread;
      }
    
    //  PostQuitMessage();
    
    ///  m_Graph.DestroyWindow();
      Sleep(500L);
    
      DeleteCriticalSection(&H8Ctl::cs);
    
      Sleep(50L);
    
      return CDialog::DestroyWindow();
    }
    
    void CFooDlg::OnSize(UINT nType, int cx, int cy)
    {
      CDialog::OnSize(nType, cx, cy);
    
      // TODO: Add your message handler code here
    
      AdjustLayout();
    
      // For Statusbar
      RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
    
      m_bResized = TRUE;
    
    
    }
    
    void CFooDlg::OnPaint()
    {
      DWORD t = GetTickCount();
    
    
      if (IsIconic())
      {
        CPaintDC dc(this); // 描画のデバイス コンテキスト
    
        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
    
        // クライアントの四角形領域内の中央
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
    
        // アイコンの描画
        dc.DrawIcon(x, y, m_hIcon);
      }
      else
      {
    
        DWORD tic = GetTickCount();
    
       if(!m_bSplash && m_bResized) {  //起動時のスプラッシュ表示までは、メモリＤＣをリサイズしない
         dbg_printf("resized\n");
         EnterCriticalSection(&csm);
         DeleteMemDC();
         CreateMemDC();
         LeaveCriticalSection(&csm);
         m_bResized = FALSE;
    
       }
    
        CRect rect;
        m_graphTemp.GetClientRect(&rect);
    
        CDC* pDC = m_graphTemp.GetDC();
    
        if(m_bSplash)
          pDC->BitBlt(0,0,rect.right,rect.bottom,&m_memDC[L_Splash],0,0,SRCCOPY);
        else
        {
          pDC->BitBlt(0,0,rect.right,rect.bottom,&m_memDC[L_Graph],0,0,SRCCOPY);
          ers_t = -1;
    
        }
    
        m_graphTemp.ReleaseDC(pDC);
    
        CDialog::OnPaint();
    
      }
    
    }
    
    // ユーザーメッセージハンドラ
    // ｸﾞﾗﾌをメモリDCに描画する
    LRESULT CFootDlg::OnUserUpdateChild(WPARAM wParam, LPARAM lParam)
    {
      DWORD t = GetTickCount();
    
      CRect rect;
      m_graphTemp.GetClientRect(&rect);
      drawGraph(&m_memDC[L_Graph],rect.Width(),rect.Height(),0,rect.Height());
    
      BYTE pv[20];
      memset(pv,0x00,sizeof(pv));
      for(int i=0;i<4;i++)
        pv[i] = H8Ctl::pv.vent_PV[i];
      for(int i=0;i<2;i++)
        pv[i+4] = H8Ctl::pv.curt_PV[i];
    
      if(pDispDlg)
        pDispDlg->UpdateLED(m_lamp, pv);
    
      if (pMainGraphSetupDlg)
      {
        if (!m_bCursor && !bLogvw /* == isToday()*/)
        {
          CTime today = CTime::GetCurrentTime();
          cur_t = today.GetHour() * 60 + today.GetMinute();
        }
        pMainGraphSetupDlg->m_DlgBar.UpdateCurrentValue(cur_t, bLogvw);
      }
    
      return 1L;
    }
    
    // *memDCにグラフを描画
    void CFooTestDlg::drawGraph(CDC* pDC, int devWidth, int devHeight,int vwOrgX,int vwOrgY, BOOL bPrint) 
    {
    
      COLORREF col = DK_GREEN;
    
      CFont font,fontS;
      CFont* pOldFont;
    
      font.CreatePointFont(160,"MS UI Gothic");
      fontS.CreatePointFont(120,"MS UI Gothic");
    
      CRect rcw;
      CRect rect;
      m_graphTemp.GetClientRect(&rect);
    
      int map = pDC->SetMapMode(MM_ANISOTROPIC);//通常座標系
    
      CPoint ptOrg = CPoint(-LP_MX, -LP_MY);         // 原点
      CSize  szWind = CSize(LP_W, LP_H);         // 仮想ウィンドウサイズ
    
      CSize szW = pDC->SetWindowExt(szWind);  //仮想ウィンドウサイズ
      CPoint ptW = pDC->SetWindowOrg(ptOrg);
    
      CSize szV = pDC->SetViewportExt(devWidth, -devHeight);
      CPoint ptV = pDC->SetViewportOrg(vwOrgX, vwOrgY);
      CBrush* pOldBrsh = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
    
      COLORREF bk = pDC->GetBkColor();
      pDC->SetBkMode(TRANSPARENT);  // 背景透明
    
      pOldFont = pDC->SelectObject(&font);
    
      bk = RGB(255,255,255);
      rcw = CRect(ptOrg.x,ptOrg.y,ptOrg.x+szWind.cx,ptOrg.y+szWind.cy);
    
      pDC->FillSolidRect(&rcw, RGB(255,255,255));
    
      CPen pen(PS_DOT,0,LT_GRAY);  //目盛
      CPen pen0(PS_SOLID,0,BLACK);  //目盛
      CPen penTh(PS_SOLID,0,LT_GRAY);
      CPen penB(PS_SOLID,3,BLACK);
      CPen penBold(PS_SOLID,5,GRAY);  //目盛
    
      CPen penT(PS_SOLID,1,col);
      CPen px(PS_SOLID,1,RGB(192,128,192));
      CPen penXX(PS_SOLID,1,RGB(0,0,255));
      CPen penXXX(PS_DOT,0,RGB(0,0,192));
    
      CRgn rgnG;
      CBrush brshS(RGB(255,255,192));  // 昼時間
    
      int w = LP_X;
      int hh = LP_Y;
    
      int rise = suntime[0]/100 * 60 + suntime[0]%100;
      int set = suntime[1]/100 * 60 + suntime[1]%100;
      int south = (set - rise) / 2 + rise;
      if(bLogvw) {
        rise = vLog_suntime[0]/100 * 60 + vLog_suntime[0]%100;
        set = vLog_suntime[1]/100 * 60 + vLog_suntime[1]%100;
        south = (set - rise) / 2 + rise;
      }
      ////// 昼時間の描画
      float xx = (float)LP_X/(float)(Tick[1] - Tick[0]);  // スケールX
    
      int   rr = (int)((rise-Tick[0]) * xx);
      int   ss = (int)((set -Tick[0]) * xx);
    
      // グラフ域のみに描画制限
      CRect rcGrp(0,0,LP_X,LP_Y); //LP領域
      pDC->LPtoDP(&rcGrp);
      rgnG.CreateRectRgn(rcGrp.left,rcGrp.top,rcGrp.right,rcGrp.bottom);
    
      CRect rc(rr,0,ss,hh);
      pDC->FillRect(rc, &brshS);
    
      // 全面に制限変更
    
      CString str;
      int wh = w/24;
    
      CPen* pOldPen = pDC->SelectObject(&penB);
    
      // 時間軸描画
      int x;
      // 段階ズームおよび開始分(!=0)対応
      pDC->SelectObject(&penB);     // THIN_SOLID
      x = (int)(0);
      pDC->MoveTo(x, 0);  pDC->LineTo(x,hh);
      x = (int)(((float)(Tick[1]- Tick[0]) * xx)+0.5f);
      pDC->MoveTo(x, 0);  pDC->LineTo(x,hh);
    
      for(int i=Tick[0];i<=Tick[1];i++) {
        if(!(i%180)) { //3時間
          x = (int)(((float)(i-Tick[0]) * xx)+0.5f);
    
          if(m_swTimeScale) {
            if(!(i%360))
              pDC->SelectObject(&penTh);  //Thin_SOLID
            else
              pDC->SelectObject(&pen);  //DOT
    
            pDC->MoveTo(x, 0);  pDC->LineTo(x, hh);
          }
    
          pDC->SelectObject(&penB);
          pDC->MoveTo(x, -hh/100);  pDC->LineTo(x,hh/100);
        } else if(!(i%60)) { //1時間
          x = (int)(((float)(i-Tick[0]) * xx)+0.5f);
          pDC->SelectObject(&pen0);
          pDC->MoveTo(x, -hh/200);  pDC->LineTo(x,hh/200);
        }
        if(!(i%60)) { //1時間
          str.Format("%02d",i/60); 
          CSize sz = pDC->GetTextExtent(str);
          pDC->TextOut(x-sz.cx/2,-20,str);
        }
      }
      float temp = 0.f;       //開始温度
      //m_nUnit : コンボボックスでの選択番号
      // =>tGraphRangeより選択番号を使って、MeasTypeを得る
      // =>得たmeastypeより、gInfoを参照して、単位、範囲などを得る.
      CSize szT;
      str = _T("XXXX");
      szT = pDC->GetTextExtent(str);
    
      MeasureValue mt = (MeasureValue)m_nUnit[0];
      tGraphConfig* p = getMainGraphConfig(mt);
      if(p!=NULL) {
        temp = p->min;
    
        // 温度軸(縦軸)描画
        float r = p->max - p->min;
        float yy = ((temp-p->min)  * hh)/r;
    
        pDC->SetTextColor(p->col);
        if(p->step) { // 0除算対策
          DWORD t = GetTickCount();    
          pDC->SelectObject(&pen);
          for(int i=(int)(p->min);i<=(int)(p->max);i+=(int)(p->step)){
            if(GetTickCount() - t > 100L)
              break;
            temp = (float)i;
            yy = ((temp-p->min)* hh)/r;
    
          if(m_swItemScale) {
            if(i==0)
              pDC->SelectObject(&penTh);  //THIN_SOLID
            else
              pDC->SelectObject(&pen);  //DOT
    
            pDC->MoveTo(0, (int)(yy+0.5f)); pDC->LineTo(LP_X,(int)(yy+0.5f));
          }
    
            pDC->MoveTo(-LP_X/200, (int)(yy+0.5f)); pDC->LineTo(LP_X/200,(int)(yy+0.5f));
    
    
            str.Format(" %3hd ", (short)temp); // 前後空白マージン
            if(p->mt == MV_None) {
              str.Format(" %u ", (UINT)temp); // 状況は符号なし
            }
            CSize szText = pDC->GetTextExtent(str);
            CPoint pt = CPoint(-szText.cx, (int)(yy+szText.cy/2));
            CRect rect(pt,CSize(szText.cx, (int)(-szText.cy)));
            //pDC->Rectangle(rect);
            if(p->mt != MV_None)
              pDC->DrawText(str,rect,DT_SINGLELINE | DT_RIGHT);
          }
        }
    
        yy = ((p->max-p->min)* hh)/r;
    
        szT = pDC->GetTextExtent("00%%");
        str.Format("%s %s", p->name, p->unit);  // name追加
        pDC->TextOut(-szT.cx,(int)yy+szT.cy*3/2, str);
      }
    
      pDC->SelectObject(&penB);     // THIN_SOLID
      pDC->MoveTo(0,    0);
      pDC->LineTo(1440, 0);
      pDC->LineTo(LP_X, 0);
    
      //右軸
      mt = (MeasureValue)m_nUnit[1];
      p = getMainGraphConfig(mt);
      if(p!=NULL) {
        temp = p->min;
    
        // 温度軸(縦軸)描画
        float r = p->max - p->min;
        float yy = ((temp-p->min)  * hh)/r;
    
        pDC->SetTextColor(p->col);
    
    
        r = p->max - p->min;
        DWORD t = GetTickCount();
        for(int i=(int)(p->min);i<=(int)(p->max);i+=(int)(p->step)){
          if(GetTickCount() - t > 100L)
            break;
          temp = (float)i;
          yy = ((temp-p->min)  * hh)/r;
    
          str.Format(" %3hd ", (short)temp); // 前後空白はマージン
          if(p->mt == MV_None) {
            str.Format(" %u ", (UINT)temp); // 状況は符号なし
          }
          CSize szText = pDC->GetTextExtent(str);
          CPoint pt = CPoint(LP_X, (int)(yy+szText.cy/2));
          CRect rect(pt,CSize(szText.cx,-szText.cy));
          //pDC->Rectangle(rect);
          pDC->DrawText(str,rect,DT_SINGLELINE | DT_RIGHT);
    
        }
        
        yy = ((p->max-p->min)* hh)/r;
        
        szT = pDC->GetTextExtent("00%%");
        str.Format("%s %s", p->name, p->unit);  // name追加
        pDC->TextOut(LP_X-szT.cx, (int)(yy+szT.cy*3/2), str);
      }
    
      int h = m_u8time[4];
      int m = m_u8time[5];
      int x0 = h * wh;
      int xo = wh * m / 60;
      int tick = (h*60 + m)%TIME_RANGE;
    
    
      int   tic = (int)( (tick-Tick[0]) * xx );
    
      ////////////////////
      // グラフ、目標温度をスケール内での描画に制限
      pDC->SelectClipRgn(&rgnG);
    
      // 設定1 or 設定2の　換気・暖房ライン(時間帯設定ライン)
      // 換気設定
      // 冷房設定
      // 暖房管理1
      // 暖房管理2 の設定ラインの描画
      if(!bLogvw) {
        if(m_swKankiSV[0])
          DrawSV(pDC, Kanki_Temp,   timz[0], timz_N, 1440, hh );
        if(m_swHeatSV[0])
          DrawSV(pDC, Danbo_Temp_1, timz_h[0], timz_N, 1440, hh );
        if(m_swHeatSV[1])
          DrawSV(pDC, Danbo_Temp_2, timz_h[1], timz_N, 1440, hh );
      }
    
      pDC->SelectClipRgn(NULL);
      ////////////////////
      // クライアント座標(物理座標DP)
      // 以下の描画時、グラフ域外に項目名を書くため
      CFont* pF = pDC->SelectObject(&fontS);
      for(int b = 0; b < 16; b ++) {
        DrawStatusGraph(pDC, 1<<b, tick, LP_X, hh);
      }
      pDC->SelectObject(pF);
      pDC->SelectClipRgn(&rgnG);
      // グラフ描画 (gccでのmkr!=0の時のみ表示する。)
      for(int i=1;i<MV_Max_Count;i++) {
        MeasureValue mt = gcc[i].mt;
        if(mt == MV_Invalid_Item)
          break;
        if(mt < MV_None || mt >= MV_Max_Count)
          continue;
        DrawMeasGraph(pDC, mt, tick,  LP_X, hh);
      }
    
    
      if(Pressed) {
        CPoint mk[4];
        mk[0] = ptSelectDP[0];
        mk[1] = CPoint(ptSelectDP[0].x, ptSelectDP[1].y);
        mk[2] = ptSelectDP[1];
        mk[3] = CPoint(ptSelectDP[1].x, ptSelectDP[0].y);
        pDC->SelectObject(penXX);
        for(int i=0;i<4;i++) {
          pDC->DPtoLP(&mk[i]);
          pDC->FillSolidRect(CRect(mk[i].x-10,mk[i].y-10,mk[i].x+10,mk[i].y+10),RGB(0,0,255));
        }
        CRect rcLP = CRect(ptSelectDP[0],ptSelectDP[1]);
        pDC->DPtoLP(&rcLP);
        pDC->SelectObject(&penXXX);
        pDC->SelectStockObject(NULL_BRUSH);
        pDC->Rectangle(&rcLP);
      }
    
    
      pDC->SelectObject(pOldFont);
      pDC->SelectObject(pOldBrsh);
      pDC->SelectObject(pOldPen);
      pDC->SelectClipRgn( NULL ); 
    
      pDC->SetMapMode(map);//通常座標系
      pDC->SetWindowExt(szW);
      pDC->SetViewportExt(szV);
    
      pDC->SetWindowOrg(ptW);
      pDC->SetViewportOrg(ptV);
    
      pDC->SelectClipRgn(NULL);
    
      brshS.DeleteObject(); //B1.3 Added
    
      pen.DeleteObject();
      pen0.DeleteObject();
      penTh.DeleteObject();
      penB.DeleteObject();
      penBold.DeleteObject();
    
      penT.DeleteObject();
      px.DeleteObject();
      penXX.DeleteObject();
      penXXX.DeleteObject();
    
      rgnG.DeleteObject();
    
      fontS.DeleteObject();
      font.DeleteObject();
    
    }
    
    
    UINT Redraw_Thread(LPVOID ptr)
    {
      CFooDlg* p = (CFooDlg*)ptr;
      HWND hWnd =p->m_hWnd;
    
      DWORD tick = GetTickCount();
      DWORD tick2 = GetTickCount();
      DWORD tick3 = GetTickCount();
      UINT ret = 0;
    int th = 0;
    
      SetEvent(p->hRedrawThreadStarted);
      dbg_printf("****Redraw_Thread Started****\n");
    
      MSG message;
    
      while(1) {
        if(::PeekMessage(&message, NULL, 0, 0, PM_REMOVE)){ 
          //ループ中のマウスメッセージ処理
          ::TranslateMessage(&message);
          ::DispatchMessage(&message);
        }
    
        Sleep(50L);
        if(WaitForSingleObject(p->hKillRedrawThread, 100L) == WAIT_OBJECT_0)
          break;
        if(WaitForSingleObject(p->hStartRedrawThread, 100L) == WAIT_TIMEOUT)
          continue;
    
        EnterCriticalSection(&csm);
        if((GetTickCount() - tick) > 500L) {
          tick = GetTickCount();
          ::PostMessage(hWnd,WM_USER_REDRAW, NULL, 0L);
        }
        LeaveCriticalSection(&csm);
    
      }
      SetEvent(p->hRedrawThreadKilled);
      dbg_printf("****Ended Redraw_Thread****\n");
      return 0;
    }
    
[/code]


CC BY-SA 4.0
2021-11-08T00:32:27.467
83479
2021-11-08T23:26:53.753
2021-11-08T02:02:01.970
3060
48939
question
mfc visual-c++
VC++/MFC メモリDCの破棄時に不正終了してしまう場合がある (その２)


とりあえず下記サイトを参考に、アプリ クラッシュ時のプロセス ダンプを採取する設定を行い、問題現象再現後に生成されたプロセス ダンプを解析してみては?

Windowsエラー報告（WER）機能を使ってアプリケーションのクラッシュダンプ（ユーザーダンプ）を作成する方法  
<https://support.citrix.com/article/CTX119302>


CC BY-SA 4.0
2021-11-08T01:15:52.123
83480
2021-11-08T01:15:52.123
34652
83479
answer