2026年4月17日金曜日

bcdedit ブート構成のデータ ストアを開けませんでした。

C:\windows\system32>bcdedit 
ブート構成のデータ ストアを開けませんでした。 
ファイルを格納しているボリュームが外部的に変更されたため、開かれているファイルが無効になりました。 

レジストリの HKEY_LOCAL_MACHINE\BCD00000000\Description\System に 1 が設定されているかどうか、確認しましょう。

Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\BCD00000000\Description]
"System"=dword:00000001

あるいは、 bcdedit /sysstore を使用することで修正ができます。

bcdedit /sysstore S:\EFI\Microsoft\Boot\BCD

参考

---

ケース

  • 正規の \EFI\Microsoft\Boot\BCD が破損した。 そのため \EFI\Microsoft\Recovery\BCD をコピーして流用した場合。

---

通常の Windows 起動後にドライバーのロードエラーが多発する場合

winpe Yes を削除しましょう。 bcdedit /deletevalue /? で説明が出ます。

次のコマンドは、指定されたオペレーティング システムのブート エントリから
Windows PE の値を削除します:

    bcdedit /deletevalue {cbd971bf-b7b8-4885-951a-fa03044f5d71} winpe

---

レジストリに HKEY_LOCAL_MACHINE\BCD00000000 が存在しない場合

可能性は色々あります。

  • UEFI ブートではなく BIOS ブートで Windows をインストールした場合。
  • System 値が適切な内容ではなかった。 そのため BCDEDIT がレジストリーハイブをアンロードしてしまった場合。

EFI パーティションを発見し、マウントし、冒頭の修正を適用しましょう。

---

mountvol コマンドで、 EFI パーティションを含む、 マウント操作はできます。しかし、 大変です。

C:\windows\system32>mountvol
ボリューム マウント ポイントを作成、削除、一覧を表示します。

MOUNTVOL [ドライブ:]パス ボリューム名
MOUNTVOL [ドライブ:]パス /D
MOUNTVOL [ドライブ:]パス /L
MOUNTVOL [ドライブ:]パス /P
MOUNTVOL /R
MOUNTVOL /N
MOUNTVOL /E
MOUNTVOL drive: /S

    パス        マウント ポイントを常駐させる既存の NTFS ディレクトリ
                を指定します
    ボリューム名
                マウント ポイントのターゲットとなるボリューム名を指定しま
                す。
    /D          指定されたディレクトリからボリューム マウント ポイント
                を削除します。
    /L          指定されたディレクトリのマウントされているボリューム
                の一覧を表示します。
    /P          指定されたディレクトリからボリューム マウント ポイントを削除
                してボリュームをマウント解除し、ボリュームをマウントできな
                くします。
                ボリューム マウント ポイントを作成して、もう一度ボリュームを
                マウントできるようにします。
    /R          システムに存在しないマウント ポイント ディレクトリとレジストリ
                設定を削除します。
    /N          新しいボリュームの自動マウントを無効にします。
    /E          新しいボリュームの自動マウントを再び有効にします。
    /S          EFI システム パーティションを与えられたドライブにマウントします。

現在のマウント ポイントとボリューム名の考えられる値:

    \\?\Volume{d91c85a3-9dab-4fed-8127-c1dc22030c50}\
        C:\

    \\?\Volume{4ac0892e-7ced-11ef-8fa7-fb42c4497b34}\
        *** マウント ポイントなし ***

    \\?\Volume{353729de-022e-496c-be84-40661eb3c26e}\
        H:\

    \\?\Volume{cceccf4f-78e6-4f42-b778-c5833680a4a9}\
        V:\

    \\?\Volume{8c1c1ca0-0000-0000-0080-000000000000}\
        X:\

    \\?\Volume{4ac0892b-7ced-11ef-8fa7-fb42c4497b34}\
        S:\

    \\?\Volume{2fe034fc-4f9a-11ea-a282-001bdc0575bf}\
        F:\

    EFI システム パーティションが S:\ にマウントされています

