Trouble Shooting

Alex Maitland edited this page Feb 9, 2017 · 31 revisions

Using the Chromium Embedded Framework(CEF) is not an easy task by any stretch of the imagination. It's a complex process fitting something as powerful and feature rich as the entire Chrome browser into as small as possible Windows DLL for others to make use of in their own programs.

Because of this complexity things frequently can go wrong, and to many developers who are just used to plugging components together it can seem like the world in front of them has just fallen into a huge crater.

It doesn't have to be like this though, The CefSharp community realize that folks are going to have issues, and they do what they can to help, since they do this voluntarily however they may not always be there when you need them to be.

As a result this page is being added to the Wiki in order to help you help yourself when facing problems using CefSharp.

Initially the page is going to be split into sections, starting with coverage of Windows Forms (WinForms) and at a later date any WPF specific notes too.

Even though the page is going to be split however, much of what applies to WinForms does also apply to WPF. This means that WPF users should also refer to the WinForms specific notes too as these will still be beneficial to helping them solve their issues.

General Troubleshooting

1) Platform Target Version 51.0.0 added support for the AnyCPU target, see https://github.com/cefsharp/CefSharp/issues/1714 for details. You can still of course select either x86 or x64 when using the NuGet packages (This is the simplest option).

2) Dependencies still not showing up after adding the Nuget packages? Try closing Visual Studio (not just the solution) and then reopen, some of the Nuget black magic used to import the VC++ dll's doesn't always play nice with Visual Studio. Switching to the newer method of package restore as outlined in http://blog.davidebbo.com/2014/01/the-right-way-to-restore-nuget-packages.html will typically fix the problem permanently.

Troubleshooting WinForms installations

The biggest problem that seems to be encountered by developers using CefSharp in their own applications is that the browser does not appear when programmed to do so.

There are a number of reasons for this, some are already outlined elsewhere, but will be repeated here for completeness.

1) Did you initialize the CefSharp Libraries correctly?

Before instances of ChromiumWebBrowser are created the underlying framework needs to be initialized. If you don't need to configure any settings then this will be done automatically for you by the framework. See https://github.com/cefsharp/CefSharp/wiki/General-Usage#initialize-and-shutdown for more details.

Should you need to specify some settings, like a CachePath (so the browser persists cookies, etc) then you'll need to manually initialize. In essence however it boils down to creating a settings object, ensuring that the browser sub process property is set correctly, then calling the main initialization function using these settings.

The following code will do this for you:

Cef.Initialize(new CefSettings() { CachePath = "Cache" } );

Remember to also include "using CefSharp;" at the beginning of your code file, so that the correct references can be resolved.

You can easily add this to your "Program.cs" file in a WinForms application as follows:

using System;
using System.Windows.Forms;
using CefSharp;

namespace CefBlog3
{
  static class Program
  {
    [STAThread]
    static void Main()
    {
      Cef.Initialize(new CefSettings() { CachePath = "Cache" } );

      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Application.Run(new Form1());
    }
  }
}

Remembering to substitute 'Form1' for the name of your main form class. In the MinimalExample repository there is a "CefSharp.MinimalExample.WinForms" that should serve as a template to how this is done correctly.

2) Where are you calling the initial invocation of the browser?

If you need to have the browser not display at startup, then you simply need to pass in an empty string when creating the object, and all you'll receive is a blank browser window.

As above, the simple WinForms demo shows how to do this correctly, using the following bit of code:

browser = new ChromiumWebBrowser("www.google.com")
{
  Dock = DockStyle.Fill,
};
toolStripContainer.ContentPanel.Controls.Add(browser);

Replace the 'www.google.com' string with something like 'string.Empty' if you don't want to load anything initially.

You'll notice in the above example, that the browser is loaded into a 'toolStripContainer' this is also an important point to note, and is covered in the next check point.

3) Where are you trying to render the browser?

There are many examples out there on the internet that show the browser being added to an application's window by adding it directly to the controls collection of the form.

In the older versions of CefSharp this was the main accepted way of doing things, and on the whole of it this does still work.

However, in some edge cases when doing things this way the browser does not render correctly, often re-appearing when the form is re-sized leading to the belief that the problem cause is actually point number 2 above.

It's therefore recommended that you render the browser into a WinForms panel or similar object, there are two very good reasons for this.

a) The panel allows you to control the browser size, it will never overflow a panel component, but if attached to a form will attempt to use the full form surface often appearing behind regular win-form controls.

b) You can hide the browser (For example if you didn't want to show it at start up) by simply hiding the panel

Rendering into a common component gives you much more control over the render surface allowing you to do many more things not possible when adding direct to the forms controls.

4) Have you included 'CefSharp.BrowserSubprocess.exe' in your output folder?

This one usually seems quite mysterious.

Everything appears to work correctly, all the required code is present, and yet still nothing appears. No exceptions are thrown and everything looks normal.

If the EXE is missing from your output folder, but all the DLL's and other dependencies are present then the WinForms subsystem will not throw any kind of error indicating anything is wrong, this is one of those problems that can have you going around in ever decreasing circles until the penny suddenly drops.

While your checking for the existence of the EXE stub, it's also worth making sure that you have all the other dependencies there too, some of them are optional and are only used when you ask the browser to do certain things.

Usually however if a DLL dependency is missing, this does result in a missing file exception being thrown.

Still no joy?

If you checked all 4 points above and still can't get the browser output to appear, then there are a couple of other things you can check for a possible cause.

