Review: PVS Studio

Disclaimer: The friendly folks at Viva64 have kindly provided me a review version of PVS Studio. I could test it completely on my own, on my machine, just as if I would have bought it.

As I have been curious for some while how PVS Studio stacks up against solutions I have already tried (C++-Check, Visual Studio Code Analysis, Intel C++ Code Analysis), I gladly took the opportunity to test-drive it one two of my projects: VPlan4, a small Qt based task tracker and niven, my research engine. VPlan4 consists of ~ 20 source files, compromising ~ 4 kLoC while niven consists of ~ 550kLoC, with 70 kLoC in the main library and the rest being external dependencies (400 kLoC), test code, infrastructure and scaffolding.

I tested PVS Studio on a quad-core Core i7 with 2.8 GHz and 12 GiB of memory; all data coming from a 7200 rpm HDD RAID-0. The interesting timings are for the larger project: For one library (~17 kLoC) is takes several minutes. The whole project requires ~ 45 minutes. PVS studio compiles each file and stores the preprocessed output, so using precompiled headers hurts in this case. On the upside you can easily restrict PVS studio to run on a single project or file only. For comparison, processing VPlan4 takes only a few seconds.

Setup

PVS Studio directly integrates itself into Visual Studio 2010. It also features an auto-update tool which is run at each startup, so there is no annoying resident update application. Painless procedure, just as it should be. After the installation, you can immediately run it on any C++ project (no need to modify the project files!)

Results

After the checking is done, PVS Studio groups the warnings into 3 categories sorted by severity. For the niven libraries, this results in ~10k warnings, the majority in the lowest-impact category. PVS Studio usually provides distinct warnings for similar-but-not-exactly-the-same issues which enables precise disabling of warnings. That and the fact that you only need two clicks to disable a warning makes the warning list manageable.

Now, the most important part: In the niven code base, it did find three real bugs — which haven’t been found by C++-Check and the Visual Studio Code Analysis. Three bugs might not sound a lot, but many code analysis tools are not even able to find a single real bug, and the niven code base is pretty mature and has been tested with lots of static code analysis tools already, so three bugs are an excellent result here. On VPlan4, I got very few warnings and nothing serious, so I guess the code was written ok’ish :)

To give you an idea of what kind of bugs PVS Studio captures, here is one from niven:

TASKDIALOGCONFIG tc = { 0 };
tc.cbSize = sizeof (tc);
tc.pszWindowTitle = L"Title";

if (ok)
{
	tc.pszMainInstruction = L"Done";
	tc.pszMainIcon = TD_INFORMATION_ICON;
}
else
{
	tc.pszMainInstruction = L"Error";
	tc.pszMainIcon = TD_ERROR_ICON;

	// No longer valid after assignment, caught by PVS Studio!
	wchar_t errorString [256] = {0};
	wsprintf (errorString, L"Error code: %d", GetLastError ());
	tc.pszExpandedInformation = errorString;
}

On the other hand, using PVS Studio does not mean you can throw away all other analysis tools you are using, as some bugs reported by other tools are not found. For instance, C++-Check finds this one but PVS Studio doesn’t:

char s [5];
strcpy (s, "Sixchr");

There’s also a bunch of things that get reported which shouldn’t, but the folks at Viva64 told me that future releases will get those fixed. Overall, as far as I can tell, the analysis quality is pretty good (make sure you take a look at the list of issues which PVS Studio can find) and I couldn’t spot any junk warnings or incorrect warnings.

Short rant: Having used lots of static code analysis tools so far, I’m still puzzled why nobody bothers to check for portability issues. niven compiles with GCC and MSVC. I’d be very happy to have a tool which gives me a warning if I’m using some construct which is not understood by GCC. That would definitely save me a lot of porting pain.

Overall

Good

  • Works directly on Visual Studio solutions
  • Finds a lot of issues
  • Good, precise warning messages
  • Good support

Bad

  • Slow
  • Too many spurious warnings*
  • No porting/non-standard C++ warnings

*In practice, I found that I’m checking my code base once every 2-3 months. As it’s pretty infrequent, I don’t worry too much if the tool produces a few spurious warnings but I do worry if something is missed. In that regard, PVS Studio fits the bill very well.

Final remarks

If you are new to static analysis, I can recommend giving PVS Studio a shot (there is a trial version.) Static code analysis for C++ is still at an early stage, but even now, a tool like PVS Studio can already help you discover lurking bugs. Especially if your code base is not already covered by unit tests, a static code analysis tool can quickly give you a hint which parts of your code base are ripe for review.

Oh, and before I forget: It also gets regular updates and the support is good — in fact, I reported a bug at the beginning of my review which was fixed in just a few days.

Thanks again to Viva64 for the review version, and keep up the good work!

Posted in Programming | Tagged , , , | 1 Comment

Poor man’s animation framework revisited

Recently, I described the simple animation system I used for videos while at NVIDIA. After coming back, I’ve finally had some time to fix some remaining issues and and get a useful tool out of it. The core requirements remained the same:

  • Frame-by-frame processing: No .avi or other intermediate files, only plain images.
  • Leverage ImageMagick for the actual processing
  • Parallel: Efficiently scale with core count

The ImageMagick part was working reasonable well, so I decided to stick with this. However, the original framework required to manually compute the frame offsets which made stitching cumbersome and blending nearly impossible. Looking closer at what was happening, it became quickly obvious that the framework was stream oriented, but it was not explicit anywhere.

