VSTO Add-in causing Word to crash on application close - vsto

I have created numerous VSTO Add-Ins over the last few years. They are running against many versions of MS Word (but mostly MS Word 2016). I share a common library of code that I add to when working on each new project.
I've noticed sporadic crashing when closing Word. It's the bad crash that requires task manager to clean up:
"Microsoft Word has stopped working" "Close the program?"
It happens very rarely. Rare enough that I shrug it off as "Crazy MS Word..".
My colleagues have also noticed the problem a number of times. Often it went away after I built them a new assembly (with little or no code changes..)
The situation is now more serious, seeing as a client has report the issue while testing. Interestingly, on the client machine the crashing is reproducible.
I've spent the last few days commenting out code in an attempt to identify the problem. I thought I had the problem isolated to some Ribbon Visibility code, however it turns out I was just going round in circles..
I've tried getting a crash dump via:
adsplus.exe -crash -pn winword.exe -o c:\Temp
After running this command I am unable to reproduce the error.
I noticed that changing my log4net tracing level from WARN to DEBUG caused the reproducible error to stop. I'm not confident that it's fixed however.
Is it a timing issue? Any idea how I can find the cause of my problem?
-- Edit --
#Thomas Weller, I was able to get a crash dump using https://learn.microsoft.com/en-us/sysinternals/downloads/procdump
Will see how I go interpreting it.

I was able to get a memory dump using ProcDump and it showed that a Thread exception was occurring as Word was closing.
Turns out I when I thought I was using the same dispatcher object, I was creating a new one each time.
I had code similar to:
Dispatcher dispatcher = System.Windows.Application.Current.Dispatcher;
O.CustomXMLParts parts = null;
dispatcher.WaitUntilApplicationIdle(() =>
{
parts = doc.CustomXMLParts.SelectByNamespace(Office.Namespace);
});
...
public static void WaitUntilApplicationIdle(this Dispatcher dispatcher, Action action)
{
dispatcher.Invoke(action, DispatcherPriority.ApplicationIdle);
}
And I had to ensure that the application was correctly set up as Word started:
void ThisAddIn_Startup(object sender, EventArgs e)
{
EnsureApplication();
}
void EnsureApplication()
{
if (System.Windows.Application.Current == null)
new Application()
{
ShutdownMode = ShutdownMode.OnExplicitShutdown
};
}

Related

CefSharp.BrowserSubProcess.Core WCF pipe failure

