Skip to content

Commit 7055f8a

Browse files
authored
Extract event log for potential crash info (microsoft#5807)
## Change We are seeing occasional errors during test setup that might be a crash. These started happening when 1.11.510 became the latest version. To better understand this and any future crashes that might occur, grab the Application event log from the pipeline. Also grabs the GA winget logs since that is what is being used during this potential crash. Also enables the unit tests to write a minidump if they crash, since that happened randomly during one of the builds for this PR.
1 parent ac226ee commit 7055f8a

File tree

6 files changed

+114
-22
lines changed

6 files changed

+114
-22
lines changed

.github/actions/spelling/expect.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ ERRORONEXIT
161161
errstr
162162
ESRB
163163
etl
164+
evtx
164165
ewgp
165166
ewgs
166167
execustom
@@ -323,6 +324,7 @@ MBH
323324
MBs
324325
mday
325326
mdmp
327+
mdmpto
326328
MDs
327329
megamorf
328330
microsoftentraid
@@ -614,6 +616,7 @@ wincodec
614616
windir
615617
windowsdeveloper
616618
winerror
619+
winevt
617620
wingdi
618621
wingetconfigroot
619622
wingetcreate

azure-pipelines.yml

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ jobs:
340340
341341
- pwsh: |
342342
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
343-
PsExec -accepteula -s -i $(buildOutDir)\AppInstallerCLITests\AppInstallerCLITests.exe -logto $(artifactsDir)\AICLI-Unpackaged-System.log -s -r junit -o $(artifactsDir)\TEST-AppInstallerCLI-Unpackaged-System.xml
343+
PsExec -accepteula -s -i $(buildOutDir)\AppInstallerCLITests\AppInstallerCLITests.exe -logto $(artifactsDir)\AICLI-Unpackaged-System.log -mdmpto $(artifactsDir)\AICLI-Unpackaged-System.mdmp -s -r junit -o $(artifactsDir)\TEST-AppInstallerCLI-Unpackaged-System.xml
344344
displayName: Run Unit Tests Unpackaged Under System Context
345345
workingDirectory: '$(buildOutDir)\AppInstallerCLITests'
346346
condition: succeededOrFailed()
@@ -354,7 +354,7 @@ jobs:
354354
displayName: Run Unit Tests Packaged
355355
inputs:
356356
filePath: 'src\AppInstallerCLITests\Run-TestsInPackage.ps1'
357-
arguments: '-Args "~[pips]" -BuildRoot $(buildOutDir) -PackageRoot $(packageLayoutDir) -LogTarget $(artifactsDir)\AICLI-Packaged.log -TestResultsTarget $(artifactsDir)\TEST-AppInstallerCLI-Packaged.xml -ScriptWait'
357+
arguments: '-Args "~[pips]" -BuildRoot $(buildOutDir) -PackageRoot $(packageLayoutDir) -LogTarget $(artifactsDir)\AICLI-Packaged.log -MdmpTarget $(artifactsDir)\AICLI-Packaged.mdmp -TestResultsTarget $(artifactsDir)\TEST-AppInstallerCLI-Packaged.xml -ScriptWait'
358358
workingDirectory: 'src'
359359
condition: succeededOrFailed()
360360

@@ -482,6 +482,34 @@ jobs:
482482
- powershell: Get-Process LocalhostWebServer | Stop-Process
483483
displayName: Stop LocalhostWebServer
484484
condition: succeededOrFailed()
485+
486+
- task: PowerShell@2
487+
displayName: 'Copy GA WinGet Log to artifacts folder'
488+
inputs:
489+
targetType: 'inline'
490+
script: |
491+
$source = "$env:LocalAppData\Packages\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe\LocalState\DiagOutputDir"
492+
$destination = "$(artifactsDir)\GA_WinGet_Logs"
493+
if (Test-Path $source) {
494+
Copy-Item -Path $source -Destination $destination -Recurse -Force
495+
} else {
496+
Write-Host "WinGet logs not found at $source"
497+
}
498+
condition: succeededOrFailed()
499+
500+
- task: PowerShell@2
501+
displayName: 'Copy Application Event Logs to Artifacts'
502+
inputs:
503+
targetType: 'inline'
504+
script: |
505+
$source = "$env:SystemRoot\System32\winevt\Logs\Application.evtx"
506+
$destination = "$(artifactsDir)\Application.evtx"
507+
if (Test-Path $source) {
508+
Copy-Item -Path $source -Destination $destination -Force
509+
} else {
510+
Write-Host "Application event log not found at $source"
511+
}
512+
condition: succeededOrFailed()
485513

486514
- task: PublishPipelineArtifact@1
487515
displayName: Publish Pipeline Artifacts

src/AppInstallerCLITests/Run-TestsInPackage.ps1

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
location relative to this script.
1313
.PARAMETER LogTarget
1414
The file path to log to.
15+
.PARAMETER MdmpTarget
16+
The path to write a minidump to if the tests crash.
1517
.PARAMETER TestResultsTarget
1618
The file path to place the test result file in.
1719
.PARAMETER Args
@@ -31,6 +33,9 @@ param(
3133
[Parameter(Mandatory=$false)]
3234
[string]$LogTarget,
3335

36+
[Parameter(Mandatory=$false)]
37+
[string]$MdmpTarget,
38+
3439
[Parameter(Mandatory=$false)]
3540
[string]$TestResultsTarget,
3641

@@ -93,6 +98,14 @@ if (![String]::IsNullOrEmpty($LogTarget))
9398
Write-Host "Using LogTarget = $LogTarget"
9499
}
95100

101+
if (![String]::IsNullOrEmpty($MdmpTarget))
102+
{
103+
$Local:temp = Split-Path -Parent $MdmpTarget
104+
$Local:temp = Resolve-Path $Local:temp
105+
$MdmpTarget = Join-Path $Local:temp (Split-Path -Leaf $MdmpTarget)
106+
Write-Host "Using MdmpTarget = $MdmpTarget"
107+
}
108+
96109
if (![String]::IsNullOrEmpty($TestResultsTarget))
97110
{
98111
$Local:temp = Split-Path -Parent $TestResultsTarget
@@ -123,6 +136,15 @@ else
123136
$Local:TestArgs = $Local:TestArgs + " -logto ""$LogTarget"""
124137
}
125138

139+
if ([String]::IsNullOrEmpty($MdmpTarget))
140+
{
141+
$Local:TestArgs = $Local:TestArgs + " -mdmp"
142+
}
143+
else
144+
{
145+
$Local:TestArgs = $Local:TestArgs + " -mdmpto ""$MdmpTarget"""
146+
}
147+
126148
if (![String]::IsNullOrEmpty($TestResultsTarget))
127149
{
128150
$Local:TestArgs = $Local:TestArgs + " -s -r junit -o ""$TestResultsTarget"""

src/AppInstallerCLITests/main.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
#include <AppInstallerLogging.h>
55
#include <AppInstallerFileLogger.h>
66
#include <Public/AppInstallerTelemetry.h>
7-
#include <Telemetry/TraceLogging.h>
7+
#include <Telemetry/TraceLogging.h>
8+
#include <winget/Debugging.h>
89
#include "TestCommon.h"
910
#include "TestSettings.h"
1011

@@ -87,13 +88,14 @@ int main(int argc, char** argv)
8788
}
8889
else if ("-logto"s == argv[i])
8990
{
90-
++i;
91-
Logging::FileLogger::Add(std::filesystem::path{ argv[i] });
91+
if (++i < argc)
92+
{
93+
Logging::FileLogger::Add(std::filesystem::path{ argv[i] });
94+
}
9295
}
9396
else if ("-tdd"s == argv[i])
9497
{
95-
++i;
96-
if (i < argc)
98+
if (++i < argc)
9799
{
98100
TestCommon::TestDataFile::SetTestDataBasePath(argv[i]);
99101
hasSetTestDataBasePath = true;
@@ -107,6 +109,17 @@ int main(int argc, char** argv)
107109
{
108110
keepSQLLogging = true;
109111
}
112+
else if ("-mdmp"s == argv[i])
113+
{
114+
Debugging::EnableSelfInitiatedMinidump();
115+
}
116+
else if ("-mdmpto"s == argv[i])
117+
{
118+
if (++i < argc)
119+
{
120+
Debugging::EnableSelfInitiatedMinidump(std::filesystem::path{ argv[i] });
121+
}
122+
}
110123
else
111124
{
112125
args.push_back(argv[i]);

src/AppInstallerCommonCore/Debugging.cpp

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,7 @@ namespace AppInstaller::Debugging
1414

1515
struct SelfInitiatedMinidumpHelper
1616
{
17-
SelfInitiatedMinidumpHelper() : m_keepFile(false)
18-
{
19-
m_filePath = Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation);
20-
m_filePath /= c_minidumpPrefix.data() + ('-' + Utility::GetCurrentTimeForFilename() + c_minidumpExtension.data());
21-
22-
m_file.reset(CreateFile(m_filePath.wstring().c_str(), GENERIC_READ | GENERIC_WRITE,
23-
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr));
24-
THROW_LAST_ERROR_IF(!m_file);
25-
26-
SetUnhandledExceptionFilter(UnhandledExceptionCallback);
27-
}
17+
SelfInitiatedMinidumpHelper() = default;
2818

2919
~SelfInitiatedMinidumpHelper()
3020
{
@@ -57,6 +47,30 @@ namespace AppInstaller::Debugging
5747
return EXCEPTION_CONTINUE_SEARCH;
5848
}
5949

50+
SelfInitiatedMinidumpHelper& Enable(const std::filesystem::path& filePath = {})
51+
{
52+
std::call_once(m_enableFlag, [&]()
53+
{
54+
if (filePath.empty())
55+
{
56+
m_filePath = Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation);
57+
m_filePath /= c_minidumpPrefix.data() + ('-' + Utility::GetCurrentTimeForFilename() + c_minidumpExtension.data());
58+
}
59+
else
60+
{
61+
m_filePath = filePath;
62+
}
63+
64+
m_file.reset(CreateFile(m_filePath.wstring().c_str(), GENERIC_READ | GENERIC_WRITE,
65+
FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr));
66+
THROW_LAST_ERROR_IF(!m_file);
67+
68+
SetUnhandledExceptionFilter(UnhandledExceptionCallback);
69+
});
70+
71+
return *this;
72+
}
73+
6074
void WriteMinidump()
6175
{
6276
std::thread([&]() {
@@ -66,20 +80,25 @@ namespace AppInstaller::Debugging
6680
}
6781

6882
private:
83+
std::once_flag m_enableFlag;
6984
std::filesystem::path m_filePath;
7085
wil::unique_handle m_file;
71-
std::atomic_bool m_keepFile;
86+
std::atomic_bool m_keepFile{ false };
7287
};
7388
}
7489

7590
void EnableSelfInitiatedMinidump()
7691
{
77-
// Force object creation and thus enabling of the crash detection.
78-
SelfInitiatedMinidumpHelper::Instance();
92+
SelfInitiatedMinidumpHelper::Instance().Enable();
93+
}
94+
95+
void EnableSelfInitiatedMinidump(const std::filesystem::path& filePath)
96+
{
97+
SelfInitiatedMinidumpHelper::Instance().Enable(filePath);
7998
}
8099

81100
void WriteMinidump()
82101
{
83-
SelfInitiatedMinidumpHelper::Instance().WriteMinidump();
102+
SelfInitiatedMinidumpHelper::Instance().Enable().WriteMinidump();
84103
}
85104
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33
#pragma once
4+
#include <filesystem>
45

56
namespace AppInstaller::Debugging
67
{
78
// Enables a self initiated minidump on certain process level failures.
9+
// Only the first call to EnableSelfInitiatedMinidump has any effect.
810
void EnableSelfInitiatedMinidump();
911

12+
// Enables a self initiated minidump on certain process level failures.
13+
// Creates the minidump in the given location.
14+
// Only the first call to EnableSelfInitiatedMinidump has any effect.
15+
void EnableSelfInitiatedMinidump(const std::filesystem::path& filePath);
16+
1017
// Forces the minidump to be written.
1118
void WriteMinidump();
1219
}

0 commit comments

Comments
 (0)