既にマウント済みのため「EFI システム パーティションが S:\ にマウントされています」という一文が最後に出力されています。

mountvol を使用した方法では、 EFI システム パーティションを目視で発見することはできません。

diskmgmt.msc では、 EFI システム パーティションの存在は確認できます。 一方で、 マウント操作はできなかったはずです。

mountvol の代わりに diskpart などを活用しましょう。

---

mountvol によるマウント例

mountvol S: "\\?\Volume{4ac0892b-7ced-11ef-8fa7-fb42c4497b34}"

---

EFI システム パーティションをマウントしたならば、冒頭のコマンドで補修しましょう。

bcdedit /sysstore S:\EFI\Microsoft\Boot\BCD

あるいは \EFI\Microsoft\Boot\BCD をレジストリーハイブへロードすることもできます。

C:\Windows\System32>reg load HKLM\BCD00000000 S:\EFI\Microsoft\Boot\BCD
この操作を正しく終了しました。

そうすることで、レジストリエディターから目視したり、編集したりすることができるようになります。

C:\windows\system32>reg add HKLM\BCD00000000\Description /v System /t REG_DWORD /d 1 
この操作を正しく終了しました。 
 

C:\windows\system32>reg add HKLM\BCD00000000\Description /v System /t REG_DWORD /d 1 
エラー: アクセスが拒否されました。 

拒否された場合は、 ACL (アクセス制御リスト) を修正する必要があります。

---


2022年9月12日月曜日

ASP.NET MVC "Cannot perform runtime binding on a null reference"

これは初見の人にとっては厄介な問題です。

 
[RuntimeBinderException: Cannot perform runtime binding on a null reference]
   CallSite.Target(Closure , CallSite , Object ) +148
   System.Dynamic.UpdateDelegates.UpdateAndExecute1(CallSite site, T0 arg0) +664 
   ...
 
初見の人にとって厄介な理由は、修正すべき場所とは異なる場所が指摘されるからです。
 
この例については…
luckyNumber はきちんと初期化しています。
luckyNumber に問題が無い事は明らかです。
 
 
未初期化のフィールドへアクセスしていないかどうかを確認しましょう。
 
この場合は @Model へのアクセスが問題です。
@Model を一切初期化していないのにも関わらず、
@Model へアクセスしようとしています。
 

@Model については @model 宣言をしない場合 dynamic 型として解決されるようです。
dynamic 型は実行時に解決されます。
実行するまでエラーが発生しないため、見過ごしてしまう事が懸念されます。

他のソースコードから input タグ等をコピーしてきた場合に起こり得ます。
@Model は存在しないので value 属性ごと削除しても良いでしょう。


2022年6月1日水曜日

Debugging Tools for Windows の cdb.exe を使って .NET Framework 4.0 アプリのクラッシュダンプから stack trace を得る

Debugging Tools for Windows の cdb.exe を使って .NET Framework 4.0 アプリのクラッシュダンプから stack trace を得る

 

スタックトレースだけを取得したい場合、cdb.exe をワンライナーで使う手もあると思います。

 

cdb.exe は「Windows 用デバッグ ツール (WinDbg)」セットアップに含まれています。

Windows 用デバッグ ツールのダウンロード を参照して、入手してください。

 

X64 Debuggers And Tools-x64_en-us.msi を既定の設定でセットアップした場合:

"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe"

X86 Debuggers And Tools-x86_en-us.msi を既定の設定でセットアップした場合:

"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe"


参考: CDB のコマンドライン オプション

コマンドライン 64-bit 用:

"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe" -z "C:\ProgramData\Wazato\Wazato.exe.21264.dmp" -aC:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll -lines -c "!sos.printexception -nested -lines" < nul

コマンドライン 32-bit 用 :

"C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe" -z "C:\ProgramData\Wazato\Wazato.exe.21264.dmp" -aC:\Windows\Microsoft.NET\Framework\v4.0.30319\SOS.dll -lines -c "!sos.printexception -nested -lines" < nul

