Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Procdump Arguments Changed #1700

Merged

Conversation

vagisha-nidhi
Copy link
Contributor

@vagisha-nidhi vagisha-nidhi commented Jul 26, 2018

Description

  1. Procdump options enhanced to handle crash scenorios in test host. STACK_OVERFLOW and ACCESS_VIOLATION filter added to get dumps on these crashes.
  2. Procdump is launched according to the process. The version of the procdump chosen is now depending on the bitness of the test host.
  3. Validated the scenarios on 32 bit OS as well as 64 bit OS.

Using procdump options as
For mini dump : -accepteula -e 1 -g -t -f STACK_OVERFLOW -f ACCESS_VIOLATION
For full dump : -accepteula -e 1 -g -t -ma -f STACK_OVERFLOW -f ACCESS_VIOLATION

-accepteula: Auto accept end-user license agreement
-e: Write a dump when the process encounters an unhandled exception. Include the 1 to create dump on first chance exceptions.
-g: Run as a native debugger in a managed process (no interop).
-t: Write a dump when the process terminates.
-ma: Full dump argument.
-f: Filter the exceptions.

@@ -42,5 +42,10 @@ internal static class Constants
/// Configuration key name for dump mode
/// </summary>
public const string DumpModeKey = "CollectDump";

/// <summary>
/// X86 Test Host Process Name
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: small casing X86 test host process name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

@@ -100,27 +99,38 @@ private static string BuildProcDumpArgs(int processId, string filename)
// -accepteula: Auto accept end-user license agreement
// -t: Write a dump when the process terminates.
// This will create a minidump of the process with specified filename
return "-accepteula -t " + processId + " " + filename + ".dmp";
return "-accepteula -e 1 -g -t -f STACK_OVERFLOW -f ACCESS_VIOLATION " + processId + " " + filename + ".dmp";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you write in detail in description what validations you did for these parameters check?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the description.

@@ -100,27 +99,38 @@ private static string BuildProcDumpArgs(int processId, string filename)
// -accepteula: Auto accept end-user license agreement
// -t: Write a dump when the process terminates.
// This will create a minidump of the process with specified filename
return "-accepteula -t " + processId + " " + filename + ".dmp";
return "-accepteula -e 1 -g -t -f STACK_OVERFLOW -f ACCESS_VIOLATION " + processId + " " + filename + ".dmp";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STACK_OVERFLOW and ACCESS_VIOLATION.. pick these values from a list. This list will contain only these 2 values for now but can be extended in future.

use a string builder to build the params.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Picking values from a list of exceptionFilters now.