Our application is using CefSharp version 73.1.130. The issue only occurs on a small number of internal workstations within our organization. Worth noting, we are also seeing the same error with CefSharp version 92. Another strange thing is that it the issue is consistent, but only when the web apps are launched through certain navigations. Other navigations work consistently for these users.
We use RegisterJsObject to register a javascript object with browser. If I understand correctly, asynchronous binding is preferred moving forward.
The issue presents as strange/unexpected behavior in the hosted web application due to failure to retrieve context from the host WinForms application. The behavior would suggest a failure to register/bind the js object with the RegisterJsObject method. However, that method is not throwing an exception.
Enabled Cef logging showed the following error:
ERROR:JavascriptRootObjectWrapper.cpp(34)] IBrowserProcess is null, unable to bind object
After looking into the code, it appears the location that the value pointed to by "IBrowserProcess" is set is in WcfEnabledSubProcess::OnBrowserCreated (https://github.com/cefsharp/CefSharp/blob/cefsharp/73/CefSharp.BrowserSubprocess.Core/WcfEnabledSubProcess.cpp). I was able to build CefSharp and add additional logging to that method.
On my workstation (I'm not affected by the issue), I get through OnBrowserCreated with no exceptions. However, on my coworkers workstation I see the following line is failing:
...
channelFactory->Open();
auto browserProcess = channelFactory->CreateChannel();
auto clientChannel = ((IClientChannel^)browserProcess);
try
{
clientChannel->Open(); <-- FAILS
browser->ChannelFactory = channelFactory;
browser->BrowserProcess = browserProcess;
}
catch (Exception^)
{
}
}
With the error:
There was an error reading from the pipe: The pipe has been ended. (109, 0x6d)
Has anyone seen this issue before? I'm not sure how much this will help, but does anyone know if it's possible to enable WCF tracing with the CefSharp.BrowserSubProcess.exe. I have been trying this, but no luck so far.

Force FirebaseCrashlytics print logs to console

Is it possible to force FirebaseCrashlytics to print the log messages to console prior google buy them (and make shit as always) it was possible using the fabric api. But now seems these methods were removed.
Is there any way to do for the android sdk?
Short Answer
IT IS IMPOSSIBLE (USING FIREBASECRASHLYTICS SDK)
Complete Answer
It is a shame that prior to Google buys Crashlytics, watch the log messages on development console was an easy task to do. But now these methods were removed.
The whole problem is, if I'm in the development environment and want to follow the code execution (by watching the log messages) Crashlytics won't show them... I need to intentionally cause an crash, then wait a time for it be uploaded to dashboard them start hunting for the registers among maybe thousands of others... (non sense)
I filled a bug report for firebase
https://github.com/firebase/firebase-android-sdk/issues/3005
For those who don't want wait to google fix their shit there is a workaround:
FirebaseApp.initializeApp(this);
if (BuildConfig.DEBUG) {
try {
Field f = FirebaseCrashlytics.class.getDeclaredField("core");
f.setAccessible(true);
CrashlyticsCore core = (CrashlyticsCore) f.get(FirebaseCrashlytics.getInstance());
f = CrashlyticsCore.class.getDeclaredField("controller");
f.setAccessible(true);
Object controler = f.get(core);
f = controler.getClass().getDeclaredField("logFileManager");
f.setAccessible(true);
f.set(controler, new LogFileManager(null, null) {
#Override
public void writeToLog(long timestamp, String msg) {
super.writeToLog(timestamp, msg);
System.out.println(msg);
}
});
FirebaseCrashlytics.getInstance().log("test");
} catch (Exception e) {
}
}
The code above is replacing the field that was supposed to write the log messages to a file (AND ACTUALLY DOES NOTHING) by a new class which does all the previous one (NOTHING) but prints on the fly all messages logged.
ATTENTION
I've tested this on firebase-analytics:19.0.1 and this will only on versions of the lib with the same fields names
IT WON'T WORK IN OBFUSCATED BUILD, if you obfuscate the code in DEBUG mode the code will break (unless you add the proper rules to proguard)
If this topic reaches google engineers is very likely they will remove/obfuscate the code for next versions
google...

Error in 3rd Party Library Causing Hanging in Release

My main program is an ASP.Net Core Web API that has a third party library in a hosted service. The third party library is initializing fine but then it throws some errors sometime throughout its lifecycle.
It supplies a way of hooking into the object via an event and will let me know what the error is so that I can handle it but it still throws in the third party library..
Since I am handling the event myself, I want to completely ignore these errors that are occurring in this library. Is there anyway that I can do that?
I have already tried to add a global exception handler and the strange thing is, this exception handler never gets hit. The only way I can get the exception is to set my exception settings to break when CLR exceptions happen like in the picture above
This does not crash my program. For some reason, the program just hangs. When I turn off CLR exceptions in the "Break when thrown" window, then the program runs just fine. It is almost like visual studio is doing something special to handle these types of exceptions that a console version cannot do
The only way that I can seem to get a console version of this running, is attach a visual studio debugger to the process and when the exception is hit, press the green play button "Continue" in visual studio. Otherwise the application just seems to hang on the exception being thrown by the third party library.
The application will run fine as long as visual studio is attached and the CLR break exceptions are not checked
Does anyone know how to make sure that these types of exceptions do not hang the program when released?
Additional Info:
The third party library is a .NET Framework 4 library
The Asp.Net project is targetting "net5.0-windows"
The 3rd party class is probably using multi-threading
if it helps, this is how I am creating the third party class
Handling NullReferenceException in release code(Official advice)
It's usually better to avoid a NullReferenceException than to handle it after it occurs. Handling an exception can make your code harder to maintain and understand, and can sometimes introduce other bugs. A NullReferenceException is often a non-recoverable error. In these cases, letting the exception stop the app might be the best alternative.
However, there are many situations where handling the error can be useful:
1.Your app can ignore objects that are null. For example, if your app retrieves and processes records in a database, you might be able to ignore some number of bad records that result in null objects. Recording the bad data in a log file or in the application UI might be all you have to do.
2.You can recover from the exception. For example, a call to a web service that returns a reference type might return null if the connection is lost or the connection times out. You can attempt to reestablish the connection and try the call again.
3.You can restore the state of your app to a valid state. For example, you might be performing a multi-step task that requires you to save information to a data store before you call a method that throws a NullReferenceException. If the uninitialized object would corrupt the data record, you can remove the previous data before you close the app.
4.You want to report the exception. For example, if the error was caused by a mistake from the user of your app, you can generate a message to help them supply the correct information. You can also log information about the error to help you fix the problem. Some frameworks, like ASP.NET, have a high-level exception handler that captures all errors to that the app never crashes; in that case, logging the exception might be the only way you can know that it occurs.
So after days of research I've finally found an event to hook into to give you error messages from ANY source no matter how many level deep you go in threads.
AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
Hooking into this event it will allow you to see errors from every library and every thread. Simply place the above into you program.cs (or whatever startup file you have) and magically you will be flooded with all of the unknown errors from all of the 3rd party libraries you thought were once flawless.
private static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
{
Console.WriteLine(e.Exception.Message, e.Exception.StackTrace);
}
I've done so with the following method and low and behold. The third party library was trying to reference another project in an unsafe way and throwing an error. Since I didn't need this other project reference the built exe did not have a reference to this assembly because I had no direct reference to it in the project (darn smarty pants who need to optimize everything). I was able to run correctly because in my visual studio solution, I had a reference to this other project. So the third party library would pick up on it as soon as visual studio connected with the debugger through some sort of dark magic.
Anyways, I made a throw away object that used the project that was required and the issue was solved.
I really hope that this helps someone else and saves them the days it took me to find this.

RuntimeBinderException when using dynamic object even though Just My Code checked

I have some very simple code that is throwing a RuntimeBinderException
var mockString = "{ Status: \"Aware\" }";
dynamic d = JsonConvert.DeserializeObject(mockString);
OutputString = d.Status;
I have read a lot of the similar questions like this one and the answer given is that it is a first chance exception and I should check "Just My Code' in Tools > Options > Debugging.
I have the code in two solutions. One works and one does not. Both have the "Just My Code" option checked. Both are using the same version of Newtonsoft.Json (8.0.3)
This is VS 2015, Xamarin Forms running on Android.
In my case I had the debugger break on first chance exceptions for RuntimeBinderException, but when running on Android it was shown as "unhandled" exception in the debugger.
That threw me off for a moment, but after I found out I could continue running without problems I realised it was actually a first chance exception. After turning break on first chance exception of for RuntimeBinderException (since I wasn't interested in those at the time) it worked as expected.
To turn break on first chance exceptions on/off check the menu: Debug -> Windows -> Exception settings

NUnit async test causing AppDomainUnloadedException

I have a .NET 4.5 WCF service with async operations. I have integration tests which constructs the service host using NetNamedPipeBinding and hits the operation via a client.
However, each test like this always causes NUnit to report the following:
System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain.
This can happen if the test(s) started a thread but did not stop it.
Make sure that all the threads started by the test(s) are stopped before completion.
Everything looks ok to me. Can anyone see what might be causing this? I have a complete code sample on GitHub: https://github.com/devlife/codesamples
I'm having the same problem. It looks as if the issue are "lenient" completion port threads (in the ThreadPool) that have been used by WCF to handle async IO.
When ServiceHost.Close() is used, it will signal all those threads that work is done, but they won't go away immediately, that is, they may outlive the end of the ServiceHost.Close() operation. Thus, the "shutdown" procedure races with the actual AppDomain unloading induced by NUnit due to the end of the test run.
Basically, a simple Thread.Sleep(<a couple of seconds>) after a ServiceHost.Close() "fixes" this :-)
After much searching around on the internet I couldn't find a robust solution for this issue (for a selection of similar issues, not all due to the same cause though, google "unit test appdomainunloadedexception"), short of having some way to suppress this warning itself.
I tried different bindings and transports (includind the NullTransport), but to no avail.
In the end I settled with this "solution":
static void PreventPrematureAppDomainUnloadHack()
{
//
// When NUnit unloads the test AppDomain, the WCF started IO completion port threads might
// not have exited yet.
// That leads to AppDomainUnloadedExceptions being raised after all is said and done.
// While native NUnit, ReSharper oder TestDriven.NET runners don't show these, VSTest (and
// TFS-Build) does. Resulting in very annoying noise in the form of build/test warnings.
//
// The following code _attempts_ to wait for all completion port threads to end. This is not
// an exact thing one can do, however we mitigate the risk of going wrong by several factors:
// (1) This code is only used during Unit-Tests and not for production code.
// (2) It is only called when the AppDomain in question is about to go away anway.
// So the risk of someone starting new IO threads while we're waiting is very
// low.
// (3) Finally, we have a timeout in place so that we don't wait forever if something
// goes wrong.
//
if (AppDomain.CurrentDomain.FriendlyName.StartsWith("test-domain-", StringComparison.Ordinal))
{
Console.WriteLine("AppDomainUnloadHack: enabled (use DbgView.exe for details).");
Trace.WriteLine(string.Format("AppDomainUnloadHack: enabled for domain '{0}'.", AppDomain.CurrentDomain.FriendlyName));
AppDomain.CurrentDomain.DomainUnload += (sender, args) =>
{
int activeIo;
var sw = Stopwatch.StartNew();
var timeout = TimeSpan.FromSeconds(3);
do
{
if (sw.Elapsed > timeout)
{
Trace.WriteLine("AppDomainUnloadHack: timeout waiting for threads to complete.");
sw.Stop();
break;
}
Thread.Sleep(5);
int maxWorkers;
int availWorkers;
int maxIo;
int availIo;
ThreadPool.GetMaxThreads(out maxWorkers, out maxIo);
ThreadPool.GetAvailableThreads(out availWorkers, out availIo);
activeIo = maxIo - availIo;
Trace.WriteLine(string.Format("AppDomainUnloadHack: active completion port threads: {0}", activeIo));
} while (activeIo > 0);
Trace.WriteLine(string.Format("AppDomainUnloadHack: complete after {0}", sw.Elapsed));
};
}
}
The timeout of 3 seconds is totally arbitrary and so is the wait of 5ms between each retry. Sometimes I do get a "timeout", but most of the time it works.
I make sure that this code is called once for every test assembly (i.e. through a static ctor of a referenced type).
As usual in such cases YMMV.