出力:

Microsoft (R) Windows Debugger Version 10.0.22621.1 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.


Loading Dump File [C:\ProgramData\Wazato\Wazato.exe.24684.dmp]
User Mini Dump File: Only registers, stack and portions of memory are available

Symbol search path is: srv*
Executable search path is:
Windows 10 Version 19044 MP (4 procs) Free x64
Product: WinNt, suite: SingleUserTS
Edition build lab: 19041.1.amd64fre.vb_release.191206-1406
Machine Name:
Debug session time: Wed Jun  1 21:56:33.000 2022 (UTC + 9:00)
System Uptime: not available
Process Uptime: 0 days 0:00:04.000
...................................
Loading unloaded module list
.
----------------------------------------------------------------------------
The user dump currently examined is a minidump. Consequently, only a subset
of sos.dll functionality will be available. If needed, attaching to the live
process or debugging a full dump will allow access to sos.dll's full feature
set.
To create a full user dump use the command: .dump /ma <filename>
----------------------------------------------------------------------------
This dump file has an exception of interest stored in it.
The stored exception information can be accessed via .ecxr.
(606c.4a64): CLR exception - code e0434352 (first/second chance not available)
For analysis of this file, run !analyze -v
ntdll!NtWaitForMultipleObjects+0x14:
00007ff8`85f4d894 c3              ret
0:000> cdb: Reading initial command '!sos.printexception -nested -lines'
----------------------------------------------------------------------------
The user dump currently examined is a minidump. Consequently, only a subset
of sos.dll functionality will be available. If needed, attaching to the live
process or debugging a full dump will allow access to sos.dll's full feature
set.
To create a full user dump use the command: .dump /ma <filename>
----------------------------------------------------------------------------
Exception object: 0000000002f28178
Exception type:   System.Exception
Message:          例外が発生しました。
InnerException:   Wazato.WazatoException, Use !PrintException 0000000002f28030 to see more.
StackTrace (generated):
*** WARNING: Unable to verify checksum for Wazato.exe
    SP               IP               Function
    0000000000DCCB60 00007FF807220961 Wazato!Wazato.Program.Main(System.String[])+0xd1 [H:\Proj\Wazato\Wazato\Program.cs @ 12]

StackTraceString: <none>
HResult: 80131500

Nested exception -------------------------------------------------------------
Exception object: 0000000002f28030
Exception type:   Wazato.WazatoException
Message:          わざと例外です
InnerException:   <none>
StackTrace (generated):
    SP               IP               Function
    0000000000DCEE90 00007FF8072208FA Wazato!Wazato.Program.Main(System.String[])+0x6a [H:\Proj\Wazato\Wazato\Program.cs @ 17]

StackTraceString: <none>
HResult: 80131500

0:000> NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\atlmfc.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\ObjectiveC.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\concurrency.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\cpp_rest.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\stl.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\Windows.Data.Json.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\Windows.Devices.Geolocation.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\Windows.Devices.Sensors.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\Windows.Media.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\windows.natvis'
NatVis script unloaded from 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\Visualizers\winrt.natvis'

 

上記の朱色の部分が、関心の高い部分です。スタックトレースが含まれています。

ただ、一部、行数目 (Program.cs @ 12) の特定に不正確さが見られます。


ソースコード:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Wazato
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            try
            {
                throw new WazatoException();
            }
            catch (Exception ex)
            {
                throw new Exception("例外が発生しました。", ex);
            }
        }
    }

    public class WazatoException : Exception
    {
        public WazatoException() : base("わざと例外です")
        {

        }
    }
}


因みに、普通に実行した場合のエラー出力はこのようなものです。こちらの行数目の特定は正確です:

H:\Proj\Wazato\Wazato\bin\Debug\Wazato.exe

ハンドルされていない例外: System.Exception: 例外が発生しました。 ---> Wazato.WazatoException: わざと例外です
   場所 Wazato.Program.Main(String[] args) 場所 H:\Proj\Wazato\Wazato\Program.cs:行 17
   --- 内部例外スタック トレースの終わり ---
   場所 Wazato.Program.Main(String[] args) 場所 H:\Proj\Wazato\Wazato\Program.cs:行 21

 

そもそも、アプリがクラッシュする前であれば $exception.ToString() でスタックトレースを取得できます。


dobon.net で紹介されている「AppDomain.UnhandledExceptionイベントを使用する方法
」を用いて、アプリがクラッシュする前に、スタックトレースをどこかへ保存する、という手もあると思いました。

世間のクラッシュ情報回収系ツール (App Center Crashes など) では、このような手法を用いているものと思われます。

 

イベントビューアでは (Application → Windows Error Reporting):

障害バケット 、種類 0
イベント名: CLR20r3
応答: 使用不可
Cab ID: 0

問題の署名:
P1: Wazato.exe
P2: 1.0.0.0
P3: c9a37b6c
P4: Wazato
P5: 1.0.0.0
P6: c9a37b6c
P7: 1
P8: 14
P9: System.Exception
P10:

添付ファイル:
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERD9ED.tmp.mdmp
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERDA8A.tmp.WERInternalMetadata.xml
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERDA9B.tmp.xml
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERDAA8.tmp.csv
\\?\C:\ProgramData\Microsoft\Windows\WER\Temp\WERDAD8.tmp.txt

これらのファイルは次の場所にある可能性があります:
\\?\C:\ProgramData\Microsoft\Windows\WER\ReportArchive\AppCrash_Wazato.exe_90677cdd904a7f2b1a386721e7dac5b230783d62_abbc5ab9_2f417abf-d27d-48a1-8f57-3d9dffd9b30e

分析記号:
解決策を再確認中: 0
レポート ID: 06931fdf-f9c9-4609-8100-1ca1b16625a5
レポートの状態: 97
ハッシュされたバケット:
Cab GUID: 0

 

イベントビューアでは (Application → Application Error):

障害が発生しているアプリケーション名: Wazato.exe、バージョン: 1.0.0.0、タイム スタンプ: 0xc9a37b6c
障害が発生しているモジュール名: KERNELBASE.dll、バージョン: 10.0.19041.1706、タイム スタンプ: 0x458acb5b
例外コード: 0xe0434352
障害オフセット: 0x0000000000034fd9
障害が発生しているプロセス ID: 0x6df0
障害が発生しているアプリケーションの開始時刻: 0x01d875b84b1582d2
障害が発生しているアプリケーション パス: H:\Proj\Wazato\Wazato\bin\Debug\Wazato.exe
障害が発生しているモジュール パス: C:\WINDOWS\System32\KERNELBASE.dll
レポート ID: 06931fdf-f9c9-4609-8100-1ca1b16625a5
障害が発生しているパッケージの完全な名前:
障害が発生しているパッケージに関連するアプリケーション ID: 

 

イベントビューアでは (Application → .NET Runtime):

アプリケーション:Wazato.exe
フレームワークのバージョン:v4.0.30319
説明: ハンドルされない例外のため、プロセスが中止されました。
例外情報:Wazato.WazatoException
   場所 Wazato.Program.Main(System.String[])

例外情報:System.Exception
   場所 Wazato.Program.Main(System.String[])

 

CDB と .NET Framework アプリの CPU アーキテクチャ (x86, x64) が異なる場合は "SOS does not support the current target architecture." が出力されます:

0:000> cdb: Reading initial command '!sos.printexception'
SOS does not support the current target architecture.

 

Visual Studio 2022 で .NET Framework 4.x アプリのクラッシュダンプを開く

 Visual Studio 2022 で .NET Framework 4.x アプリのクラッシュダンプを開く

「ファイル」 →「開く」→「ファイル」

右下のファイルタイプを「ダンプ ファイル (*.dmp; *.mdmp; *.hdmp)」にします。

ミニダンプ・完全ダンプ いずれかを開くと概要が表示されます。

つぎに「診断分析の実行」をクリックします。

すると、あたかもデバッグを始めて、デバッグ・ブレークしたかのような画面になります。これで、スタックトレースが得られます。クラッシュ発生の要因に近づけるのではないでしょうか。

勿論、アプリの継続や実行はできません…

[Shift]+[F9] キーで、クイックウォッチを展開しましょう。

例外の詳細を見たい場合は $exception を評価します。

以下はミニダンプ診断時のものです。


「'mscorlib' のメタデータが無効です。ミニダンプをデバッグする場合は、新しいヒープ付きミニダンプを収集し、式を再度評価することによって、この問題を解決できることがあります。」というエラーが幾多表示されます。

以下は完全ダンプ時のものです。


こちらは評価の表示がきちんとできました。


.NET Framework 4.x アプリのクラッシュダンプを作成したい

.NET Framework 4.x アプリのクラッシュダンプを作成したい

レジストリにキーを追加すると、ダンプファイルが得られるようです。

Windows 10 Pro (version 21H2) で確認しました。

参考記事:

以下のレジストリキーの配下に wazato.exe のような exe ファイル名のキーを作成します:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps

詳細は: ユーザーモード ダンプの収集

上図の状態で .reg ファイルをエクスポートするとこのような感じです:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\wazato.exe]
"DumpCount"=dword:00000003
"DumpType"=dword:00000002
"DumpFolder"=hex(2):25,00,50,00,52,00,4f,00,47,00,52,00,41,00,4d,00,44,00,41,\
  00,54,00,41,00,25,00,5c,00,57,00,61,00,7a,00,61,00,74,00,6f,00,00,00
DumpType:

0 = カスタム
1 = ミニ
2 = 完全

レジストリを設定後 .NET Framework のアプリがクラッシュすると .dmp ファイルができました。

クラッシュすると Windows Error Reporting の画面が出現します。
ここで「キャンセル」をクリックして閉じても .dmp は作成されました。

また…
「デバッグ」を選択して、デバッガーが起動し終わった後、
「プログラムの終了」を選択して、アプリを終了した後にも .dmp は作成されました。

単純な容量比較では…

ミニダンプ 11,842 KB
完全ダンプ 102,691 KB

10 倍の差がありました。throw するだけの簡単なコンソールアプリでしたが。

続きはこちら…

 

2021年5月14日金曜日

Microsoft Access フォーム名に「半角カナ」、の件

Access を利用中に、つぎのようなエラーメッセージが表示されたら、疑わしいです…

パターン 1

データベースに含まれている VBA プロジェクトを読み取れないため、データベースを開く事ができません。データベースを開くには VBA プロジェクトを削除する必要があります。VBA プロジェクトを削除するとモジュール、フォーム、およびレポートからすべてのコードが削除されます。

データベースを開いて VBA プロジェクトを削除する前に、バックアップ コピーを作成することをお勧めします。


データベースのバックアップ コピーを作成する場合は、[キャンセル] をクリックしてください。バックアップ コピーを作成しないでデータベースを開き、VBA プロジェクトを削除する場合は、[OK] をクリックしてください。

パターン 2

このデータベース内の VBA モジュールはエラーを含んだ状態で保存された可能性があります。Access ではこのモジュールを回復できますが、まずこのデータベースをバックアップする必要があります。データベースをバックアップするためにこの操作を取り消すには、[キャンセル] をクリックしてください。


バックアップ コピーが既にある場合は、[OK] をクリックしてください。データベースを開くときに、モジュールが正しいかどうか調べてください。正しくない場合は、最新のバックアップに戻してください。

危惧
  • Access によって Access データベースの VBA データが一部損傷され、回復できない可能性
  • バックアップからの復元が必要となる可能性

対策例

回避例

  • msaccess.exe の互換設定を Windows 8 に変更する
  • Windows OS の NLS バージョンを 6.3 から 6.2 に変更する