Ava

Enter Ava, the graph-based video processor. Right from the start, Ava is designed around the processing graph. For example, here is the graph for the SRAA video, which is already pretty big:
No SVG support.
The key property is that the everything is designed around an image stream. Each node transforms one or more inputs into a single output; and can be evaluated independently of all other nodes. All frame indices are relative, that is, the graph can be easily composed as there is no “global” frame count. And finally, the processing order is bottom-up, or pull, instead of push. This means that each node executes its own inputs first before applying the transformation, minimising wasted work.

An interesting part is how the inputs are handled. As I use ImageMagick for the actual processing, the inputs have to present as files. What Ava does is while it walks the graph (where each node must have a unique name) it also generates unique file names for each node’s input and process. Generating them from the input side is necessary so that for instance a single node which gets piped into several other nodes does not continuously overwrite its own input. Of course, this means some duplicated work, but the net win is that there is no synchronisation whatsoever. Overwriting the same file all the time also has the added advantage that less file system flushes are necessary. Originally, I would delete each file and recreate it again for the next frame, but overwriting directly seems to be a tad faster on Windows.

All of the stuff used to generate the SRAA video is also really compact. There are 11 different node types in total (roughly 200 lines of Python), plus 300 for the graph and finally 100 lines or so of scaffolding. Individual frames can be easily piped into FFMpeg, so there is no comfort loss anywhere. The amount of code is smaller than the original framework, which had less features — mostly because the declarative part (the graph) is split into JSON instead of being intermingled with the processing code.

So much for the definitive version of the animation framework. I completely scrapped the old one in favour of Ava, and when reading the old blog post you should be aware that it was only a proof-of-concept while this here is the real McCoy.

Posted in Programming | Tagged , , | 2 Comments

VPlan4: Project overview

VPlan4

Fast-forward to 2010: I started to use Linux for some of my development work, and I really wanted VPlan to run on Linux as well. In the meantime, all of the web-based tools have appeared with nice UIs, drag & drop, comfort functions etc. which VPlan lacked, so there was really some reason to give it another shot. This time around, I wrote down the requirements first before starting one line of code:

  • Portability: Should run on Linux and Windows; the storage format should be platform-neutral
  • Performance: Fast startup, little memory use.
  • Features:
    • Drag & drop in the tree-view
    • ACID for all operations
    • Per-task descriptions and priorities

For development, I used Qt this time around, as it is available under the LGPL and thus does not force me to publish the source (I didn’t set my mind on that yet.) It also supports sqlite, which gives me the ACID compliance, and should improve memory usage and performance quite a bit compared to WPF. With that much preparation, I went to coding.

Implementation

I’m a strong believer that any crap can be refactored/polished until it’s good, as long as you have some crap to start with. Given my initial requirements, I didn’t spend too much time fleshing out an architecture, but went to implement a data model for all tasks so it could be bound to a QTreeView and write the corresponding SQL schema as I went along.

Get a basic UI with Qt turned out to be really simple using QtDesigner. A nice feature is that you can subclass any widget but still use QtDesigner to place it — something which turned out to be useful for my “deselecting tree-view”, a tree-view which deselects if you click the empty space.

I built the project with CMake, which works nicely with Qt once you setup it properly. Most coding was done in a single sprint: The feature set was limited and known up front and all I needed to do was to adapt the SQL backend into an abstract tree model. The rest is handled by Qt, including drag & drop and various other details.

Pretty late in the development cycle I decided to add translations. With Qt, all you need is to make sure that every string is wrapped with a macro and then run QtLinguist. The actual translation is pretty simple later on. One advantage of translating is that you can also generate proper plural form handling for English. That’s a nice polishing touch, and even though I assume that no VPlan user noticed it I always wanted to have this in an application since playing Transport Tycoon.

Deployment

For deployment, I’m using Wix again. Wix is great for Windows deployment as it generates Microsoft Installer packages. One problem with Wix is that it’s verbose for small projects and thus takes some time to write. For larger projects, some I’m playing around with some automatic Wix generation but this has other issues (especially when it comes to the directory structure.) After each build, I’m storing the binaries and tagging the repository for each installer so I can exactly recreate the same file.

Various unsolved issues

So much for the stuff that works. Some other details are not working yet which I’d definitely like to attack at some point. First of all, there is no automated testing for the UI and very limited testing for the backend. I guess that a script intermediate layer would be the easiest solution for that, but as it stands now, there is no good test coverage.

Crash handling is also an unsolved issue. For the latest version of my research engine, I’m using a crash handler and storing the PDBs along with the source and binaries so I can capture crashes and perform post-mortem debugging.  As the user base seems to be minimal, this is enough for VPlan, but every larger project needs some mechanism to capture a minidump.

Conclusion

So much for VPlan 4. This blog post has been a long time in the making, and I hope it shed some light on the development of VPlan4. So long, and thanks for all the fish!

Posted in Programming | Tagged , , , , | Leave a comment

Notes section

Just new, the notes section. Often enough, I find some small tidbit of knowledge which is useful but does not warrant a full blog post. In order to keep those around, I’ve added a notes section. Over time, some blog posts will be moved there for easier finding and to have all updates in a central place. After my latest round of blog updates, it’s easy for me now to add a custom field which indicates that a blog post has been moved to the notes.

Posted in General | Tagged | 1 Comment