a) In your application output folder be that Debug or Release, you'll find a plain text file called 'Debug.Log' in many cases that will actually have in it the error that CEF encountered when trying to initialize.

b) The developer tools. Add a button to your form and make a call to "browser.ShowDevTools()". If you can see a document has loaded and you have a DOM in there, then your problem is a display output one and your most likely problem is one of not setting 'Dock' correctly, or some other setting is causing the browser to render offscreen/headless. If you get a blank tool window, or no tool window at all, then CefSharp has failed to initialize correctly, so you have a set-up issue to troubleshoot.

Tooltips don't appear

You need to modify your app.manifest to include a dependency on Microsoft.Windows.Common-Controls like in the WinForms example app: https://github.com/cefsharp/CefSharp/blob/master/CefSharp.WinForms.Example/app.manifest#L15

Troubleshooting WPF installations

Blurry text

Try enabling ClearType in WPF (source: #1045):

browser.BrowserSettings = new BrowserSettings()
{
    OffScreenTransparentBackground = false
};

Troubleshooting Graphics, Video or Performance Problems

GPU acceleration is on by default. This creates a dependency on graphics cards and their drivers, which are notoriously unreliable. If you experience slow or quirky rendering, try:

  • Disable GPU VSync: var settings = new CefSharp.CefSettings(); settings.CefCommandLineArgs.Add("disable-gpu-vsync", "1"); Cef.Initialize(settings);
  • Disable GPU acceleration: settings.CefCommandLineArgs.Add("disable-gpu", "1");
  • Confirm the command line args have filtered through by starting your app and navigating to this URL: chrome://version
  • Try your app on a different machine, preferably with a different video card.
  • Open chrome://gpu/ in Chrome to see what it says about your GPU.

Application freezing on shutdown

No-nos:

  • Do not create COM objects on CEF callback threads. This will cause shutdown to freeze.
  • If you call Cef.Shutdown() explicitly, do not do so on a background thread - this may cause a freeze. It must be called on the main thread.
  • Calling Application.Exit() and then Environment.Exit() will cause a hang - just wait for Application.Exit() to finish.

Things to try:

Related issues:

Unmanaged crashes (when the process dies)

This section covers debugging and diagnosing native/unmanaged crashes in libcef.dll, BrowserSubProcess, and C++ code in general. When these crashes occur, the C# exception handler does not get called and your application exits. Windows logs an Error event, which you can find the details of using Windows Event Viewer. CEF also has it's own log file, which by default is called Debug.log, it will be in your applications executing directory e.g. bin directory.

Loading native symbols, for easier diagnosis

Download the Release Symbols that match the CEF version you're using from http://opensource.spotify.com/cefbuilds/index.html (or https://cefbuilds.com/ for older version), then extract libcef.dll.pdb into the executing folder (the same directory as libcef.dll). It's very important that you match the exact version of CEF. To identity which version of CEF your actually using, easiest way is to check your packages.config file, look for the cef.redist.x86 package, it's version will be something like 3.2526.1362, that's the exact version of CEF you'll need to download for comparison. You can also open chrome://version in the browser to determine the version.

As of version 49 you can download CefSharp symbols see #1610. If you see an exception in libcef.dll then focus on getting the CEF release symbols.

To analyse a crash after the fact check your user profiles AppData\Local\CrashDumps folder, their is likely a mini crashdump. See the next section for more details.

You may find it useful to attach the debugger to CefSharp.BrowserSubProcess.exe, add the following command line option. When the message box opens, attach the debugger to the matching process (should be named Chromium Renderer). If you have the libcef.dll.pdb in the same folder as libcef.dll it should load the symbols successfully an when the app crashes hopefully you will have a more detailed crash stack trace.

settings.CefCommandLineArgs.Add("renderer-startup-dialog", "1");

Getting a crash report from a customer's computer

Check the AppData\Local\CrashDumps folder for CefSharp.BrowserSubProcess.exe dumps. Best to load the symbols for libcef.dll (See above).

To manually generate a crash dump your user can utilize Procdump like this:

procdump -e -ma <binaryname or PID>  <dumpfile.dmp> 

If your user is on Win 8.1 or later they can use the -r option for a bit more efficiency in creating the memory dump.

If that command line doesn't do the trick, you might need to use procdump's -e1 option instead of -e.

You then load the memory dump into Visual Studio or WinDbg and see what the call stack for the CEF issue is. (You can google about how to deal with memory dumps and .Net if you haven't done it before.) Our recommendation is to use Visual Studio 2013+ with integrated WinDbg, or WinDbg.

Mozilla - How to get a stacktrace with WinDbg

Will look something like "c:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe" -y . -c ".ecxr;k30;q" -z my_dump_file.dmp

Starting with 55.0.0 the new crashpad handler is used, see https://bitbucket.org/chromiumembedded/cef/issues/1995/migrate-from-breakpad-to-crashpad for details. You can log crash dumps to a folder or server if you so choose.

Exception code 0x4000001f (debugger breakpoint)

Exception code: 0x4000001f

This is the exception code that occurs when the int 3 instruction is executed.

CEF is known to do this when you violate its threading restrictions about what executes on which CEF thread. See CEF Threads for the list of CEF threads.

If you are lost as to what caused this, reproduce the crash in Visual Studio with symbols loaded.

VS Debug Unmanaged Exceptions

Javascript Memory Debugging

Still having problems?

Ask on Gitter Chat - Make sure you provide as much detail as possible.