DTF and PDB files for better error logging

5 messages Options
Embed this post
Permalink
Rob MacFadyen

DTF and PDB files for better error logging

Reply Threaded More More options
Print post
Permalink
Hey all,

I've been doing a few C# based custom actions and find the DTF "stuff" very
easy to use and it works quite well.

However I'm wondering if there is anyway to include my custom action DLL's
PDB file with the actual CA? If the .PDB was extracted and copied to the
same location as the .DLL then if the .DLL throws an unhandled exception the
stack trace would include an exact line number reference.

I find that having an exact line number reference to be exceptionally useful
when diagnosing problems. Especially null object errors that can creep in at
unexpected places. Have an exact line number reduces the possible places a
single function could be failing because of a null reference error.

Having this would avoid needed to add logging after each and every line
(which is overkill and brute force... but if I need to know exactly where a
function is crapping out there's not much choice).

For example here is a custom action that installs a list of assemblies and
their associated PDB's into the GAC:

/// <summary>
/// Install a list of files into the GAC.
/// </summary>
/// <param name="session"></param>
/// <returns>ActionResult.Success if the files where installed successfull.
/// Otherwise the action has thrown an unexpected exception.</returns>
[CustomAction]
public static ActionResult InstallFilesToGac(Session session)
{
    //
    // Show a nice status message
    //
    session.Message(InstallMessage.ActionStart, new Record(new object[] {
"Installing assemblies in the Global Assembly Cache" }));
    session.Log("Installing assemblies in the Global Assembly Cache");

    //
    // Build a reference using specific values
    //  - The reference is used by the GAC for reference count purposes.
Each
    //    installer that installs a given assembly should provide its own
    //    reference. When all references have been removed from the GAC
    //    then the assembly will actually be removed from the GAC.
    //
    string ReferenceGuid = "{USE_YOUR_OWN_GUID}";
    string ReferenceDescription = "Your Installer";
    InstallReference Reference = new
InstallReference(InstallReferenceGuid.OpaqueGuid, ReferenceGuid,
ReferenceDescription);

    //
    // Process each file
    //
    session.Log("Number of files to install: {0}",
session.CustomActionData.Values.Count);
    foreach (string Filename in session.CustomActionData.Values)
    {
        //
        // Ought not happen but rather safe than sorry
        //
        if (!string.IsNullOrEmpty(Filename))
        {
            //
            // Add the assembly to the GAC
            //
            session.Log("Install in the GAC: {0}", Filename);
            AssemblyCache.InstallAssembly(Filename, Reference,
AssemblyCommitFlags.Default);

            //
            // If a PDB exists then copy it to the GAC as well
            //
            string PdbFilename = Path.ChangeExtension(Filename, "pdb");
            if (!File.Exists(PdbFilename))
            {
                session.Log("No PDB was found: {0}", PdbFilename);
            }
            else
            {
                session.Log("PDB found: {0}", PdbFilename);
                string StrongName = GetStrongTypeName(Filename);
                session.Log("Assembly strong name: {0}", StrongName);
                string GacFileLocation =
AssemblyCache.QueryAssemblyInfo(StrongName);
                session.Log("GAC location: {0}", GacFileLocation);
                string GacPDbFileLocation =
Path.ChangeExtension(GacFileLocation, "pdb");
                session.Log("PDB GAC location will be: {0}",
GacPDbFileLocation);
                File.Copy(PdbFilename, GacPDbFileLocation);
                session.Log("PDB copied to GAC");
            }
        }
    }

    //
    // Success
    //
    session.Log("All assemblies installed in the GAC");
    session.Log("Returning ActionResult.Success");
    return ActionResult.Success;
}


When I was first putting this together I was having trouble getting
parameters passed in and a couple of other problems... but debugging was
challenging. I couldn't get the actual debugger to work... and even if I had
I would still prefer to have the DTF runtime be able log the exact error
location.

So... any ideas on how to get a .PDB for a DTF custom action to be "carted
around" with the actual dll?

Regards,

Rob





------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
WiX-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/wix-users
Jason Ginchereau

Re: DTF and PDB files for better error logging

Reply Threaded More More options
Print post
Permalink
You can add additional items to the CA package by manually adding a CustomActionContents property to your project file. For example, to include your assembly PDB when building in debug mode:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
  <CustomActionContents>$(IntermediateOutputPath)$(AssemblyName).pdb</CustomActionContents>
</PropertyGroup>


-----Original Message-----
From: Rob MacFadyen [mailto:[hidden email]]
Sent: Wednesday, July 08, 2009 11:22 AM
To: [hidden email]
Subject: [WiX-users] DTF and PDB files for better error logging

Hey all,

I've been doing a few C# based custom actions and find the DTF "stuff" very
easy to use and it works quite well.

However I'm wondering if there is anyway to include my custom action DLL's
PDB file with the actual CA? If the .PDB was extracted and copied to the
same location as the .DLL then if the .DLL throws an unhandled exception the
stack trace would include an exact line number reference.

I find that having an exact line number reference to be exceptionally useful
when diagnosing problems. Especially null object errors that can creep in at
unexpected places. Have an exact line number reduces the possible places a
single function could be failing because of a null reference error.

Having this would avoid needed to add logging after each and every line
(which is overkill and brute force... but if I need to know exactly where a
function is crapping out there's not much choice).

For example here is a custom action that installs a list of assemblies and
their associated PDB's into the GAC:

/// <summary>
/// Install a list of files into the GAC.
/// </summary>
/// <param name="session"></param>
/// <returns>ActionResult.Success if the files where installed successfull.
/// Otherwise the action has thrown an unexpected exception.</returns>
[CustomAction]
public static ActionResult InstallFilesToGac(Session session)
{
    //
    // Show a nice status message
    //
    session.Message(InstallMessage.ActionStart, new Record(new object[] {
"Installing assemblies in the Global Assembly Cache" }));
    session.Log("Installing assemblies in the Global Assembly Cache");

    //
    // Build a reference using specific values
    //  - The reference is used by the GAC for reference count purposes.
Each
    //    installer that installs a given assembly should provide its own
    //    reference. When all references have been removed from the GAC
    //    then the assembly will actually be removed from the GAC.
    //
    string ReferenceGuid = "{USE_YOUR_OWN_GUID}";
    string ReferenceDescription = "Your Installer";
    InstallReference Reference = new
InstallReference(InstallReferenceGuid.OpaqueGuid, ReferenceGuid,
ReferenceDescription);

    //
    // Process each file
    //
    session.Log("Number of files to install: {0}",
session.CustomActionData.Values.Count);
    foreach (string Filename in session.CustomActionData.Values)
    {
        //
        // Ought not happen but rather safe than sorry
        //
        if (!string.IsNullOrEmpty(Filename))
        {
            //
            // Add the assembly to the GAC
            //
            session.Log("Install in the GAC: {0}", Filename);
            AssemblyCache.InstallAssembly(Filename, Reference,
AssemblyCommitFlags.Default);

            //
            // If a PDB exists then copy it to the GAC as well
            //
            string PdbFilename = Path.ChangeExtension(Filename, "pdb");
            if (!File.Exists(PdbFilename))
            {
                session.Log("No PDB was found: {0}", PdbFilename);
            }
            else
            {
                session.Log("PDB found: {0}", PdbFilename);
                string StrongName = GetStrongTypeName(Filename);
                session.Log("Assembly strong name: {0}", StrongName);
                string GacFileLocation =
AssemblyCache.QueryAssemblyInfo(StrongName);
                session.Log("GAC location: {0}", GacFileLocation);
                string GacPDbFileLocation =
Path.ChangeExtension(GacFileLocation, "pdb");
                session.Log("PDB GAC location will be: {0}",
GacPDbFileLocation);
                File.Copy(PdbFilename, GacPDbFileLocation);
                session.Log("PDB copied to GAC");
            }
        }
    }

    //
    // Success
    //
    session.Log("All assemblies installed in the GAC");
    session.Log("Returning ActionResult.Success");
    return ActionResult.Success;
}


When I was first putting this together I was having trouble getting
parameters passed in and a couple of other problems... but debugging was
challenging. I couldn't get the actual debugger to work... and even if I had
I would still prefer to have the DTF runtime be able log the exact error
location.

So... any ideas on how to get a .PDB for a DTF custom action to be "carted
around" with the actual dll?

Regards,

Rob





------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
WiX-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/wix-users


------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
WiX-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/wix-users
Rob MacFadyen

Re: DTF and PDB files for better error logging

Reply Threaded More More options
Print post
Permalink
In reply to this post by Rob MacFadyen
Jason,

I did this at one point but it was ineffective. On the installation side it
appeared that the .PDB was not being extracted to the temporary directory.

Are you certain this actually works and results in line numbers showing in
stack traces for unhandled exceptions in managed CA's?

Thanks,

Rob

-----Original Message-----

Date: Wed, 8 Jul 2009 12:32:07 -0700
From: Jason Ginchereau <[hidden email]>
Subject: Re: [WiX-users] DTF and PDB files for better error logging
To: "[hidden email]"
        <[hidden email]>
Message-ID:
       
<[hidden email]
soft.com>
       
Content-Type: text/plain; charset="us-ascii"

You can add additional items to the CA package by manually adding a
CustomActionContents property to your project file. For example, to include
your assembly PDB when building in debug mode:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
 
<CustomActionContents>$(IntermediateOutputPath)$(AssemblyName).pdb</CustomAc
tionContents>
</PropertyGroup>





------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
WiX-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/wix-users
Jason Ginchereau

Re: DTF and PDB files for better error logging

Reply Threaded More More options
Print post
Permalink
Just tried again and it does work -- I got line numbers in the stack trace in the log.

Note if you're referencing $(IntermediateOutputPath) like in my example below, you need to define the CustomActionContents property at the BOTTOM of your project file, because $(IntermediateOutputPath) isn't created until Microsoft.Common.targets is included.

At runtime the entire CA package is always extracted. At build time you should be able to see the PDB getting included in the CA package in the MSBuild output/log, it looks like this:

Modifying SfxCA.dll stub
Copying file version info from C:\temp\CATest\CustomAction1\obj\x86\Debug\Microsoft.Deployment.Samples.ManagedCA.dll to C:\temp\CATest\CustomAction1\obj\x86\Debug\Microsoft.Deployment.Samples.ManagedCA.CA.dll
Packaging files
    Microsoft.Deployment.Samples.ManagedCA.dll
    Microsoft.Deployment.WindowsInstaller.dll
    CustomAction.config
    Microsoft.Deployment.Samples.ManagedCA.pdb
MakeSfxCA finished: C:\temp\CATest\CustomAction1\obj\x86\Debug\Microsoft.Deployment.Samples.ManagedCA.CA.dll


-----Original Message-----
From: Rob MacFadyen [mailto:[hidden email]]
Sent: Wednesday, July 08, 2009 1:49 PM
To: [hidden email]
Subject: Re: [WiX-users] DTF and PDB files for better error logging

Jason,

I did this at one point but it was ineffective. On the installation side it
appeared that the .PDB was not being extracted to the temporary directory.

Are you certain this actually works and results in line numbers showing in
stack traces for unhandled exceptions in managed CA's?

Thanks,

Rob

-----Original Message-----

Date: Wed, 8 Jul 2009 12:32:07 -0700
From: Jason Ginchereau <[hidden email]>
Subject: Re: [WiX-users] DTF and PDB files for better error logging
To: "[hidden email]"
        <[hidden email]>
Message-ID:
       
<[hidden email]
soft.com>
       
Content-Type: text/plain; charset="us-ascii"

You can add additional items to the CA package by manually adding a
CustomActionContents property to your project file. For example, to include
your assembly PDB when building in debug mode:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<CustomActionContents>$(IntermediateOutputPath)$(AssemblyName).pdb</CustomActionContents>
</PropertyGroup>



------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
WiX-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/wix-users
Rob MacFadyen

Re: DTF and PDB files for better error logging

Reply Threaded More More options
Print post
Permalink
In reply to this post by Rob MacFadyen
Jason,

Just a quick follow up... this works exactly as you said :)

So nice to see a stack trace that includes the offending line number as
well.

I'm a huge fan of shipping .PDB's... the exact line number for unexpected
exceptions seems so very useful to me that any associated costs are well
worth the trouble.

Thanks very much!

Rob

ps. I had to upgrade VisualBuildPro from v6 to v7 for this to work (not sure
why but when it was building it would abort with an "null reference" style
of exception). Running msbuild from the command line worked... but for some
reason visualbuildpro just didn't like the .csproj file I guess.


-----Original Message-----
Date: Wed, 8 Jul 2009 18:51:59 -0400
From: "Rob MacFadyen" <[hidden email]>
Subject: Re: [WiX-users] WiX-users Digest, Vol 38, Issue 35
To: <[hidden email]>
Message-ID: <103a01ca001e$b4f9f760$1eede620$@com>
Content-Type: text/plain; charset="us-ascii"

Jason,

Thanks a ton! I'll dig into this again and see if I can make it work
(fingers crossed).

Regards,

Rob


-----Original Message-----

Date: Wed, 8 Jul 2009 14:38:38 -0700
From: Jason Ginchereau <[hidden email]>
Subject: Re: [WiX-users] DTF and PDB files for better error logging
To: "[hidden email]"
        <[hidden email]>
Message-ID:
       
<[hidden email]
soft.com>
       
Content-Type: text/plain; charset="us-ascii"

Just tried again and it does work -- I got line numbers in the stack trace
in the log.

Note if you're referencing $(IntermediateOutputPath) like in my example
below, you need to define the CustomActionContents property at the BOTTOM of
your project file, because $(IntermediateOutputPath) isn't created until
Microsoft.Common.targets is included.

At runtime the entire CA package is always extracted. At build time you
should be able to see the PDB getting included in the CA package in the
MSBuild output/log, it looks like this:

Modifying SfxCA.dll stub
Copying file version info from
C:\temp\CATest\CustomAction1\obj\x86\Debug\Microsoft.Deployment.Samples.Mana
gedCA.dll to
C:\temp\CATest\CustomAction1\obj\x86\Debug\Microsoft.Deployment.Samples.Mana
gedCA.CA.dll
Packaging files
    Microsoft.Deployment.Samples.ManagedCA.dll
    Microsoft.Deployment.WindowsInstaller.dll
    CustomAction.config
    Microsoft.Deployment.Samples.ManagedCA.pdb
MakeSfxCA finished:
C:\temp\CATest\CustomAction1\obj\x86\Debug\Microsoft.Deployment.Samples.Mana
gedCA.CA.dll




------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
WiX-users mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/wix-users