Abstract: Having problems with threading? Check out these plugins to identify shared global objects. The plugins also use a cool trick: architectures as entity tags to store information like thread priorities.
Suppose I have a threaded application. Which variables need to be protected?
Global Variables from the Information Browser
I’m going to use FastGrep as an example since it’s a classic sample project. It’s not really threaded, but I can pretend. Let’s say the function regatom will be run on its own thread. What variables does it access? The information browser will tell me:
Global Variables in Call Trees
So, regatom uses regparse. But regatom also has calls. If it’s the start of my thread, I need to know all the global objects that are accessed anywhere in the call tree. It turns out there’s a graph for that. The “Calls with Global Objects (Classic)” is a Python plugin graph shipped with Understand. I could also turn on the “Global Objects” option in most of the other graph variants to get a similar view. The global objects show as rounded nodes in the graph below and the rectangles are functions.
One thread solved. Let’s add some more. I’ll pick the functions regoptail and reginsert and get their object references graphs:
Using Architectures to Tag Entities
It’s not bad. But what I really want to know is which global objects are accessed by all three functions. How can I get a graph with multiple entities?
Here’s the clever trick. An architecture is a group of entities. Like me, you might be used to thinking of an architecture as a tree that structures your project. But architectures can also be used like tags for entities. I want to tag each of my three entities as the source of a thread.
I’m working with a plugin that was developed by Robby Bennett for some customers in Japan. So, the tags I use need to follow the format “*/*task*” where star can be anything and task is case insensitive. So, I’ll use “Shared Tasks/tasks” and tag my three functions. I created the architecture nodes first, but I could have also just typed the text into the textbook and the architecture would have been created.
Shared Tasks Plugin Graph
The plugin graph (Shared Tasks) is essentially a “Calls with Object References” graph that has three root functions instead of just one. It helpfully identifies global variables that are accessed from more than one of my root functions by shading them blue. So I can quickly see that the variables that might need to be protected are “regsize”, “regcode” and “regdummy”.
Graph Options
However, the “quickly see” part of my statement is greatly aided by the fact that the FastGrep sample project is tiny. Furthermore, it’s not actually a threaded application. A real graph might be enormous. So, the first filter I can apply to this graph is to not show global objects that aren’t shared by setting Objects=”Shared Only” (image part a).
Even for global objects that are shared, some of them might still be irrelevant. For example, variables that are never read (Filter out set modify only=On; image part b) or is only read (Filter out use only=On; image part c). Also, just like I don’t care about the global objects that aren’t shared, I might not care about the call tree to the variable. So I can just show the relationship between the root entities and the global objects (Reference=Simple; image part d).
Priorities
Suppose I had more information I wanted on the graph. I can keep going with the tag strategy to associate more information with the entities. The Shared Tasks plugin also identifies patterns like “*/*priority*/\d+” where * is anything and \d+ is one or more numbers. So I can update my architecture to show priorities on my root entities:
Shared Tasks Plugin Report
Graphs are great for exploring but even with all my graph options the graph might still be too big to be useful. Or, I might want to save the information over time for comparison. In that case, I might want the companion plugin for generating an interactive report. It has the same four options as the graph, plus options to save the file.
Protected Objects
There’s one final feature of the plugin. So far, I’ve been using the graph to find objects that need protection. But what if I’ve already protected some of the references to my variables. In that case, what I want to find is which references aren’t protected.
How does the plugin tell if a reference is protected? The plugin currently only detects protection in the form of a pair of functions that disable and enable interrupts. Once again, these functions pairs are identified by tag format “*/*interrupt*/*/*enable*/” and “*/*interrupt*/*/*disable*/”.
Then a global object reference is protected if it is preceded by a call to an interrupt disable function and followed by a call to the corresponding interrupt enable function. Note that this does not take into consideration the control flow of the function.
Personally, I’m unfamiliar with interrupt functions so the best I can do here is show some sample code used in development with the sample graph.
Conclusion
If the tagging rules for the plugin get confusing, there’s a helper Python script for generating the architecture. There are also many other cool plugins in our plugin repository. Check them out or contribute your own. We’d love to hear from you.