if (!string.IsNullOrWhiteSpace(procdumpPath))
{
string filename = string.Empty;

if (this.environment.Architecture == PlatformArchitecture.X64)
// Launch procdump according to process architecture
if (this.environment.Architecture == PlatformArchitecture.X86 || processName == Constants.X86TestHostProcessName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we dont need this (this.environment.Architecture == PlatformArchitecture.X86) change as in 32 bit OS, we can't run 64 bit process. So only second condition (processName == Constants.X86TestHostProcessName) is sufficient.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the logic to determine if a process is 32 bit or not using ISWow64 Native method. We don't need to use processName == Constants.X86TestHostProcessName now

if (!string.IsNullOrWhiteSpace(procdumpPath))
{
string filename = string.Empty;

if (this.environment.Architecture == PlatformArchitecture.X64)
// Launch procdump according to process architecture
if (this.environment.Architecture == PlatformArchitecture.X86 || processName == Constants.X86TestHostProcessName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ProcDumpUtility should not be aware of what process it is taking dump. So dont use X86TestHostProcessName name directly here. Instead pass it via blameCollector.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using IsWow64.

{
filename = "procdump64.exe";
filename = "procdump.exe";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define these strings in constants

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes okay. Defined in Constants.

@@ -100,27 +99,38 @@ private static string BuildProcDumpArgs(int processId, string filename)
// -accepteula: Auto accept end-user license agreement
// -t: Write a dump when the process terminates.
// This will create a minidump of the process with specified filename
return "-accepteula -t " + processId + " " + filename + ".dmp";
return "-accepteula -e 1 -g -t -f STACK_OVERFLOW -f ACCESS_VIOLATION " + processId + " " + filename + ".dmp";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Output in verbose the command which we are passing to procdump.

/// Start process dump will start exe according to Test host Process
/// </summary>
[TestMethod]
public void StartProcessDumpWillStartExeCorrespondingToTestHostProcessIn64BitOS()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test the command which we are passing to procdump as well whether if its correct.

@@ -100,27 +99,38 @@ private static string BuildProcDumpArgs(int processId, string filename)
// -accepteula: Auto accept end-user license agreement
// -t: Write a dump when the process terminates.
// This will create a minidump of the process with specified filename
return "-accepteula -t " + processId + " " + filename + ".dmp";
return "-accepteula -e 1 -g -t -f STACK_OVERFLOW -f ACCESS_VIOLATION " + processId + " " + filename + ".dmp";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we okay with -g option @abhishkk

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kaadhina :
@vagisha-nidhi did extensive validations with known crash scenarios in different possible scenarios. Also she validated if the dump created is usable.

if (!string.IsNullOrWhiteSpace(procdumpPath))
{
string filename = string.Empty;

if (this.environment.Architecture == PlatformArchitecture.X64)
// Launch procdump according to process architecture
if (this.environment.Architecture == PlatformArchitecture.X86 || processName == Constants.X86TestHostProcessName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to find the bitness from process id instead of relying on process name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. On 64 bit OS, we are now determinig if a process is 32 bit by using just the process Id .

/// <param name="processHandle">Process Handle</param>
/// <returns>Bool for Is64Bit</returns>
public bool Is64Bit(IntPtr processHandle)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work for 32 bit os as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use this condition only for 64 bit

@@ -44,6 +44,16 @@ internal static class Constants
public const string DumpModeKey = "CollectDump";

/// <summary>
/// Procdump 32 bit version
/// </summary>
public const string ProcdumpProcessName = "procdump.exe";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: can remove Name from both variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the names

{
using System;

public interface INativeMethodsHelper
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this interface and make NativeMethodsHelper a static class as it has methods which are not using any class level variables. Also class seems more like helper class this making it static makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made it via interface to use it for unit tests.

using System.Runtime.InteropServices;
using Microsoft.TestPlatform.Extensions.BlameDataCollector.Interfaces;

public class NativeMethodsHelper : INativeMethodsHelper
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static

bool isWow64 = false;
if (!IsWow64Process(processHandle, out isWow64))
{
throw new Win32Exception();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why we are throwing Win32Exception? We are not catching it anywhere and there are no UTs for it. Can't we simply return the flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the exception thrown.

return !isWow64;
}

[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a comment for this method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments.

// -t: Write a dump when the process terminates.
// -ma: Full dump argument.
// -f: Filter the exceptions.
StringBuilder procDumpArgument = new StringBuilder("-accepteula -e 1 -g -t ");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice :)

{
filename = "procdump.exe";
if (this.nativeMethodsHelper.Is64Bit(this.processHelper.GetProcessHandleById(processId)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Can use ternary operator for reducing lines.

filename = this.nativeMethodsHelper.Is64Bit(this.processHelper.GetProcessHandleById(processId)) ?
                     Constants.Procdump64ProcessName :
                     Constants.ProcdumpProcessName;

/// </summary>
/// <param name="processId">process id</param>
/// <returns>Process Handle</returns>
IntPtr GetProcessHandleById(int processId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Method name can be simply GetProcessHandle

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the name to GetProcessHandle


public IntPtr GetProcessHandleById(int processId)
{
return Process.GetProcessById(processId).SafeHandle.DangerousGetHandle();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this DangerousGetHandle? Is it dangerous? :P
Can you write a comment as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comment for description.

}

procDumpArgument.Append($"{processId} {filename}.dmp");
return procDumpArgument.ToString();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we output this argument in logs as well (with info level may be)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Output in logs done

Copy link
Contributor

@abhishkk abhishkk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved with suggestions.

@vagisha-nidhi vagisha-nidhi force-pushed the ChangeInProcdumpOptions branch from e41957f to 65a3263 Compare August 1, 2018 08:48
Copy link
Contributor

@kaadhina kaadhina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@vagisha-nidhi vagisha-nidhi merged commit 3db5c0d into microsoft:master Aug 2, 2018
@vagisha-nidhi vagisha-nidhi deleted the ChangeInProcdumpOptions branch August 10, 2018 06:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants