Prompt user when resolving clipboard contents (#123)

* Add a prompt to confirm if user wants to resolve clipboard contents.
* Optionally remember the user's choice.
* Update README and supporting images.
* Update assembly versions to 2.3.0.0.
* Update the latest release date.
This commit is contained in:
Arvind Shyamsundar 2023-06-19 09:18:43 -07:00 коммит произвёл GitHub
Родитель ac6c0fd29a
Коммит 003b85544c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
15 изменённых файлов: 115 добавлений и 58 удалений

15
BUILDING.md Normal file
Просмотреть файл

@ -0,0 +1,15 @@
# Building
* You will need Visual Studio 2022+ installed to build this solution.
* Access to nuget.org is needed to fetch and restore package dependencies. Please note the terms of usage for the following dependency files:
* symsrv.dll and dbghelp.dll (originally part of the x64 / AMD64 Windows Debugger package, part of Windows SDK and many other tools) are used under the terms published [here](https://docs.microsoft.com/en-us/legal/windows-sdk/redist#debugging-tools-for-windows).
* The DIA SDK files - msdia140.dll and msdia140.dll.manifest - are components of Visual Studio 2022 used under the terms as published [here](https://docs.microsoft.com/en-us/visualstudio/releases/2022/redistribution).
* [XELite](https://www.nuget.org/packages/Microsoft.SqlServer.XEvent.XELite/) is used for importing Microsoft SQL Extended Event (XEL) files.
* Other packages from Microsoft .NET family are used as well.
* Tests are implemented using [MSTest v2](https://docs.microsoft.com/en-us/visualstudio/test/mstest-update-to-mstestv2?view=vs-2022#why-upgrade-to-mstestv2). Please try to ensure all the tests are passing before submitting a PR.
* Prior to running tests, you need to execute the [downloadsyms.ps1](./Tests/TestCases/downloadsyms.ps1) file once as shown below:
``` cmd
cd .\SQLCallStackResolver\Tests\TestCases
powershell < .\downloadsyms.ps1
```
Monitor for any warnings shown by the script and address them if needed.
* When a Pull Request (PR) is submitted for this project, there is a [GitHub Actions workflow](./.github/workflows/build.yml) which will build the project and run tests. PRs cannot merge till the workflow succeeds.

Просмотреть файл

@ -7,7 +7,6 @@ global using System;
global using System.Collections.Concurrent;
global using System.Collections.Generic;
global using System.Collections.Immutable;
global using System.Diagnostics;
global using System.Diagnostics.Contracts;
global using System.Globalization;
global using System.IO;

Просмотреть файл

@ -11,6 +11,6 @@
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("782bbd60-ee45-43cd-8a4f-0505efe4ff1a")]
[assembly: AssemblyVersion("2.2.0.0")]
[assembly: AssemblyFileVersion("2.2.0.0")]
[assembly: AssemblyVersion("2.3.0.0")]
[assembly: AssemblyFileVersion("2.3.0.0")]
[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]

Просмотреть файл

@ -1,6 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<appSettings>
@ -15,4 +20,8 @@
<dependentAssembly><assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" /><bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" /></dependentAssembly>
</assemblyBinding>
</runtime>
<userSettings><Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver.Properties.Settings>
<setting name="promptForClipboardPaste" serializeAs="String"><value>True</value></setting>
<setting name="choiceForClipboardPaste" serializeAs="String"><value>False</value></setting>
</Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver.Properties.Settings></userSettings>
</configuration>

Просмотреть файл

@ -26,6 +26,20 @@ namespace Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver {
}
private void ResolveCallStackFromClipboardButton_Click(object sender, EventArgs e) {
if (Properties.Settings.Default.promptForClipboardPaste) {
var resProceed = MessageBox.Show(this, "Proceeding will paste the contents of your clipboard and attempt to resolve them. Are you sure?", "Proceed with paste from clipboard", MessageBoxButtons.YesNo, MessageBoxIcon.Information);
var resRememberChoice = MessageBox.Show(this, "Should we remember your choice for the future?", "Save your choice?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
Properties.Settings.Default.promptForClipboardPaste = (resRememberChoice == DialogResult.No);
Properties.Settings.Default.choiceForClipboardPaste = (resProceed == DialogResult.Yes);
Properties.Settings.Default.Save();
}
if (!Properties.Settings.Default.choiceForClipboardPaste) {
this.UpdateStatus((Properties.Settings.Default.promptForClipboardPaste ? "You chose to not" : "You have chosen never to") + " paste clipboard contents. Nothing to do!");
return;
}
callStackInput.Clear();
finalOutput.Clear();
callStackInput.Text = Clipboard.GetText();

Просмотреть файл

@ -11,7 +11,7 @@
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
[assembly: Guid("f65803b0-f5b2-4fa4-99b2-c91600e77e26")]
[assembly: AssemblyVersion("2.2.0.0")]
[assembly: AssemblyFileVersion("2.2.0.0")]
[assembly: AssemblyVersion("2.3.0.0")]
[assembly: AssemblyFileVersion("2.3.0.0")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]

31
GUI/Properties/Settings.Designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,31 @@
namespace Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()][global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()][global::System.Diagnostics.DebuggerNonUserCodeAttribute()][global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool promptForClipboardPaste {
get {
return ((bool)(this["promptForClipboardPaste"]));
}
set {
this["promptForClipboardPaste"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()][global::System.Diagnostics.DebuggerNonUserCodeAttribute()][global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool choiceForClipboardPaste {
get {
return ((bool)(this["choiceForClipboardPaste"]));
}
set {
this["choiceForClipboardPaste"] = value;
}
}
}
}

Просмотреть файл

@ -0,0 +1 @@
<?xml version='1.0' encoding='utf-8'?><SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver.Properties" GeneratedClassName="Settings"><Profiles /><Settings><Setting Name="promptForClipboardPaste" Type="System.Boolean" Scope="User"><Value Profile="(Default)">True</Value></Setting><Setting Name="choiceForClipboardPaste" Type="System.Boolean" Scope="User"><Value Profile="(Default)">False</Value></Setting></Settings></SettingsFile>

Просмотреть файл

@ -70,6 +70,11 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="SQLBuildsForm.cs">
<SubType>Form</SubType>
</Compile>
@ -94,6 +99,10 @@
<SubType>Designer</SubType>
</EmbeddedResource>
<None Include="App.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Engine\SQLCallstackResolver.Engine.csproj">

Просмотреть файл

@ -4,82 +4,60 @@
SQLCallStackResolver is a sample tool provided for users who want to resolve the raw call stack information provided by Microsoft SQL Server, to a "symbolized" form with function names. This helps in self-service diagnostics of certain SQL Server issues. Please note that this sample tool is provided AS-IS - see [SUPPORT](SUPPORT.md) for details.
# Installation
Please refer to the [Releases](../../releases) section for a ready-to-run set of binaries. Release 2.0 is self-contained, XCOPY / UnZip and run - no external installation required other than .NET Framework 4.7.2 or above. We now include the [msdia140.dll](https://blogs.msdn.microsoft.com/calvin_hsia/2016/07/30/whats-in-a-pdb-file-use-the-debug-interface-access-sdk/) and [XELite](https://www.nuget.org/packages/Microsoft.SqlServer.XEvent.XELite/) as part of the ZIP file with the rest of the binaries. Note that SQLCallStackResolver 2.0 is released as purely for 64-bit the Intel/AMD family (x64) Windows OS. Windows 10 or Windows Server 2016 are the minimum required OS versions. SQLCallStackResolver uses registration-free COM activation of msdia140.dll, so no additional configuration is needed.
Other Microsoft components used, and their associated terms of use are documented in the [Building](#building) section.
Please refer to the [Releases](../../releases) section for a ready-to-run set of binaries. This sample tool does not have any other requirements other than .NET Framework 4.7.2 or above. SQLCallStackResolver requires Windows 10, Windows Server 2016, or higher. Other Microsoft components used, and their associated terms of use are documented in the [Building](./BUILDING.md) file.
# Usage
SQLCallStackResolver takes callstacks as input. These callstacks can be obtained from a variety of SQL Server sources:
SQLCallStackResolver takes raw call stack text as input. These call stacks can be obtained from a variety of SQL Server sources:
* Individual callstack extracted from XML output from the XEvents DMVs or .XEL files. These represent individual call stack frames in the with `module+offset` notation
* Multiple callstacks in Histogram XML markup (multiple-instance case of above).
* Older format with just virtual addresses [[1]](#footnote1). This is typically what you would get when viewing a .XEL file (containing callstack events) using SQL Server Management Studio.
* `dll!OrdinalNNN` frames [[2]](#footnote2). This is a very rare case and typically an outcome of operator error (enabling a trace flag to symbolize call stacks but forgot to use PDBs).
* Individual call stack extracted from XML output from the XEvents DMVs or .XEL files. These represent individual call stack frames in the with `module+offset` notation
* Multiple call stacks in Histogram XML markup (multiple-instance case of above).
* Older format with just virtual addresses [[1]](#footnote1). This is typically what you would get when viewing a .XEL file (containing call stack events) using SQL Server Management Studio.
* `dll!OrdinalNNN` frames [[2]](#footnote2). This is a very rare case and typically an outcome of user error (for example, enabling a trace flag to symbolize call stacks, without having the required PDBs).
* Output from SQLDumper (SQLDumpNNNN.TXT file) - at least the sections which have stack frames [[5]](#footnote5)
* The new XML callstack format which is available in SQL Server 2022 CTP 2.0 and above. [[example]](#usage-example-3)
* The new XML format provided by the `callstack_rva` action in SQL Server 2022 CTP 2.0 and above. [[example]](#usage-example-3)
The tool comes with a pre-populated example in the textboxes, just follow that example with your real-world stack(s). In all cases you must provided a symbol search path [[3]](#footnote3),[[4]](#footnote4). If a symbol server is used in this path, there must be corresponding information in the input callstack to help identify which PDBs to get from the symbol server. See [[6]](#footnote6).
To use the tool, follow the sequence shown on the GUI:
* Step 0 is usually not required for most cases. More details on the options are [[here]](#footnote1).
* Step 1 is where you can optionally import SQL Extended Events (XEL) files to populate the call stack input area on the left side of the tool.
* Step 2 is a needed one. In all cases you must provided a symbol search path [[3]](#footnote3),[[4]](#footnote4). If a symbol server is used in this path, there must be corresponding information in the input call stack to help identify which PDBs to get from the symbol server. See [[6]](#footnote6).
* Two buttons are provided for executing the (final) "Step 3" on the GUI:
* The first button processes the input that was already manually entered (or pasted) into the call stack input area.
* The second button copies the current contents of the clipboard, into the call stack input area on the tool. If you click this button, for privacy reasons you will be prompted to confirm that you indeed want to use the clipboard contents. You can optionally remember your choice for pasting clipboard content, in which case that choice is stored in a file called `user.config` under the `C:\Users\YOURUSERNAME\AppData\Local\Microsoft_Corporation\SQLCallStackResolver.exe_Url_STRONGNAME\VERSION` folder. If you want to reset the choice, you can delete the `user.config` file and restart the tool.
## Usage example #1
This is a trivial case, where the user enters the callstack in `module+offset` notation, and selects one of the pre-populated list of SQL builds to download symbols. The user then clicks the Resolve Callstacks button, and obtains the symbolized output in the right-hand side textbox.
This is a simple case, where you enter the call stack in `module+offset` notation, and select one of the pre-populated list of SQL builds to download symbols. You then click the Resolve Callstacks button, and obtain the symbolized output in the right-hand side textbox.
![](images/1_ModOffset_Text.gif)
## Usage example #2
This is a typical use case, where the user imports events from a XEL file. Because the XEL file does not have the module base addresses, the user first inputs those. They then select one of the pre-populated list of SQL builds to download symbols and finally click the Resolve Callstacks button to obtain the symbolized output in the right-hand side textbox.
This is a typical use case, where you can import events from a XEL file. Because the XEL file does not have the module base addresses, you have to first provide those module base addresses. You can then select one of the pre-populated list of SQL builds to download symbols and finally click the Resolve Callstacks button to obtain the symbolized output in the right-hand side textbox.
![](images/2_XEL_Address.gif)
## Usage example #3
With SQL Server 2022 CTP 2.0 and above, callstacks returned by the XE functions are represented in a XML format, with PDB symbol information provided inline for each frame. With this format for callstacks, you can alternatively specify the symbol path as a symbol server, as documented in the [WinDbg help](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/symbol-path#using-a-symbol-server). An example of this is shown below.
With SQL Server 2022 CTP 2.0 and above, call stacks returned by the XE functions are represented in a XML format, with PDB symbol information provided inline for each frame. With this format for call stacks, you can alternatively specify the symbol path as a symbol server, as documented in the [WinDbg help](https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/symbol-path#using-a-symbol-server). An example of this is shown below. Note the usage of the "Paste clipboard contents" button in this example.
![](images/3_SQL2022_format.gif)
## Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
## Building
* You will need Visual Studio 2022+ installed to build this solution.
* Access to NuGet is needed to fetch and restore package dependencies.
* If needed, you may also need to manually obtain the current versions of the following files:
* symsrv.dll and dbghelp.dll (from the x64 / AMD64 Windows Debugger package, part of Windows SDK and many other tools) are used under the terms published [here](https://docs.microsoft.com/en-us/legal/windows-sdk/redist#debugging-tools-for-windows).
* msdia140.dll and msdia140.dll.manifest are components of Visual Studio 2022 used under the terms as published [here](https://docs.microsoft.com/en-us/visualstudio/releases/2022/redistribution).
* Tests are implemented using [MSTest v2](https://docs.microsoft.com/en-us/visualstudio/test/mstest-update-to-mstestv2?view=vs-2022#why-upgrade-to-mstestv2). Please try to ensure that tests are passing before submitting a PR.
* Prior to running tests, you need to execute the [downloadsyms.ps1](./Tests/TestCases/downloadsyms.ps1) file once as shown below:
``` cmd
cd .\SQLCallStackResolver\Tests\TestCases
powershell < .\downloadsyms.ps1
```
Monitor for any warnings shown by the script and address them if needed.
* When a PR is submitted, there is a GitHub Actions workflow which will build the project and run tests. PRs cannot merge till the workflow succeeds.
# Notes
## Notes on usage
1. <a name="footnote1"></a>In this case you need to populate the Base Addresses with the output of the following query from the actual SQL instance when the XE was captured:
``` sql
```sql
select name, base_address from sys.dm_os_loaded_modules where name not like '%.rll'
```
2. <a name="footnote2"></a>When dealing with frames having `OrdinalNNN`, you need to press the Module Paths button where you will be prompted to enter the path to a folder containing the modules (typically, DLLs) involved. For example you can point to C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Binn for SQL 2019.
3. <a name="footnote3"></a>This has to be path to a folder or a set of such paths (can be UNC as well) each separated with a semicolon (;). Use the checkbox to specify if sub-folders need to be checked in each case. If multiple paths might contain matching PDBs, the first path from the left which contained the PDB wins. There is no means to know if the PDB is matched with the build that your are using - you need to ensure that the folder path(s) are correct!
4. <a name="footnote4"></a>To obtain public PDBs for major SQL releases, PowerShell scripts are available in the SQLCallStackResolver [Wiki](https://github.com/arvindshmicrosoft/SQLCallStackResolver/wiki/Obtaining-symbol-files-(.PDB)-for-SQL-Server-Releases)
5. <a name="footnote5"></a>The tool does not strip out just the 'Short Stack Dump' sections; instead it will preserve non-callstack text as-is.
6. <a name="footnote6"></a>It is possible to use a symbol server in the symbol search path. For example, the symbol search path can be specified as `srv*c:\syms*https://msdl.microsoft.com/download/symbols`. In such a case, the corresponding callstack input should have a minimal set of details included in separate lines, each containing comma-separated values. Each of these lines should include the following minimum set of information:
* Module name, for example `ntdll.dll`
* PDB file name, for example `ntdll.pdb`
* PDB GUID, for example `1EB9FACB-04C7-3C5D-EA71-60764CD333D0`
* The very last comma-separated field will be taken as the PDB Age.
6. <a name="footnote6"></a>It is possible to use a symbol server in the symbol search path. For example, the symbol search path can be specified as `srv*c:\syms*https://msdl.microsoft.com/download/symbols`. In such a case, the corresponding call stack input should have symbol metadata included in separate lines, each containing comma-separated values. Each of these lines should include the following minimum set of information:
* Module name, for example `ntdll.dll`
* PDB file name, for example `ntdll.pdb`
* PDB GUID, for example `1EB9FACB-04C7-3C5D-EA71-60764CD333D0`
* The very last comma-separated field will be taken as the PDB Age.
Alternatively, this information can be provided as XML <frame> elements, with each `frame` element having attributes called `module`, `pdb`, `guid`, and `age` which fully describe the matching PDB information for that frame. This is the format which was introduced first in SQL Server 2022 CTP 2.0.
Alternatively, this information can be provided as XML <frame> elements, with each `frame` element having attributes called `module`, `pdb`, `guid`, and `age` which fully describe the matching PDB information for that frame. This is the format which was introduced first in SQL Server 2022 CTP 2.0. When symbol metadata is included (in either CSV or XML format), it is parsed and used to retrieve PDBs from the symbol server specified. If matching PDBs are not found locally for whatever reason (wrong paths, wrong metadata, failed download etc.), the symbol resolution step will just return back the original raw input.
When such information is included (in either CSV or XML format), it is parsed and used to retrieve PDBs from the symbol server specified. If matching PDBs are not found locally for whatever reason (wrong paths, wrong metadata, failed download etc.), the symbol resolution step will just return back the original raw input.
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. For technical instructions on how to build and test this project, see [Building](./BUILDING.md).
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Trademarks
# Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow [Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general). Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

Просмотреть файл

@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Files", "Files", "{551EED46
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
.github\workflows\build.yml = .github\workflows\build.yml
BUILDING.md = BUILDING.md
.github\workflows\codeql-analyze.yml = .github\workflows\codeql-analyze.yml
latestrelease.txt = latestrelease.txt
LICENSE = LICENSE

Двоичные данные
images/1_ModOffset_Text.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 820 KiB

После

Ширина:  |  Высота:  |  Размер: 1.5 MiB

Двоичные данные
images/2_XEL_Address.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.6 MiB

После

Ширина:  |  Высота:  |  Размер: 4.0 MiB

Двоичные данные
images/3_SQL2022_format.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 611 KiB

После

Ширина:  |  Высота:  |  Размер: 3.0 MiB

Просмотреть файл

@ -1 +1 @@
2022-12-05 00:00
2023-06-19 00:00