Seeing the Unseeable

Abstract: An advanced workaround for visualizing graphs when the layout fails – and I use it to fix a bug in the UML Class Diagram.

Have you ever seen this message when trying to generate a very complex graph in Understand?

The dialog itself has gotten a lot more descriptive over the years and contains several things to try. But what do you do when none of the suggestions work?

There are several different layout engines in Understand. If the graph has a .dot export option, then the layout is done by Graphviz. The following tips work for any of the Graphviz graphs, which is most of the graphs in Understand.

The first thing to realize is only the layout failed. The graph itself still exists. So, even after receiving an error message, you can interact with the graph window. Specifically, you can export the dot file for the graph, even if no graph is visible. The next step is to get a better error message. Why did the graph fail?

As an example, I’m going to use a recent bug report with the UML Class Diagram. With a project based on ArduPilot ArduPlane (version 4.0.9) the UML Class Diagram gave the previous error message when the Plane class was showing class details. After dismissing the error message, I exported the dot file: UMLClassDiagram-Plane.dot.

Understand includes several executables such as the Understand GUI and the command line tool und. The relevant executable for laying out graphs is gvlayout. It’s a wrapper around the Graphviz library and uses the same command-line arguments as Graphviz. Understand typically invokes it with the following arguments:

gvlayout  [input_dot_file] -Kdot -Txdot1.2 -o [output_dot_file]

Running it with UMLClassDiagram-Plane.dot gives the following output:

$ ~/sti/bin/macosx/gvlayout UMLClassDiagram-Plane.dot -Kdot -Txdot1.2 -o UMLClassDiagram-Plane-test.dot 
Error: UMLClassDiagram-Plane.dot: syntax error in line 5 scanning a quoted string (missing endquote? longer than 16384?)
String starting:"
▲
Plane


- var_info: const AP_Param::Info [154]= {{plane.g.format_versio

So the problem is likely a missing end quote or a string too long. Double-checking the end quotes revealed no problems. Was the label really too long? The whole file was less than 400 lines. Turns out that the line starting with “-var_info” was over 22,000 columns long! And two lines down, the longest line in the file is over 30,000 characters long! 

Where did these long strings come from? The UML Class diagram shows the value of variables. The value of var_info is “{{plane.g.format_version.vtype, “FORMAT_VERSION”, Parameters::k_param_format_version, &plane.g.format_version, {def_value: 0}}, {plane.g.sysid_this_mav.vtype,…” plus another 22,000ish characters.  

For an error like this, the UML Class Diagram code was updated for build 1086 to truncate values at 128 characters. After all, even if Graphviz could handle the length of the string, who wants to see all 22,000 characters in a graph? But, as a user without the option of updating Understand, another option is to directly edit the dot file to shorten the lines and then run gvlayout again. To get visual output, use -Tsvg to export the svg.

Most likely, the graph you were using didn’t have such a fixable error. The fastest way to find graphs that won’t lay out is to open the entity locator, sort the functions by cyclomatic complexity, and start generating control flow graphs on the most complex. In the GitAhead sample, _scan_html_tag with a complexity of 360 is an example. Exporting the dot and running gvlayout gives the elusive error: “Error: trouble in init_rank” followed with a long list of debug information. 

For most graphs, if the dot layout fails, Understand falls back on fdp layout. You might notice in dependency graphs that you end up with a spikey-star graph instead of a linear graph sometimes. 

A dependency graph using fdp layout

Understand will use fdp if the graph has lots of nodes (because fdp is a lot faster than dot) or if dot layout failed. The Control Flow graph is an exception because it doesn’t make much sense unordered, but for huge functions like _scan_html_entity you could try fdp directly.

$ ~/sti/bin/macosx/gvlayout ControlFlow-_scan_html_tag.dot -Kfdp -Tsvg -o ControlFlow-_scan_html_tag_out.svg
A control flow graph using fdp layout

Conversely, if the dependency graph you drew was large and you don’t like the layout, there’s a chance that dot layout was never even attempted. You can export the dot file and try generating with dot layout directly. However, as mentioned, dot can take a long time (I’ve never been patient enough to see if the Control Flow graph for Gitahead’s _scan_autolink_email function will ever finish laying out).

Along the same lines, you can try other Graphviz layout engines. For me, though, after reaching this point, I usually decide I’d rather have 1,000 words than a picture.