<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Embedded Computing Design</title>
	<atom:link href="http://embedded-computing.com/articles/feed/?tag=static-analysis" rel="self" type="application/rss+xml" />
	<link>http://embedded-computing.com</link>
	<description>Embedded Computing Design is targeted at engineers, architects, and decision makers looking at silicon, software, and strategies for embedded devices. With an estimated 15,000,000,000 devices in the world soon, we&#039;re out to help every designer working on one of them–this is where the next decade of embedded computing is going.</description>
	<lastBuildDate>Thu, 16 May 2013 13:48:30 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
		<item>
		<title>Static analysis exposes latent defects in legacy software</title>
		<link>http://embedded-computing.com/articles/static-latent-defects-legacy-software/</link>
		<comments>http://embedded-computing.com/articles/static-latent-defects-legacy-software/#comments</comments>
		<pubDate>Mon, 11 Feb 2013 15:00:00 +0000</pubDate>
		<dc:creator>Paul Anderson, GrammaTech, Inc.</dc:creator>
				<category><![CDATA[applications embedded systems]]></category>
		<category><![CDATA[arm embedded linux]]></category>
		<category><![CDATA[c compiler arm]]></category>
		<category><![CDATA[c static code analyzer]]></category>
		<category><![CDATA[code analyzer tool]]></category>
		<category><![CDATA[design embedded hardware]]></category>
		<category><![CDATA[design embedded system]]></category>
		<category><![CDATA[design embedded systems]]></category>
		<category><![CDATA[designing embedded systems]]></category>
		<category><![CDATA[embedded microcontroller systems]]></category>
		<category><![CDATA[embedded real time system]]></category>
		<category><![CDATA[Embedded Software]]></category>
		<category><![CDATA[embedded software applications]]></category>
		<category><![CDATA[embedded software design]]></category>
		<category><![CDATA[embedded software programming]]></category>
		<category><![CDATA[embedded software systems]]></category>
		<category><![CDATA[embedded system designing]]></category>
		<category><![CDATA[embedded system hardware]]></category>
		<category><![CDATA[embedded system software development]]></category>
		<category><![CDATA[embedded systems hardware]]></category>
		<category><![CDATA[gnu gcc c]]></category>
		<category><![CDATA[GrammaTech]]></category>
		<category><![CDATA[klocwork static analysis]]></category>
		<category><![CDATA[klocwork tool]]></category>
		<category><![CDATA[legacy application migration]]></category>
		<category><![CDATA[legacy application modernization]]></category>
		<category><![CDATA[Legacy Software Migration]]></category>
		<category><![CDATA[legacy systems migration]]></category>
		<category><![CDATA[legacy systems modernization]]></category>
		<category><![CDATA[mainframe application modernization]]></category>
		<category><![CDATA[mainframe legacy modernization]]></category>
		<category><![CDATA[mainframe modernization]]></category>
		<category><![CDATA[modernizing legacy systems]]></category>
		<category><![CDATA[programming embedded system]]></category>
		<category><![CDATA[real time embedded]]></category>
		<category><![CDATA[real time embedded software]]></category>
		<category><![CDATA[real time embedded software development]]></category>
		<category><![CDATA[realtime embedded system]]></category>
		<category><![CDATA[realtime embedded systems]]></category>
		<category><![CDATA[static analysis]]></category>
		<category><![CDATA[static code analyser]]></category>
		<category><![CDATA[static code analyzer]]></category>
		<category><![CDATA[static code analyzer c]]></category>
		<category><![CDATA[static code analyzers]]></category>
		<category><![CDATA[static code checker]]></category>
		<category><![CDATA[static source code analysis]]></category>

		<guid isPermaLink="false">http://embedded-computing.com/?guid=949396d96795c33b7c482c23e9fc6ffe</guid>
		<description><![CDATA[Static analysis tools can help find concurrency and other defects to cut legacy's latency.]]></description>
			<content:encoded><![CDATA[<ul style='margin-left: 11px; margin-top: 0px; padding: 2px;'><li style="list-style-type: none; list-style: none; background-position: 0px 8px; background-image: url(http://cloud1.opensystemsmedia.com/arrows/9.gif); background-repeat: no-repeat;  margin-bottom: 11px; margin-top: 6px; padding-left: 19px; padding-top: 5px; font-size: 14px; font-family: arial;" ><div class="story"><span id="more-18018"></span><span class='body'>
<p class="body-text">When migrating from a legacy software-based system to new technology, it is important to be able to reuse as much code as possible. Even if such code has been tested thoroughly and has proved reliable in practice in the old system, it might still contain latent bugs. Those bugs might have never been triggered in the legacy system because of very specific properties of that system such as the toolchain used to compile the code, the processor architecture, or the host operating system. When ported to a new system where those properties are different, the latent defects might be manifest as harmful bugs. But the good news is that advanced static analysis tools can flush out these latent defects to help combat the challenge.</p>
<p class="heading-1">Updating the system, revealing coding flaws</p>
<p class="body-text"><span id="Ad-ABD-1" style="display: none; float: left;"></span>One of the most important motivations for migrating legacy systems is to take advantage of advances in hardware technology since the original system was first deployed. Probably the most common benefit is increased performance because of the adoption of a newer and faster processor. This is also the single most significant change from the perspective of the code. The new processor can have a different bit width, or endianness, and the number of available cores can be different. During code porting from the old platform to the next, much of the recoding effort will go into adapting the code to those differences.</p>
<p class="heading-2">Compilers, toolchains, and latent&nbsp;bugs</p>
<p class="body-text">There are many other less obvious differences than implementing a new processor, and these subtle nuances can be easy to overlook. Take, for example, the toolchain used to compile the code. On the face of it, this should not make much of a difference. After all, if the code was written to be ANSI C compliant, and if the compilers claim to support ANSI C, then surely the code will have the same semantics when compiled by either compiler? Unfortunately not. The C and C++ standards are riddled with clauses that are &#8220;compiler dependent,&#8221; meaning that the standard does not dictate exactly how to compile certain constructs, and the choice is up to the compiler writer. Many of these are obvious and well-known to programmers, such as the order in which operands are evaluated, but others are very subtle. A latent bug might be harmless on the legacy system because the compiler chooses to compile it a particular way, but hazardous on the new system because the new compiler makes a different choice.</p>
<p class="body-text">Compilers are programs too, of course, and are themselves not free of defects. A recent study of C compilers found code generation defects in every compiler they tested[1]. The treatment of the volatile keyword, which is of vital importance in embedded safety-critical software because it is frequently used to read sensor data, is especially prone to compiler errors that cause changes to sensor values to be silently ignored. A program&#8217;s correct functioning might even come to rely on such flaws.</p>
<p class="heading-2">Another danger zone: Standard&nbsp;libraries</p>
<p class="body-text">Another subtle software migration difference that can cause latent defects to become hazardous involves the standard libraries that interface to the operating system. One might hope that such libraries would be consistent across platforms, but this is rarely so. The most significant difference is with respect to error handling. A new platform can have completely different failure modes than the legacy platform, and the code might need to be changed to be able to handle those differences. Worse still, error cases appear to be very badly documented, according to a recent study[2].</p>
<p class="heading-1">Static analysis wins out, complements traditional testing</p>
<p class="body-text">Clearly, any legacy migration project must include a significant amount of time for testing the software in its new incarnation. However, test results are only as good as the test inputs. If a test case fails to exercise a path on which a bug occurs, that defect might go undetected. Generating new test cases is expensive too. Hence, a sensible tactic to flush out these latent defects is to use advanced static analysis tools as part of the legacy transformation effort. Such tools are capable of finding defects such as those described herein, including those that depend on platform subtleties. They are especially good at finding concurrency defects such as data races that are exceedingly difficult to find using traditional testing methodologies. They are also good at finding instances of code that, while not definitively wrong, is highly correlated with errors or is particularly risky when ported to a different environment. </p>
<p class="reference-heading">References</p>
<p class="references-list">[1] Finding and Understanding Bugs in C&nbsp;Compilers, Xuejun Yang, Yang Chen, Eric&nbsp;Eide, John Regehr, 2011. <span class="hyperlink"><a href="http://www.cs.utah.edu/~regehr/papers/pldi11-preprint.pdf">www.cs.utah.edu/~regehr/papers/pldi11-preprint.pdf</a></span></p>
<p class="references-list">[2] Expect the Unexpected: Error Code Mismatches Between Documentation and the Real World, Cindy Rubio-Gonz&#225;lez, Ben&nbsp;Liblit, 2010. <span class="hyperlink"><a href="http://www.eecs.berkeley.edu/~rubio/includes/paste10.pdf">www.eecs.berkeley.edu/~rubio/includes/paste10.pdf</a></span></p>
<p class="author-bio">Paul Anderson is VP of Engineering at GrammaTech and can be contacted at paul@grammatech.com. </p>
</p></div>
<p></span></div></li></ul>]]></content:encoded>
			<wfw:commentRss>http://embedded-computing.com/articles/static-latent-defects-legacy-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pitfalls of multicore software: Why data races are never benign</title>
		<link>http://embedded-computing.com/articles/pitfalls-multicore-data-races-never-benign/</link>
		<comments>http://embedded-computing.com/articles/pitfalls-multicore-data-races-never-benign/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 15:00:00 +0000</pubDate>
		<dc:creator>Paul Anderson, GrammaTech</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[c static code analyzer]]></category>
		<category><![CDATA[code analyzer tool]]></category>
		<category><![CDATA[gnu c compilers]]></category>
		<category><![CDATA[GrammaTech]]></category>
		<category><![CDATA[klocwork tool]]></category>
		<category><![CDATA[Pitfalls of multicore software]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[static analysis]]></category>
		<category><![CDATA[static code analyzer c]]></category>
		<category><![CDATA[static code checker]]></category>

		<guid isPermaLink="false">http://embedded-computing.com/?guid=48edf2cc366f65f8a7278bb09a86a271</guid>
		<description><![CDATA[Static analysis tools build models to help single out race conditions that would otherwise run away with software integrity.]]></description>
			<content:encoded><![CDATA[<ul style='margin-left: 11px; margin-top: 0px; padding: 2px;'><li style="list-style-type: none; list-style: none; background-position: 0px 8px; background-image: url(http://cloud1.opensystemsmedia.com/arrows/9.gif); background-repeat: no-repeat;  margin-bottom: 11px; margin-top: 6px; padding-left: 19px; padding-top: 5px; font-size: 14px; font-family: arial;" ><div class="story">
<h3 class="abstract"><img alt="1" class="figure_intro wide" src="http://i.opensystemsmedia.com/?zc=F&#038;f=png&#038;h=320&#038;w=600&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5568%2Ffigures%2F1" />Despite the widespread misconception that some data races are entirely harmless, modern optimizing compilers generate code that can cause incorrect execution when data races exist. Using static and dynamic analysis, programmers can find and eliminate these defects that are often inadvertently introduced into their code.</h3>
<p><span id="more-283"></span><span class='body'>
<p class=Bodytext><span id="Ad-ABD-1" style="display: none; float: left;"></span>Programming multicore processors to take advantage of their power means writing multithreaded code. C and C++ were not designed for concurrency, so developers must use a library such as pthreads for those languages. Multithreaded code is more difficult to get right than single-threaded due to the risk posed by entirely new classes of programming defects. </p>
<p class=Bodytext><span id="Ad-ABD-1" style="display: none; float: left;"></span>In the rogue&#8217;s gallery of concurrency bugs, the race condition is a notorious repeat offender. A race condition occurs when a program checks a resource property and performs an action on the assumption that the property has not changed, even though an external actor has slipped in and changed that property.</p>
<p class=bodytext>A data race is a particular type of race condition that involves concurrent access to memory locations in a multithreaded program. This defect occurs when there are two or more execution threads that access a shared memory location, at least one thread is changing the data at that location, and there is no explicit mechanism for coordinating access. If a data race occurs, it can leave the program in an inconsistent state.</p>
<h1>The insidious nature of data races</h1>
<p class=bodytext>It is widely assumed that some data races are harmless and can be safely ignored. Unfortunately, this is only true in very rare circumstances. It is best to explain why by introducing an example.</p>
<p class=bodytext>The <span class=italics>singleton pattern</span> is a commonplace idiom where the program maintains a reference to a single underlying object and a Boolean variable encodes it if it has been initialized. This pattern is also known as <span class=italics>lazy initialization</span>. The following code is an example of the pattern:</p>
<p class=codeparagraph style='text-indent:12.0pt'>if (!initialized) {</p>
<p class=codeparagraph style='margin-left:24.0pt;text-indent:12.0pt'>object = create();</p>
<p class=codeparagraph><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count:2'>&nbsp;&nbsp; </span>initialized = true;</p>
<p class=codeparagraph style='text-indent:12.0pt'>}</p>
<p class=codeparagraph style='margin-bottom:6.0pt;text-indent:12.25pt'>&#8230; object &#8230;</p>
<p class=bodytext>This code is perfectly adequate for a single-threaded program, but it is not thread-safe because it has a data race on the variable named <span class=codecharacter>initialized</span>. If called by two different threads, there is a risk that both threads will observe <span class=codecharacter>initialized</span> as false at essentially the same time, and both will call <span class=codecharacter>create()</span>, thus violating the singleton property.</p>
<p class=bodytext>To make this thread safe, the natural approach is to protect the entire <span class=codecharacter>if</span> statement with a lock. However, acquiring and releasing locks can be costly, so programmers try to avoid the expense by using the <span class=italics>double-checked locking</span> idiom &#8211; a check outside the scope of the lock and another inside. The inner check is there to confirm that the first check still holds after the lock has been acquired:</p>
<p class=codeparagraph style='text-indent:12.0pt'>if (!initialized) {</p>
<p class=codeparagraph><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count:2'>&nbsp;&nbsp; </span>lock();</p>
<p class=codeparagraph><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count:2'>&nbsp;&nbsp; </span>if (!initialized) {</p>
<p class=codeparagraph><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count: 2'>&nbsp;&nbsp;&nbsp; </span>object = create();</p>
<p class=codeparagraph><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count: 2'>&nbsp;&nbsp;&nbsp; </span>initialized = true;</p>
<p class=codeparagraph><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count:2'>&nbsp;&nbsp; </span>}</p>
<p class=codeparagraph><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count:2'>&nbsp;&nbsp; </span>unlock();</p>
<p class=codeparagraph style='text-indent:12.0pt'>}</p>
<p class=codeparagraph style='margin-bottom:6.0pt'><span style="mso-spacerun: yes">&nbsp; </span>&#8230; object &#8230;</p>
<p class=bodytext>Superficially, this looks like it will suffice, and indeed, it will as long as the statements are guaranteed to execute in that order. However, an optimizing compiler might generate code that essentially switches the order of <span class=codecharacter>object = create()</span> and <span class=codecharacter>initialized = true</span>. After all, there is no explicit dependence between those two statements. In that case, if a second thread enters this code any time after the assignment to <span class=codecharacter>initialized</span>, that thread would then use the value of <span class=codecharacter>object</span> before it has been initialized.</p>
<p class=bodytext>Optimizing compilers are inscrutable beasts. Those that optimize for speed will take many esoteric considerations into account, few of which are obvious to a programmer. It is common for them to generate instructions that are apparently out of order because doing so might result in fewer cache misses, or because fewer instructions are needed.</p>
<p class=bodytext>It is wrong to assume that because the reordering introduced a race condition in the previous example that the compiler is at fault. The compiler is doing exactly what it is allowed to do. The language specification is perfectly clear and unambiguous about this: The compiler is allowed to assume that there are no data races in the program.</p>
<p class=bodytext>In actuality, the specification is somewhat broader: Compilers are allowed to do anything in the presence of undefined behavior. This is sometimes facetiously referred to as <span class=italics>catch fire</span> semantics; the specification gives the compiler permission to set a computer on fire if the program has undefined behavior. As well as data races, many traditional bugs such as buffer overruns, dereferences of invalid addresses, and so on constitute undefined behavior. Because compilers are free to do anything, rather than burn the building down they typically do the sensible thing, which is to assume that the undefined behavior will never happen and optimize accordingly.</p>
<p class=bodytext>The consequences of this can sometimes be surprising, even to those who are experts in concurrency and compilers. It can be difficult to convince programmers that code that looks completely correct can be compiled into code that has serious errors.</p>
<p class=bodytext>Another example is worth describing. Suppose there are two threads where one reads a shared variable and the other writes to it. Let&#8217;s assume that it does not matter to the reader if it sees the value before or after it has been changed by the writer (this is not an uncommon pattern). If those accesses are not protected by a lock, then there is clearly a data race. Notwithstanding the catch fire rule, however, most programmers would conclude that this is completely benign.</p>
<p class=bodytext>As it turns out, there are at least two plausible ways in which this code could be compiled where the reader would see a value that is wrong. The first way is easy to explain: Suppose the value were a 64-bit quantity on an architecture that can only read 32-bit words. Then both the reader and the writer need two instructions, and an unlucky interleaving might mean that the reader sees the top 32 bits of the old value and the bottom 32 bits of the new, which when combined can be a value that is neither the old nor the new.</p>
<p class=bodytext>The second way in which wrong code could be generated is more subtle. Suppose the reader did the following, where the data race is on the variable named <span class=italics>global</span>:</p>
<p class=codeparagraph style='text-indent:12.0pt'>int local = global;<span style="mso-spacerun: yes">&nbsp; </span>// Take a copy of<br /> <span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// the global</p>
<p class=codeparagraph style='text-indent:12.0pt'>if (local == something) {</p>
<p class=codeparagraph><span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </span><span style='mso-tab-count:2'>&nbsp;&nbsp; </span>&#8230;</p>
<p class=codeparagraph style='text-indent:12.0pt'>}</p>
<p class=codeparagraph style='text-indent:12.0pt'>&#8230; // Some non-trivial code that does<br /> <span style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>// not change global or local</p>
<p class=codeparagraph style='text-indent:12.0pt'>if (local == something) {</p>
<p class=codeparagraph><span style="mso-spacerun: yes">&nbsp;&nbsp; </span><span style='mso-tab-count:2'>&nbsp;&nbsp;&nbsp; </span>&#8230;</p>
<p class=codeparagraph style='text-indent:12.0pt'>}</p>
<p class=bodytext>Here the reader is making a local copy of the racy variable and referring to that value twice. It is reasonable to expect that the value will be the same in both places, but again, the optimizing compiler can generate code where that expectation is unmet. If <span class=codecharacter>local</span> is assigned to a register then it will have one value for the purposes of the first comparison, but if the code between the two conditionals is sufficiently nontrivial then that register may get <span class=italics>spilled</span> &#8211; in other words, reused for a different purpose. In that case, at the second conditional, the value of <span class=codecharacter>local</span> will be reloaded from the global variable into the register, by which time the writer might have changed it to a different value.</p>
<p class=bodytext>Programmers should be very skeptical of claims that some data races are acceptable and should strive to find and remove all of them from their code.</p>
<h1>Techniques for finding risky defects</h1>
<p class=bodytext>When it comes to finding concurrency defects, traditional dynamic testing techniques might be inadequate. A program that passes a test a hundred times is not guaranteed to pass the next time, even with the same inputs and the same environment. Whether these bugs manifest or not is exquisitely sensitive to the timing, and the order in which operations in threads are interleaved is essentially nondeterministic.</p>
<p class=bodytext>New dynamic testing techniques for finding data races are emerging. These techniques work by monitoring the applications as they execute and observing the locks held by each thread, as well as the memory locations being accessed by those threads. If an anomaly is found, then a diagnostic is issued. Other tools help diagnose data races suspected of causing failures. Some companies now offer tools to facilitate diagnosis of data races that allow the replay of events leading up to an anomaly.</p>
<p class=bodytext>Static analysis tools can also be useful for finding data races and other concurrency errors. Whereas dynamic testing tools find defects that occur for particular executions of a program with a fixed set of inputs, static analysis tools check all possible executions and all possible inputs. For performance reasons, tools might place limits on how much exploration is done and thus might not be completely exhaustive; even so, they can cover much more than can ever be feasible with dynamic testing. The advantage of static analysis is that test cases are not required because the program is never actually executed.</p>
<p class=bodytext>Instead, these tools work by creating a model of the program and then exploring the model in various ways to find anomalies. GrammaTech&#8217;s CodeSonar finds data races by creating a model that represents the set of locks held by each thread and by performing a symbolic execution of the program that explores execution paths. It records the sets of variables protected by locks and uses this information to find interleavings that can result in shared variables being used without proper synchronization. Similar techniques can be used to find other concurrency defects such as deadlock and lock mismanagement.</p>
<p class=bodytext>Once found, data races are usually easy to fix, albeit doing so correctly can incur a performance penalty. In some cases, there might be a temptation to use the C volatile keyword to correct the data race, but this is not recommended because volatile was not designed to solve concurrency problems, and in any case is a poorly understood construct that is frequently miscompiled. The latest versions of C and C++ have embraced concurrency and support atomic operations. Compiler support for these operations is slowly emerging, and until it becomes readily available, the best approach is to use locks.</p>
<p class=bodytext>To achieve high-quality software for multicore processors, a zero-tolerance policy for data races is recommended. Find them using a combination of both static and dynamic techniques, and take care not to rely too heavily on esoteric compiler techniques to fix them. These defects are so risky and unpredictable that eliminating them systematically is the only safe way to be sure that they do not cause harm.</p>
<p class=authorbio>Paul Anderson is VP of Engineering at GrammaTech.</p>
<p class=contactinfo>GrammaTech<br /> 607-273-7340<br /> <span style='font-weight:normal'><a href="mailto:paul@grammatech.com"><b style='mso-bidi-font-weight:normal'>paul@grammatech.com</b></a></span> <br /> <span style='font-weight:normal'><a href="http://www.grammatech.com"><b style='mso-bidi-font-weight:normal'>www.grammatech.com</b></a></span> </p>
<p></span></div></li></ul>]]></content:encoded>
			<wfw:commentRss>http://embedded-computing.com/articles/static-latent-defects-legacy-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The value of usability: Getting developers to &#8216;push the button&#8217; on static analysis &#8211; Q&amp;A with Gwyn Fisher, CTO, Klocwork</title>
		<link>http://embedded-computing.com/articles/the-fisher-cto-klocwork/</link>
		<comments>http://embedded-computing.com/articles/the-fisher-cto-klocwork/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 15:00:00 +0000</pubDate>
		<dc:creator>Jennifer Hesse, Editor, OpenSystems Media</dc:creator>
				<category><![CDATA[advanced microsoft office training]]></category>
		<category><![CDATA[advanced microsoft project training]]></category>
		<category><![CDATA[application development process]]></category>
		<category><![CDATA[application development tools]]></category>
		<category><![CDATA[application software developer]]></category>
		<category><![CDATA[applications software development]]></category>
		<category><![CDATA[Articles]]></category>
		<category><![CDATA[c software development]]></category>
		<category><![CDATA[computer training courses]]></category>
		<category><![CDATA[computer training online courses]]></category>
		<category><![CDATA[custom software developer]]></category>
		<category><![CDATA[custom software developers]]></category>
		<category><![CDATA[database application development]]></category>
		<category><![CDATA[database software development]]></category>
		<category><![CDATA[development tools software]]></category>
		<category><![CDATA[embedded software applications]]></category>
		<category><![CDATA[embedded software developers]]></category>
		<category><![CDATA[embedded software projects]]></category>
		<category><![CDATA[embedded system software development]]></category>
		<category><![CDATA[embedded systems applications]]></category>
		<category><![CDATA[embedded systems software development]]></category>
		<category><![CDATA[interview]]></category>
		<category><![CDATA[Klocwork]]></category>
		<category><![CDATA[klocwork static analysis]]></category>
		<category><![CDATA[metrics software development]]></category>
		<category><![CDATA[microsoft access 2007 training courses]]></category>
		<category><![CDATA[microsoft publisher training courses]]></category>
		<category><![CDATA[mobile software developer]]></category>
		<category><![CDATA[ms office online courses]]></category>
		<category><![CDATA[ms project training classes]]></category>
		<category><![CDATA[online training courses]]></category>
		<category><![CDATA[product software development]]></category>
		<category><![CDATA[programming and software development]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[software application developer]]></category>
		<category><![CDATA[software application development process]]></category>
		<category><![CDATA[software applications development]]></category>
		<category><![CDATA[software database development]]></category>
		<category><![CDATA[software development application]]></category>
		<category><![CDATA[software development applications]]></category>
		<category><![CDATA[software development c]]></category>
		<category><![CDATA[software development consultant]]></category>
		<category><![CDATA[software development consulting]]></category>
		<category><![CDATA[software development custom]]></category>
		<category><![CDATA[software development environments]]></category>
		<category><![CDATA[software development from home]]></category>
		<category><![CDATA[software development home]]></category>
		<category><![CDATA[software development microsoft]]></category>
		<category><![CDATA[software development net]]></category>
		<category><![CDATA[software development platforms]]></category>
		<category><![CDATA[software development product]]></category>
		<category><![CDATA[software development products]]></category>
		<category><![CDATA[software development programming]]></category>
		<category><![CDATA[software development technology]]></category>
		<category><![CDATA[software development tools for]]></category>
		<category><![CDATA[software development windows]]></category>
		<category><![CDATA[software system development]]></category>
		<category><![CDATA[software tool development]]></category>
		<category><![CDATA[source code static analysis]]></category>
		<category><![CDATA[static analysis]]></category>
		<category><![CDATA[static code analyzer]]></category>
		<category><![CDATA[The value of usability]]></category>
		<category><![CDATA[tools for software development]]></category>
		<category><![CDATA[web application developers]]></category>
		<category><![CDATA[web application security testing]]></category>
		<category><![CDATA[web based application development]]></category>

		<guid isPermaLink="false">http://embedded-computing.com/?guid=613e6ca77fb16bd10117d309c0b0e20c</guid>
		<description><![CDATA[In and exclusive Q&#38;A session with Embedded Computing Design, Gwyn Fisher of Klocwork comments on static code analysis and its growth as a staple of embedded software development.]]></description>
			<content:encoded><![CDATA[<ul style='margin-left: 11px; margin-top: 0px; padding: 2px;'><li style="list-style-type: none; list-style: none; background-position: 0px 8px; background-image: url(http://cloud1.opensystemsmedia.com/arrows/9.gif); background-repeat: no-repeat;  margin-bottom: 11px; margin-top: 6px; padding-left: 19px; padding-top: 5px; font-size: 14px; font-family: arial;" ><div class="story">
<h3 class="abstract"><img alt="3" class="figure_intro wide" src="http://i.opensystemsmedia.com/?zc=F&#038;f=png&#038;h=320&#038;w=600&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5567%2Ffigures%2F3" />The ubiquitous nature of embedded software has made source code analysis a critical component of the development process. Gwyn discusses the impact this technology has on software security and reliability, and emphasizes the importance of making static analysis a natural part of a developer&#8217;s coding practice.</h3>
<p><span id="more-285"></span><span class='body'>
<p class="body-text"></p>
<p class="interview-question"><span class="interview-name">ECD:</span> As embedded developers turn to multicore processors to optimize performance, how can analysis tools help control inevitable cost and schedule problems?</p>
<p class="body-text"><span class="interview-name">FISHER:</span> Any new development is an exercise in balancing expectation against risk. In the case of multicore, the naive expectation is always linear acceleration tempered perhaps by some jocular &#8220;wouldn&#8217;t that be nice&#8221; acceptance that the final result won&#8217;t be quite that good, but no real understanding of the reality that without significant effort (read: time, money, angst) the result might be slower than the old, interrupt-driven single-core code. So tools have a role to play in terms of helping developers understand the impact of what they&#8217;re doing, what pitfalls they&#8217;re unwittingly leaving themselves open to, and how to mitigate the associated risks.</p>
<p class="body-text">Dynamic analysis in this space has received the lion&#8217;s share of attention for obvious reasons. If I can see a nice set of graphs over time that shows the performance of my code in action, I can presumably narrow in on problem areas quickly and apply my own knowledge to figuring out what&#8217;s going on. The challenge with dynamic analysis is that it depends on a) defining a test set that shows execution problems, and b) the reviewer&#8217;s intimate knowledge and understanding of what to do about those problems.</p>
<p class="body-text">Static analysis, by contrast, assumes little knowledge on behalf of the reviewer and requires no effort to be expended in defining test cases. Every conceivable code path through the application is exercised with as much rigor as every other path. This approach is therefore far more likely to show complex and costly issues such as data races, deadlocks, and resource contention than any constructed test bench. That speaks directly to the bottom line of cost control in what is inevitably a large, over-budget project. Leaving issues such as these in a code base until late in the validation process will cost exponentially more to address than doing so during initial development.</p>
<p class="body-text">In addition, due to the way that static analysis works by modeling the expected program execution, the finding is accompanied by a detailed walk-through of how the situation is predicted to occur, allowing even a relatively junior resource to interpret the issue at hand, determine whether or not it&#8217;s likely to happen, and apply an appropriate design fix. In one example we like to describe in seminars on the subject, a design flaw in a popular open-source database kernel resulted in months of effort expended to identify a deadlock and eventually rewrite key modules to avoid the data race at its heart. This same problem was identified during the first analysis using our tools, which provided a walk-through description enabling developers to easily see that the data race was causing the problem and that the deadlock was merely the symptom.</p>
<p class="body-text">Contrast a few hours to run the tool to analyze the code and an hour at most to interpret and act upon the result (what turns out to be a one-line fix) with months of community effort to determine an appropriate set of tests, followed by design effort attempting to fix the deadlock, and finally requiring the designer to rewrite the whole thing from scratch.</p>
<p class="interview-question"><span class="interview-name">ECD:</span> How is static analysis introduced in the software development cycle, and how can it be used with existing Integrated Development Environment (IDE) tools?</p>
<p class="body-text"><span class="interview-name">FISHER:</span> There&#8217;s absolutely no doubt that any developer-facing tool that doesn&#8217;t integrate seamlessly with any existing tooling is going to face significant friction in deployment. We&#8217;ve been selling this message effectively for years, with development managers almost asking the &#8220;why wouldn&#8217;t you do it this way?&#8221; question for us.</p>
<p class="body-text">Whether developers have migrated to IDEs or their idea of an IDE is a bunch of gVim macros or emacs lisp modules, to them it&#8217;s where they live and work. And woe betide any vendor who tries to get them to change. Even if you&#8217;re not suggesting that they change tools, and instead asking them to visit somewhere else to see what they might have done wrong in some retrospective manner, your tool is going to suffer waves of disinterest and ultimately become shelfware.</p>
<p class="body-text">Thus, static analysis has to be part of the developer&#8217;s native habitat, and more importantly, it has to work in a way that feels natural and follows the way other tools in that habitat work. For a gVim developer, issuing a &#8216;:&#8217; command is second nature, so tools in that environment should follow suit. Put that same interaction mechanism in front of a Visual Studio user, and that will make for a fun-filled afternoon of derisive commentary.</p>
<p class="body-text">At Klocwork we&#8217;ve gone through various iterations of technology design, getting closer to the developers themselves. It&#8217;s one thing to be resident as a tool within an IDE; it&#8217;s another to get the developer to &#8220;push the button&#8221; to use it. Making a button available is only changing geography, and it does nothing to help with the tool&#8217;s fundamental usability.</p>
<p class="body-text">With this in mind, we&#8217;ve recently introduced a new technology that allows static analysis to take place in much the same way as spell checking in a Word document or e-mail. That is, as you&#8217;re writing your code and the tool detects a problem with what you&#8217;re doing, it can point out the problem in a perceptually instant manner, highlight it with a squiggly underline, and deliver all the value of static analysis with none of the &#8220;what do I have to do to use it?&#8221; resistance that is typically encountered during any new tool&#8217;s introduction (see&nbsp;Figure 1).</p>
<p class="figures">
<figure>
<table width="480" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '21', 'width=875,height=580,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="21" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5567%2Ffigures%2F1" title="Following in the footsteps of word processors, Klocwork Insight highlights coding issues with a squiggly line the instant they&amp;#8217;re introduced."><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=470&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5567%2Ffigures%2F1" alt="21" width="470" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption><b>Figure 1:</b> Following in the footsteps of word processors, Klocwork Insight highlights coding issues with a squiggly line the instant they&#8217;re introduced.</figcaption>
<div class="fig-zoom">(Click graphic to zoom by 1.9x)</div>
</td>
</tr>
</table>
</figure>
<p class="body-text">Getting a tool into an IDE is tough; getting it to be useful in the part of the IDE the developer truly lives in (the editor component, whatever that looks like in the environment at hand) is really&nbsp;tough. But until you&#8217;re there, you&#8217;re a&nbsp;distraction.</p>
<p class="interview-question"><span class="interview-name">ECD:</span> Can source code analysis be used to protect embedded devices against potential security threats?</p>
<p class="body-text"><span class="interview-name">FISHER:</span> Absolutely, source code analysis has a significant role to play in threat identification and validating whatever threat model is being used to determine vulnerability in the device. The connectivity requirement is common in the embedded world today. That connection might be to another chip, or another device, or the whole Internet. In any case, there&#8217;s somebody else either sending you information or receiving information you&#8217;re sending. That&#8217;s the starting point for having to worry about your entire application design.</p>
<p class="body-text">Static analysis doesn&#8217;t typically know, or try to know, anything about your surrounding environment. Tools can sometimes be tuned to perform their analysis within certain data boundaries, for example, such as knowing that a particular input will only range between -20 and +30 because it&#8217;s a temperature sensor intended for use in Western Europe. But that kind of thing is discouraged because you&#8217;re allowing the user to define limits to what the modeling technology naturally does &#8211; that is, assume nothing and point out everything that looks wrong.</p>
<p class="body-text">In the case of threat detection, we&#8217;re most worried about how the data you&#8217;re interacting with from the outside world is used internally. Is it used to create a buffer into which you&#8217;ll read data (code or value injection), or is it used for memory allocation (Denial of Service or DoS), or perhaps interpreted as a reference into an internal data structure (hijacking or redirection)? This kind of data and path validation &#8211; that is, the path that tainted data follows from the outside world to its point of use within the code &#8211; is natural for source code analysis, as it accomplishes this modeling in order to perform everything else it does.</p>
<p class="body-text">As a wonderful gentleman at a defense contractor once said to me, &#8220;Son, it&#8217;s a bomb; it&#8217;s supposed to blow up. We just want to be sure it doesn&#8217;t get hijacked on its way.&#8221;</p>
<p class="interview-question"><span class="interview-name">ECD:</span> What educational events or online classes does Klocwork offer to help embedded designers get started with its code analysis tools?</p>
<p class="body-text"><span class="interview-name">FISHER:</span> Like any commercial organization attempting to encourage users to gain value from its tools, Klocwork provides a full suite of educational and professional services, running the gamut from introductory materials aimed at first-time users, to more advanced courses targeting secure coding and threat modeling, to full-on deployment services and mentoring.</p>
<p class="body-text">We also recently introduced the Klocwork Developer Network (<span class="hyperlink"><a href="http://developer.klocwork.com">http://developer.klocwork.com</a></span>), a website serving our users and acting as a repository for online courses, video tutorials, in-depth courseware, and the usual variety of community forums and ticketing.</p>
<p class="body-text">Each customer has something unique they wish to gain from a tool such as source code analysis, so a large part of our educational focus is on internal champions, people who take knowledge of how the tools work and how other organizations have applied them and leverage those lessons in deploying our tools for their own use. A large part of that is learning from the community, so I&#8217;ve been thrilled to see the fast uptake that the Klocwork Developer Network has seen amongst users, both as a less formal mechanism for interacting with our staff, but most importantly as a way to learn from other customers.</p>
<p class="figures">
<figure>
<table width="260" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '22', 'width=875,height=870,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="22" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5567%2Ffigures%2F2" title="ECD in 2D: Klocwork Insight&amp;#8217;s plug-in for Visual Studio continuously runs data flow analysis to accurately identify defects and security vulnerabilities. Use your smartphone, scan this code, watch a video: http://opsy.st/zdEhC1. ART"><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=250&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5567%2Ffigures%2F2" alt="22" width="250" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption>ECD in 2D: Klocwork Insight&#8217;s plug-in for Visual Studio continuously runs data flow analysis to accurately identify defects and security vulnerabilities. Use your smartphone, scan this code, watch a video: http://opsy.st/zdEhC1. </figcaption>
<div class="fig-zoom">(Click graphic to zoom)</div>
</td>
</tr>
</table>
</figure>
<p class="author-bio">Gwyn Fisher is CTO of Klocwork.</p>
<p class="contact-info">Klocwork <span class="hyperlink"><a href="mailto:info@klocwork.com">info@klocwork.com</a></span>  <span class="hyperlink"><a href="http://www.klocwork.com/blog">www.klocwork.com/blog</a></span> <span class="hyperlink"><a href="http://www.fb.com/klocwork">www.facebook.com/klocwork</a></span>  <span class="bold">www.twitter.com/</span><span class="hyperlink"><a href="https://twitter.com/#!/klocwork">@klocwork</a></span> <span class="hyperlink"><a href="http://www.klocwork.com">www.klocwork.com</a></span> </p>
</p></div>
<p></span></div></li></ul>]]></content:encoded>
			<wfw:commentRss>http://embedded-computing.com/articles/static-latent-defects-legacy-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Static analysis: Beyond a simple list of defects</title>
		<link>http://embedded-computing.com/articles/static-analysis-beyond-simple-list-defects/</link>
		<comments>http://embedded-computing.com/articles/static-analysis-beyond-simple-list-defects/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 15:00:00 +0000</pubDate>
		<dc:creator>Rutul Dave, Coverity</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Coverity]]></category>
		<category><![CDATA[diskless computer]]></category>
		<category><![CDATA[embeded system]]></category>
		<category><![CDATA[single board computer]]></category>
		<category><![CDATA[single board computer linux]]></category>
		<category><![CDATA[single board computers]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[software for engineers]]></category>
		<category><![CDATA[static analysis]]></category>
		<category><![CDATA[Static code analysis]]></category>

		<guid isPermaLink="false">http://embedded-computing.com/?guid=d1acf315cafadeea777f01a56b703c91</guid>
		<description><![CDATA[Contextual information is a valuable asset that enhances static code analysis in the quest for error-free software.]]></description>
			<content:encoded><![CDATA[<ul style='margin-left: 11px; margin-top: 0px; padding: 2px;'><li style="list-style-type: none; list-style: none; background-position: 0px 8px; background-image: url(http://cloud1.opensystemsmedia.com/arrows/9.gif); background-repeat: no-repeat;  margin-bottom: 11px; margin-top: 6px; padding-left: 19px; padding-top: 5px; font-size: 14px; font-family: arial;" ><div class="story">
<h3 class="abstract"><img alt="4" class="figure_intro wide" src="http://i.opensystemsmedia.com/?zc=F&#038;f=png&#038;h=320&#038;w=600&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5191%2Ffigures%2F4" />You&#8217;ve been diligent and used static code analysis to identify defects early during development. Great. So now what? Finding defects is just the first step in the process of ensuring software integrity. Contextual information on every identified defect is essential to prioritize fixes and maintain bug-free software.</h3>
<p><span id="more-120"></span><span class='body'>
<p class="body-text-">Embedded software is ubiquitous and provides critical functionality in a variety of devices, from the latest smartphones and gaming gadgets to life-saving medical devices. Engineering organizations creating embedded software understand that ensuring quality of code is a key differentiator and competitive advantage. Along with other methods of testing and verification, many companies have taken advantage of the benefits of code testing with modern static analysis to identify defects early in development. During the&nbsp;past few years, various reports by embedded market research firm VDC Research indicate strong growth in companies adopting static analysis as a critical test automation tool. Modern&nbsp;static analysis is arguably the most cost-effective, automated, and repeatable way to meet the challenge of ensuring the quality of complex software. </p>
<p class="body-text-">A strong reason driving this growth is that the technology used to identify critical defects such as memory corruptions, resource leaks, null pointer dereferences, and invalid memory accesses has matured to a point where finding large numbers of hard-to-find defects that traverse function and file boundaries can now be accomplished accurately, resulting in a very small number of false positives. However, the real innovation lies in providing contextual information for every defect identified. A developer needs to know why the defect exists, what impact it will have, and where it needs to be fixed. </p>
<p class="body-text-">The answer to the question of where it needs to be fixed is not as simple as knowing the file name and line number. Code branching and merging for versioning, reuse of code, and reuse of code components for development productivity allow a defect to make its way into multiple versions and products. </p>
<p class="body-text-">Consider the case of a software team with multiple branches for various versions of the product. A bug in one of these branches might exist in one or more other branches due to code replication. In another case, consider a team creating the framework to support applications for smartphones. Because they might be porting the framework onto various platforms like Windows, Android, or iPhone, it is critical that the static analysis results clearly indicate whether identified defects exist in just one place or on multiple platforms. Similarly, when software is created by aggregating from multiple sources, it is a nightmare when a particular component is used in various products, as a defect in one third-party component might end up affecting all the different products that include it. </p>
<p class="heading-1">Multiple branches for different versions of an operating system </p>
<p class="body-text-">Imagine a software development team responsible for creating a new Operating System (OS) for mobile smartphones. Because multiple mobile phone vendors (OEMs) must be supported, every vendor in the source control management system needs a development branch. In addition, each vendor typically has multiple branches for different releases and product generations. The picture starts to get complex very quickly.</p>
<p class="body-text-">Static analysis performed on every branch of the code produces a list of defects. However, depending on when a defect is introduced, it could exist in all versions or a subset. When looking at a single defect in isolation in a single branch, the challenge for developers is that they can&#8217;t gauge the severity of the defect without knowing where else it is present. A defect that is not limited to a single version or one OEM client would be severe, and fixing it would need to be prioritized over anything else. Additionally, a developer writing code to fix the defect needs to know exactly which branches in the source control management system the fix&nbsp;needs to be checked in. Analysis results that pinpoint the exact location where the defect exists and provide information such as the branches where defects occur are highly valuable to developers (see Figure 1).</p>
<p class="figures">
<figure>
<table width="480" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '21', 'width=875,height=580,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="21" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5191%2Ffigures%2F1" title="Defects duplicate due to code branching and merging."><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=470&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5191%2Ffigures%2F1" alt="21" width="470" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption><b>Figure 1:</b> Defects duplicate due to code branching and merging.</figcaption>
<div class="fig-zoom">(Click graphic to zoom by 1.9x)</div>
</td>
</tr>
</table>
</figure>
<p class="heading-1">A single framework for multiple&nbsp;platforms</p>
<p class="body-text-">On the flip side of branching, there is often a need to write code designed to run on multiple platforms. A software component such as a framework for mobile applications is usually built to run on various types of mobile phone platforms. For embedded devices, a common requirement is to build 32- and 64-bit versions of the same code base. Let&#8217;s take a simple example: </p>
<p class="body-text-"><span class="code-character">gcc &#8211;m32 -c foo.c </span></p>
<p class="body-text-">// 32-bit compile. Contains a null pointer dereference defect.</p>
<p class="body-text-"><span class="code-character">gcc -c foo.c </span></p>
<p class="body-text-">// 64-bit compile. Contains the same null pointer dereference defect.</p>
<p class="body-text-">A defect in <span class="code-character">foo.c</span> that gets triggered in both 32- and 64-bit binaries will be detected and reported as a single defect. However, because the source code is the same, a sophisticated analysis would not report it as a duplicate defect. Duplicates are as harmful as false positives in losing the developer&#8217;s trust in the static analysis&nbsp;solution.</p>
<p class="heading-1">Sharing common code&nbsp;components</p>
<p class="body-text-">In this final example, consider a team developing the platform software for a family of networking switches. Because the functionality provided by the platform software must be implemented in all products, this code component will be shared (see Figure 2). For developers working on this team, the best assessment of the severity of a defect reported by static analysis is not only the impact it will have on one switch product, but also information on all the products that use this platform software component.</p>
<p class="figures">
<figure>
<table width="480" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '22', 'width=875,height=580,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="22" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5191%2Ffigures%2F2" title="A single software component is reused in multiple products."><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=470&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5191%2Ffigures%2F2" alt="22" width="470" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption><b>Figure 2:</b> A single software component is reused in multiple products.</figcaption>
<div class="fig-zoom">(Click graphic to zoom by 1.9x)</div>
</td>
</tr>
</table>
</figure>
<p class="body-text-">A product is usually created by combining many such shared components. Each component is not only a project itself, but also a part of various other projects using it. The analysis result needs to identify that a defect in this shared component has an impact on the various projects using it. </p>
<p class="heading-1">Taking the guesswork out of code&nbsp;testing</p>
<p class="body-text-">The adoption of modern developer-side testing methods such as static analysis is a positive trend in the embedded software industry. The technology has matured to a point where it is a strong weapon in the software engineer&#8217;s arsenal. Without needing to create elaborate test cases and testing infrastructures, static analysis automatically finds critical defects as code is written and compiled. However, for static analysis to become a developer&#8217;s most valuable tool, the analysis must provide answers to questions such as &#8220;What is the impact of this defect?&#8221; and &#8220;Where do I need to check in the fix?&#8221; to help prioritize fixing the identified defects and take the guesswork out of ensuring that software is as bug-free as possible.</p>
<p class="figures">
<figure>
<table width="260" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '23', 'width=875,height=870,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="23" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5191%2Ffigures%2F3" title="ECD in 2D: Former Coverity CTO Ben Chelf explains how the software analysis capabilities offered by Coverity Integrity Center can help avoid debugging nightmares. Use your smartphone, scan this code, watch a video: http://opsy.st/ikAgqg. ART"><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=250&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5191%2Ffigures%2F3" alt="23" width="250" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption>ECD in 2D: Former Coverity CTO Ben Chelf explains how the software analysis capabilities offered by Coverity Integrity Center can help avoid debugging nightmares. Use your smartphone, scan this code, watch a video: http://opsy.st/ikAgqg. </figcaption>
<div class="fig-zoom">(Click graphic to zoom)</div>
</td>
</tr>
</table>
</figure>
<p class="author-bio"><span class="author-bio-name">Rutul Dave</span> is senior development manager at Coverity. He has several years of software development experience in embedded and real-time systems, including work developing bleeding-edge technology systems at Procket Networks, Topspin Communications, and Cisco Systems. When not evangelizing about the benefits of software integrity, Rutul scratches the coding itch by developing mobile apps and understanding the Linux kernel. He received his Master&#8217;s in Computer Science with a focus on networking and communications systems from the University of Southern California. </p>
<p class="contact-info">Coverity   <span class="hyperlink"><a href="mailto:info@coverity.com">info@coverity.com</a></span> www.coverity.com</p>
</p></div>
<p></span></div></li></ul>]]></content:encoded>
			<wfw:commentRss>http://embedded-computing.com/articles/static-latent-defects-legacy-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding concurrency errors with static analysis</title>
		<link>http://embedded-computing.com/articles/finding-concurrency-errors-static-analysis/</link>
		<comments>http://embedded-computing.com/articles/finding-concurrency-errors-static-analysis/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 15:00:00 +0000</pubDate>
		<dc:creator>Paul Anderson, GrammaTech</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[diskless computer]]></category>
		<category><![CDATA[embeded system]]></category>
		<category><![CDATA[GrammaTech]]></category>
		<category><![CDATA[single board computer]]></category>
		<category><![CDATA[single board computer linux]]></category>
		<category><![CDATA[single board computers]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[software for engineers]]></category>
		<category><![CDATA[static analysis]]></category>

		<guid isPermaLink="false">http://embedded-computing.com/?guid=88d6c66ea94987d95bcd345e06e00c2e</guid>
		<description><![CDATA[Static analysis tools aid in eliminating the concurrency pitfalls of multithreaded code.]]></description>
			<content:encoded><![CDATA[<ul style='margin-left: 11px; margin-top: 0px; padding: 2px;'><li style="list-style-type: none; list-style: none; background-position: 0px 8px; background-image: url(http://cloud1.opensystemsmedia.com/arrows/9.gif); background-repeat: no-repeat;  margin-bottom: 11px; margin-top: 6px; padding-left: 19px; padding-top: 5px; font-size: 14px; font-family: arial;" ><div class="story">
<h3 class="abstract"><img alt="4" class="figure_intro wide" src="http://i.opensystemsmedia.com/?zc=F&#038;f=png&#038;h=320&#038;w=600&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5192%2Ffigures%2F4" />Due to the rise of multicore processors, programmers increasingly need to write multithreaded code. Pitfalls such as race conditions, starvation, and deadlock make it hard to get such code right, and traditional testing can only help so much. New approaches based on static analysis are proving effective at quickly finding difficult bugs.</h3>
<p><span id="more-222"></span><span class='body'>
<p class="body-text-">Although decades of advances in miniaturization have yielded enormous performance gains for single processors, it appears this era is coming to a close. The best bet for achieving significant additional performance with single chips is through multiple cores, but only if software can be programmed to take advantage of them. </p>
<p class="body-text-">Unfortunately, concurrent programming is difficult. Even expert-level programmers familiar only with single-threaded programming often fail to appreciate that concurrent programs are susceptible to entirely new classes of defects such as race conditions, deadlocks, and starvation. It is difficult for humans to reason about concurrent programs, and some aspects of programming languages themselves are ill-suited to concurrency. Consequently, experts frequently stumble over these hazards. The following discussion describes common concurrency pitfalls and explains how static analysis tools can find such defects without executing the program.</p>
<p class="heading-1">Consequences of race conditions</p>
<p class="body-text-">A race condition arises when multiple threads of execution access a shared piece of data and at least one of them changes the value of that data without an explicit synchronization operation to separate the accesses. Depending on the interleaving of the two threads, the system can be left in an inconsistent state. </p>
<p class="body-text-">Race conditions are especially insidious because they can lurk undetected indefinitely, and only show up in rare circumstances exhibiting mysterious symptoms that are difficult to diagnose and reproduce. In particular, they are likely to survive through testing into deployed software. At best, this means increased development times; at worst, the consequences can be devastating. </p>
<p class="body-text-">One reason the Northeast Blackout of 2003 was so widespread was that a race condition in a computerized energy management system caused misleading information to be communicated to the operators. As Kevin Poulsen noted in a 2004 article (<span class="hyperlink"><a href="http://www.securityfocus.com/news/8412">www.securityfocus.com/news/8412</a></span>), &#8220;the bug had a window of opportunity measured in milliseconds.&#8221; The chances of a problem like this manifesting during testing are infinitesimal. In another case, a race condition in iOS 4.0 through 4.1 (now fixed) meant that any person with physical access to an iPhone 3G or later could bypass its passcode lock under certain conditions. </p>
<p class="body-text-">An example of a simple race condition is shown in Figure 1. A manufacturing assembly line with entry and exit sensors maintains a running count of the items currently on the line. This count is incremented every time an item enters the line and decremented every time an item reaches the end of the line and exits. If an item enters the line at the same time that another item exits, the count should be incremented and then decremented (or vice versa) for a net change of zero. However, normal increment and decrement are not atomic operations; they are composed of a sequence of individual instructions that first loads the value from memory, then modifies it locally, and finally stores it back in memory. If the updating transactions are processed in a multithreaded system without sufficient safeguards, a race condition can arise because the sensors read and write a shared piece of data: the count. The interleaving in Figure 1 results in an incorrect count of 69. There are also interleavings that can result in an incorrect count of 71, as well as some that correctly result in a count of 70.</p>
<p class="figures">
<figure>
<table width="480" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '21', 'width=875,height=580,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="21" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5192%2Ffigures%2F1" title="A race condition leads to an incorrect count of items on an assembly line."><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=470&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5192%2Ffigures%2F1" alt="21" width="470" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption><b>Figure 1:</b> A race condition leads to an incorrect count of items on an assembly line.</figcaption>
<div class="fig-zoom">(Click graphic to zoom by 1.8x)</div>
</td>
</tr>
</table>
</figure>
<p class="body-text-">For this example and for race condition bugs in general, standard debugging techniques may be ineffective for several reasons. </p>
<p class="body-text-"><span class="italics">Rare occurrence</span> means a reduced chance of noticing there is a problem. If the problem manifests infrequently, it may never show up during testing. The issue is twofold. Firstly, the number of possible interleavings of the instructions in two threads can be huge and increases enormously as the number of instructions grows. This phenomenon is known as <span class="italics">combinatorial explosion</span>. If thread A executes <span class="italics">M</span> instructions and thread B executes <span class="italics">N</span>;instructions, the possible interleavings of the two threads are:</p>
<p class="figures">
<figure>
<table width="190" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '21', 'width=875,height=661,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="21" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5192%2Fequations%2F1" title=""><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=180&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5192%2Fequations%2F1" alt="21" width="180" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption><b>Equation 1</b></figcaption>
<div class="fig-zoom">(Click graphic to zoom by 4.8x)</div>
</td>
</tr>
</table>
</figure>
<p class="body-text-">For example, given two trivial threads with 10 instructions each, there are 184,756 possible interleavings of the instructions. Real-world software is large and complex; testing every interleaving is simply impossible. Secondly, even if testers can identify a few interleavings that merit inspection, it is difficult to set up test cases to ensure they actually occur because thread scheduling can be highly nondeterministic.</p>
<p class="body-text-">If exhaustive testing is intractable, then what can developers do? One extremely useful approach is static analysis. Advanced static analysis tools such as CodeSonar use highly sophisticated symbolic execution techniques to consider many possible execution paths and interleavings at once. These techniques can find race conditions and other concurrency errors without needing to execute the program.</p>
<p class="body-text-">Several factors make race condition diagnosis difficult. Firstly, the symptoms can be perplexing. In the Figure 1 example, the running count will usually be correct, but sometimes too high and other times too low. Secondly, programmers unaccustomed to considering the particular pitfalls of multithreaded programming may spend a lot of time puzzling over the code before the possibility of a race condition occurs to them. Advanced static analysis tools are especially helpful in this regard. They identify race conditions by examining patterns of access to shared memory locations; that is, they focus on the race itself, not its symptoms. When a race condition is identified, an advanced static analysis tool will report it along with supporting information to aid the user in evaluation and debugging. The onus on the programmer is substantially reduced. </p>
<p class="heading-1">More complexity, more bugs</p>
<p class="body-text-">Race conditions are typically avoided by using locks to protect shared resources. However, locks can introduce performance bottlenecks that might prevent the program from taking advantage of the full potential of multiple cores, so programmers must exercise care in using them. It can be tricky to write code that uses locks effectively, and this complexity can lead to a different set of problems, namely deadlock and starvation.</p>
<p class="body-text-">In a deadlock, two or more threads prevent each other from making progress because each holds a lock needed by another. Figure 2 shows how a deadlock can arise with two locks used to protect two shared variables. In this example, multiple assembly lines share a count of the total number of items currently under assembly, and a second bad_items value records how many finished items failed quality control. One thread acquires the lock on count, another acquires the lock on bad_items. Neither thread can obtain the second lock it needs; thus neither can carry out its operations, nor can it get to the point where it will release its lock. As neither update can be completed, both threads are completely stuck.</p>
<p class="figures">
<figure>
<table width="480" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '22', 'width=875,height=580,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="22" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5192%2Ffigures%2F2" title="In a deadlock between two threads, neither thread can progress."><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=470&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5192%2Ffigures%2F2" alt="22" width="470" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption><b>Figure 2:</b> In a deadlock between two threads, neither thread can progress.</figcaption>
<div class="fig-zoom">(Click graphic to zoom by 1.9x)</div>
</td>
</tr>
</table>
</figure>
<p class="body-text-">Static analysis tools can identify software at risk of deadlock by flagging situations where the same locks can be acquired in different orders by different threads, such as the threads shown in Figure 2. Eliminating all such cases is sufficient to ensure that the system cannot become deadlocked. </p>
<p class="body-text-">Starvation is another problem that occurs in multithreaded programs that use locks. A thread can starve if it is waiting for a resource currently held by another thread that takes a very long time. For example, suppose the aforementioned manufacturing automation system includes a regular audit thread that examines all entry and exit records to ensure that the running count matches total items entering less total items exiting. The audit thread would need to hold locks on the count and on all sensors, so all updates must wait for the audit to finish. If the audit runs for a long time, updates can be significantly delayed. If it runs too long, the next audit may manage to acquire all the locks and start running before the outstanding thread can make any progress. In the worst case, some or all of the updates may never have the opportunity to run. </p>
<p class="body-text-">Static analysis can provide significant value here by posing questions such as, &#8220;Is there a call to a long-running library function while a lock is held?&#8221; Tools such as CodeSonar also provide mechanisms for users to add their own checks. If an in-house function f() is known to have a long running time, engineers could add a custom check that triggers a warning whenever f() is called by a thread that holds one or more locks. </p>
<p class="body-text-">Multithreading adds entirely new classes of potential bugs to those that embedded developers must consider, making it significantly more difficult to find bugs of all kinds. The latest generation of static analysis tools can help with both of these issues.  </p>
<p class="figures">
<figure>
<table width="260" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '23', 'width=875,height=870,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="23" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5192%2Ffigures%2F3" title="ECD in 2D: A demo of CodeSonar shows how the tool can identify bugs in each version of the software being analyzed. Use your smartphone, scan this code, watch a video: http://opsy.st/kSRTWh. ART"><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=250&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD5192%2Ffigures%2F3" alt="23" width="250" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption>ECD in 2D: A demo of CodeSonar shows how the tool can identify bugs in each version of the software being analyzed. Use your smartphone, scan this code, watch a video: http://opsy.st/kSRTWh. </figcaption>
<div class="fig-zoom">(Click graphic to zoom)</div>
</td>
</tr>
</table>
</figure>
<p class="author-bio"><span class="author-bio-name">Paul Anderson</span> is VP of engineering at GrammaTech, where he manages the engineering team and architects static analysis tools. He has worked in the software industry for 20 years, helping organizations including NASA, the FDA, the FAA, MITRE, Draper Laboratory, GE, Lockheed Martin, and Boeing apply automated code analysis to critical projects. He received his BSc from King&#8217;s College London and his PhD in Computer Science from City University London.</p>
<p class="contact-info">GrammaTech  paul@grammatech.com  www.grammatech.com</p>
</p></div>
<p></span></div></li></ul>]]></content:encoded>
			<wfw:commentRss>http://embedded-computing.com/articles/static-latent-defects-legacy-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Static analysis improves efficiency, reduces downstream integration costs</title>
		<link>http://embedded-computing.com/articles/static-downstream-integration-costs/</link>
		<comments>http://embedded-computing.com/articles/static-downstream-integration-costs/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 15:00:00 +0000</pubDate>
		<dc:creator>Andy Chou, Coverity</dc:creator>
				<category><![CDATA[9001 audit checklist]]></category>
		<category><![CDATA[applications embedded systems]]></category>
		<category><![CDATA[boeing 787s]]></category>
		<category><![CDATA[boeing s dreamliner]]></category>
		<category><![CDATA[cmmi software development]]></category>
		<category><![CDATA[code analyzer tool]]></category>
		<category><![CDATA[Coverity]]></category>
		<category><![CDATA[design embedded system]]></category>
		<category><![CDATA[design embedded systems]]></category>
		<category><![CDATA[detect memory leak]]></category>
		<category><![CDATA[detecting memory leak]]></category>
		<category><![CDATA[dreamliner 787 interior]]></category>
		<category><![CDATA[dreamliner 787 pictures]]></category>
		<category><![CDATA[dreamliner 787 video]]></category>
		<category><![CDATA[Embedded Software]]></category>
		<category><![CDATA[embedded software applications]]></category>
		<category><![CDATA[embedded software design]]></category>
		<category><![CDATA[embedded software projects]]></category>
		<category><![CDATA[embedded software systems]]></category>
		<category><![CDATA[embedded system software development]]></category>
		<category><![CDATA[klocwork static analysis]]></category>
		<category><![CDATA[klocwork tool]]></category>
		<category><![CDATA[memory leak detect]]></category>
		<category><![CDATA[memory leak detector]]></category>
		<category><![CDATA[metrics for software]]></category>
		<category><![CDATA[metrics in software]]></category>
		<category><![CDATA[metrics software]]></category>
		<category><![CDATA[metrics software development]]></category>
		<category><![CDATA[quality audit checklist]]></category>
		<category><![CDATA[quality software engineering]]></category>
		<category><![CDATA[software design methodology]]></category>
		<category><![CDATA[software development prototyping]]></category>
		<category><![CDATA[software engg models]]></category>
		<category><![CDATA[software estimation methodologies]]></category>
		<category><![CDATA[software lifecycle models]]></category>
		<category><![CDATA[software lifecycle process]]></category>
		<category><![CDATA[software metrics analysis]]></category>
		<category><![CDATA[software models in software engineering]]></category>
		<category><![CDATA[software process in software engineering]]></category>
		<category><![CDATA[software process methodologies]]></category>
		<category><![CDATA[software process metrics]]></category>
		<category><![CDATA[source code static analysis]]></category>
		<category><![CDATA[static analysis]]></category>
		<category><![CDATA[static code analyser]]></category>
		<category><![CDATA[static code analyzer c]]></category>
		<category><![CDATA[static code analyzers]]></category>
		<category><![CDATA[static code checker]]></category>
		<category><![CDATA[Technology Feature]]></category>
		<category><![CDATA[the dreamliner 787]]></category>

		<guid isPermaLink="false">http://embedded-computing.com/?guid=8ce262abf887226b83400661d238eed0</guid>
		<description><![CDATA[With modern military systems increasingly relying on software, new techniques are being adopted to decrease costs and increase the chances for mission success. As a result, static analysis has been gaining traction in the software development community based on its deep analysis capabilities before runtime. These static analysis tools &#8211; which augment but do not replace traditional test and debug methods &#8211; find integration errors long before integration occurs, eliminating costly late-stage integration issues.]]></description>
			<content:encoded><![CDATA[<ul style='margin-left: 11px; margin-top: 0px; padding: 2px;'><li style="list-style-type: none; list-style: none; background-position: 0px 8px; background-image: url(http://cloud1.opensystemsmedia.com/arrows/9.gif); background-repeat: no-repeat;  margin-bottom: 11px; margin-top: 6px; padding-left: 19px; padding-top: 5px; font-size: 14px; font-family: arial;" ><div class="story">
<h3 class="abstract">With modern military systems increasingly relying on software, new techniques are being adopted to decrease costs and increase the chances for mission success. As a result, static analysis has been gaining traction in the software development community based on its deep analysis capabilities before runtime. These static analysis tools &#8211; which augment but do not replace traditional test and debug methods &#8211; find integration errors long before integration occurs, eliminating costly late-stage integration issues.</h3>
<p><span id="more-16886"></span><span class='body'>
<p class="body-text">As military equipment and vehicles become increasingly modernized, they inevitably become more technologically complicated as well. In many instances, these machines represent a delicate blend of hardware and software, both of which must interact perfectly. Since the software components of these machines must work as reliably as possible in the field, it is important to perform extensive debugging and testing using a combination of techniques to eliminate defects before they cause extended delays or overruns. This is often impractical since there is usually no way to reliably test code until it is actually implemented into the equipment on which it will eventually run. Since software seldom works perfectly the first time it is executed, going back and fixing errors with conventional development methods and tools hinders productivity and diverts valuable resources and personnel from other projects that need to be completed. </p>
<p class="body-text">For instance, the Boeing 787 Dreamliner was delayed for two years because of a combination of hardware and software defects. Often, such problems are intertwined; in the case of the Dreamliner, one particular delay was the result of defects in the software that controlled the braking system. It is important to note that conventional testing did not reveal this defect before it actually became a problem and caused costly setbacks and other complications in the development process. Modern techniques like static analysis can increase the probability of problems like memory corruption and user-after-free being discovered sooner, as well as assist in achieving DO-178B&#8217;s Design Assurance Levels (DALs). A more efficient and cost-effective path than the traditional V-model, static analysis works in concert with traditional test and debug methods to ease integration woes and expense.</p>
<p class="heading-1">Static analysis and the development process</p>
<p class="body-text">Software development tends to follow a specific life cycle. One example is the V-model (Figure 1), which is commonly used in aerospace engineering. The V-model represents a holistic approach to development that attempts to reconcile project definition and the testing process over a period of time. The model begins with establishing the scope of a project, including its concepts of operation, its requirements and architecture, and the specific details of its design. </p>
<p class="figures">
<figure>
<table width="480" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '21', 'width=875,height=580,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="21" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FMES4508%2Ffigures%2F1" title="The V-model represents a holistic approach to development that attempts to reconcile project definition and the testing process over a period of time."><br />
					<img width="470" border="0" alt="21" src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=470&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FMES4508%2Ffigures%2F1" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top: 11px; line-height: 1em;">
<figcaption><b>Figure 1:</b> The V-model represents a holistic approach to development that attempts to reconcile project definition and the testing process over a period of time.</figcaption>
<div style="color: #336600; padding-top: 4px; font-size: 9px;"><b>(click graphic to zoom by 1.2x)</b></div>
</td>
</tr>
</table>
</figure>
<p class="body-text">This process starts out very abstract at higher levels and becomes gradually refined and detailed over the course of the design process. As the design is implemented, it becomes more expensive to fix problems later in the development cycle. Once the project is mostly complete and is being tested, going back and making repairs to its fundamental aspects becomes prohibitively expensive. </p>
<p class="body-text">Ultimately, many software problems are caused and then worsened by an inefficient development model and imprecise debugging procedures. Development efficiency and cost-effectiveness can be improved by eliminating software defects as early as possible with modern techniques like static analysis.</p>
<p class="body-text">Specifically, static analysis is a technique for finding defects in software without running it. It works by examining product source code, starting from individual functions, working its way up to modules, then ultimately the entire program. Static analysis can find many different kinds of defects, including memory errors in C/C++ programs. For example, static analysis can detect an error in this simple code fragment:</p>
<p class="code">int a[10];</p>
<p class="code"> for(int i = 0; i &lt; 10; i++); {</p>
<p class="code"> a[i] = 0;</p>
<p class="code"> }</p>
<p class="body-text">Sometimes it is hard for human beings to see problems in software code because they see what they want to see instead of what is actually there. When this code is turned into an executable program by a compiler, the compiler reads the source code in a mechanical and precise way, ignoring human cues like indentation and spacing. A compiler will read the example in the following way:</p>
<p class="code">int a[10];</p>
<p class="code"> for(int i = 0; i &lt; 10; i++)</p>
<p class="code">;</p>
<p class="code">{</p>
<p class="code"> a[i] = 0;</p>
<p class="code"> }</p>
<p class="body-text">Once the code has been reformatted as shown, an extra &#8220;;&#8221; character that causes the program to have a completely different meaning suddenly becomes much more visible. If this error remains uncorrected in the final program, the array access a[i] will execute only once when i = 10. The result is an assignment to a memory location past the end of the array, which might cause the program to crash. </p>
<p class="body-text">Static analysis examines the code as mechanically and precisely as a compiler would. However, instead of blindly translating the code into an executable program, a static analyzer looks for paths where the code&#8217;s function diverges from how the developer originally intended it to work. Static analysis can be done by techniques as simple as pattern matching or as advanced as interprocedural dataflow analysis and Boolean satisfiability. Regardless of technique, static analysis is custom-built to look for cases that human developers are likely to overlook or get wrong. This presents a far more efficient alternative to comprehensive line-by-line code auditing, which is not cost-effective for larger software systems.</p>
<p class="heading-1">Combine static analysis and traditional debugging</p>
<p class="body-text">Compared with a traditional method such as functional testing, static analysis presents a different set of trade-offs. Traditional testing can only detect errors in code that is actually tested, whereas static analysis can find defects in all code without any tests. Sometimes, errors found through testing are hard to reproduce and pinpoint to a specific problem in the source code. Static analysis can find problems in a repeatable, predictable fashion and will always point to a specific location in the code. On the other hand, traditional testing can find functionality errors that static analysis cannot, because static analysis does not attempt to compare the behavior of the program against an expected result. Static analysis can also lose precision when analyzing deep program properties, so it might miss some defects. Therefore, static analysis is meant to augment the effectiveness of traditional methods instead of replacing them outright.</p>
<p class="body-text">Since static analysis works with existing toolsets and compilers, there is no need to change current development practices. Static analysis can be applied frequently (even on nightly builds) for the duration of the project starting immediately after the first line of code has been written. Essentially, if the project&#8217;s code base can be successfully compiled, static analysis can be used to debug it and eliminate problems long before the project is delivered to quality assurance personnel for final testing.</p>
<p class="heading-1">Integration benefits of static analysis</p>
<p class="body-text">Static analysis also works well in a team-oriented environment. Developers can use static analysis to check each other&#8217;s contributions for consistency and check for conflicts caused by code written by different team members. This can work within a single project or even scale to larger scenarios where integration between several projects is required to create a complicated system.</p>
<p class="body-text">Static analysis can also do more than find simple code defects; as mentioned, it is capable of analyzing the interactions between different components before they are integrated together. In the V-model of software development, testing and verification start with individual components. When these components meet their low-level specifications, they are integrated together for higher-level testing against system requirements. If software integration is performed strictly according to this ideal, the integration phase introduces a high degree of risk because the individual components will be interacting for the first time. These interactions are likely to expose problems with the original project specifications, particularly regarding how the system requirements and architecture are translated into detailed design requirements and source code. Static analysis tools can analyze the interactions between software components as soon as they are written, catching some of these expensive integration problems during the implementation phase. The tools accomplish this by finding problems in Application Programming Interface (API) usage by analyzing code across procedure boundaries even if the procedures are in different software components.</p>
<p class="heading-1">Maximizing efficiency with static&nbsp;analysis</p>
<p class="body-text">Software is being used to improve military systems such as smart bombs and unmanned drones in ways that were once impossible. Static analysis tools, such as those offered by Coverity, are also a part of this trend. Static analysis tools &#8211; when combined with traditional test and debug methods &#8211; effectively analyze software and detect code errors before runtime, minimizing risks and costs while maximizing the value of investment in software development. </p>
<p class="author-bio">Andy Chou is chief scientist and cofounder of Coverity. He is responsible for advancing source code analysis technology as well as furthering the state-of-the-art in software quality and security industry-wide. He received his Ph.D. in Computer Science from Stanford University and his B.S. in Electrical Engineering from UC Berkeley. He can be contacted at achou@coverity.com.</p>
<p class="contact-info">Coverity 415-321-5200 www.coverity.com</p>
</p></div>
<p></span></div></li></ul>]]></content:encoded>
			<wfw:commentRss>http://embedded-computing.com/articles/static-latent-defects-legacy-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Static analysis aids code portability</title>
		<link>http://embedded-computing.com/articles/static-aids-code-portability/</link>
		<comments>http://embedded-computing.com/articles/static-aids-code-portability/#comments</comments>
		<pubDate>Fri, 26 Feb 2010 15:00:00 +0000</pubDate>
		<dc:creator>Chris Tapp, LDRA</dc:creator>
				<category><![CDATA[applications embedded systems]]></category>
		<category><![CDATA[c embedded programming]]></category>
		<category><![CDATA[c programming embedded systems]]></category>
		<category><![CDATA[c software development]]></category>
		<category><![CDATA[code analyzer tool]]></category>
		<category><![CDATA[design embedded hardware]]></category>
		<category><![CDATA[design embedded system]]></category>
		<category><![CDATA[design embedded systems]]></category>
		<category><![CDATA[designing embedded systems]]></category>
		<category><![CDATA[embedded c programmer]]></category>
		<category><![CDATA[embedded hardware design]]></category>
		<category><![CDATA[embedded microcontroller systems]]></category>
		<category><![CDATA[Embedded Software]]></category>
		<category><![CDATA[embedded software applications]]></category>
		<category><![CDATA[embedded software developers]]></category>
		<category><![CDATA[embedded software programming]]></category>
		<category><![CDATA[embedded software projects]]></category>
		<category><![CDATA[embedded system c programming]]></category>
		<category><![CDATA[embedded system designing]]></category>
		<category><![CDATA[embedded system development]]></category>
		<category><![CDATA[embedded system hardware]]></category>
		<category><![CDATA[embedded system software development]]></category>
		<category><![CDATA[embedded systems c programming]]></category>
		<category><![CDATA[embedded systems developer]]></category>
		<category><![CDATA[embedded systems hardware]]></category>
		<category><![CDATA[klocwork static analysis]]></category>
		<category><![CDATA[klocwork tool]]></category>
		<category><![CDATA[ldra]]></category>
		<category><![CDATA[metrics software development]]></category>
		<category><![CDATA[programming embedded system]]></category>
		<category><![CDATA[programming for embedded systems]]></category>
		<category><![CDATA[realtime embedded system]]></category>
		<category><![CDATA[realtime embedded systems]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[software development prototyping]]></category>
		<category><![CDATA[software embedded]]></category>
		<category><![CDATA[software embedded system]]></category>
		<category><![CDATA[software embedded systems]]></category>
		<category><![CDATA[software engg models]]></category>
		<category><![CDATA[software for embedded systems]]></category>
		<category><![CDATA[software lifecycle process]]></category>
		<category><![CDATA[software process methodologies]]></category>
		<category><![CDATA[software process metrics]]></category>
		<category><![CDATA[source code static analysis]]></category>
		<category><![CDATA[static analysis]]></category>
		<category><![CDATA[static code analyser]]></category>
		<category><![CDATA[static code analyzer]]></category>
		<category><![CDATA[static code analyzer c]]></category>
		<category><![CDATA[static code analyzers]]></category>
		<category><![CDATA[static code checker]]></category>
		<category><![CDATA[what is process in software engineering]]></category>
		<category><![CDATA[what is software engineering about]]></category>

		<guid isPermaLink="false">http://embedded-computing.com/?guid=807bb82d7f4d50b4061235bc901f1044</guid>
		<description><![CDATA[Static analysis tools help developers ensure that porting will proceed as planned.]]></description>
			<content:encoded><![CDATA[<ul style='margin-left: 11px; margin-top: 0px; padding: 2px;'><li style="list-style-type: none; list-style: none; background-position: 0px 8px; background-image: url(http://cloud1.opensystemsmedia.com/arrows/9.gif); background-repeat: no-repeat;  margin-bottom: 11px; margin-top: 6px; padding-left: 19px; padding-top: 5px; font-size: 14px; font-family: arial;" ><div class="story"><span id="more-33"></span><span class='body'>
<p class="body-text">Code reuse is often a major consideration within new projects, both in terms of making use of legacy code from preceding projects and as a foundation for those that will follow. Static analysis can be used to ensure that legacy code does not become a source of issues within a project and to guarantee that any code produced during its development will not afflict any projects that draw on it as a code base.</p>
<p class="body-text">C code is particularly vulnerable to porting issues, especially since compilers cannot be expected to detect them as code will comply with the language specification (assuming no language extensions are used). It is therefore essential that developers use static analysis tools to confirm that porting will proceed as planned. Static analysis tools can help with this in several ways.</p>
<p class="heading-1">Portability issues arising from the size of int</p>
<p class="body-text">The precision (number of bits) in an int can differ between systems. To deal with this, it is common to define a set of typedefs to map system types onto application types. The following example can be defined for a 16-bit architecture:</p>
<p class="code">typedef unsigned char U8;</p>
<p class="code">typedef unsigned int U16;</p>
<p class="code">typedef unsigned long U32;</p>
<p class="author-bio">This example could then be changed to the following if the code were ported to a 32-bit architecture:</p>
<p class="code">typedef unsigned char U8;</p>
<p class="code">typedef unsigned short U16;</p>
<p class="code">typedef unsigned int U32;</p>
<p class="body-text">However, porting is not that simple, as changes in the size of int can have some less obvious effects on the code. For example, any expression whose result depends on the effects of integer promotion may exhibit different behavior. Because of this, such a change is only appropriate if the precision within all expressions containing objects of the affected types fits the purpose. Static analysis can be used to validate this assumption.</p>
<p class="body-text">Compilers will not report any of these issues because the code is perfectly valid for the targeted environment, even though it might not behave as expected.</p>
<p class="heading-1">Portability issues arising from compiler implementation</p>
<p class="body-text">Differences in the implementation-defined, unspecified, or undefined behavior associated with the compiler can lead to defects when porting.</p>
<p class="body-text">Implementation-defined behavior is behavior that might differ between compilers but is documented by the compiler vendor. Static analysis tools can detect code that invokes such behavior so that it can be eliminated to facilitate porting.</p>
<p class="body-text">Unspecified or undefined behavior can also be detected; however, it presents more than just a portability issue, as such behavior can change in an undocumented way between different versions of the same compiler and might even change between various use cases within the same compiler. Code invoking such behavior could work but most likely would be very fragile. Notably, moving to a different version of a compiler can be considered as porting.</p>
<p class="body-text">Compilers are not required to detect uses of implementation-defined, unspecified, or undefined behavior because the code is perfectly valid.</p>
<p class="heading-1">Coding standards</p>
<p class="body-text">Publicly available coding standards like MISRA C:2004 (www.misra-c.com), which can be rigorously enforced by static analysis tools, include rules that defend against these portability issues. The subsequent examples make use of this standard.</p>
<p class="heading-2">Integer conversions within C</p>
<p class="body-text">The rules governing how and when different arithmetic types are implicitly converted during the evaluation of an expression within C are complex. To ensure that results are as expected when code is ported, all operations within an expression should be conducted in the same type after all such implicit conversions have been taken into consideration.</p>
<p class="body-text">The implicit conversions associated with integer promotion can easily lead to code performing in a way that is significantly different from what developers expect. Integer promotion basically requires that any type smaller than an int (such as char, short) be converted to an int before it is used as an operand within an expression. Many embedded systems make extensive use of these types because they often allow for more efficient usage of memory resources, which could be restricted to save cost, space, and power.</p>
<p class="body-text">Integer promotion is value-preserving (meaning the magnitude and sign are preserved), but the signedness of an object might change. Additionally, the expression will be evaluated in a type that is wider than the type of the operands. Consider the following example:</p>
<p class="code">U8 u8a = 200U;</p>
<p class="code">U8 u8b = 100U;</p>
<p class="code">U8 u8r = u8a + u8b;</p>
<p class="body-text">In this example, u8a and u8b are both converted to signed int with a width of at least 16 bits before the addition takes place. The result of the addition is then implicitly converted back to 8 bits before it is stored in u8r. In this case, developers are likely to expect the result (44), as it is reasonable to assume they are aware of the modulo 2 arithmetic that takes place on assignment. This means that the result is effectively the same as it would have been if the operation had taken place with 8-bit precision (integer promotion did not affect the result).</p>
<p class="body-text">However, when integer promotion occurs at the same time as an implicit widening conversion, there is potential for confusion. Consider the following:</p>
<p class="code">U16 u16a = 0xffffU;</p>
<p class="code">U16 u16b = 0x0001U;</p>
<p class="code">U32 u32r = u16a + u16b;</p>
<p class="body-text">On a 32-bit architecture, u32r will have type unsigned int while u16a and u16b will have type unsigned short. Integer promotion will cause the operands to be converted to signed int before the addition takes place, and the result will be implicitly converted to unsigned int on assignment, giving a final value of 0&#215;10000. Developers can (perhaps justifiably) rely on the integer promotion taking place to ensure that the addition does not wrap as it would if 16-bit arithmetic were used.</p>
<p class="body-text">If developers decide to port the code to a 16-bit architecture, u32r will then have type unsigned long and u16a and u16b will have type unsigned int. This time, no conversions will be applied to the operands, which are already unsigned int, before the addition takes place (also in unsigned int), and the result of 0&#215;0000 will be implicitly converted to unsigned long on assignment, giving a final value of 0&#215;0000. The assumption that the addition would be performed in a wider type is now no longer valid, and there is a risk that an unintended wraparound has occurred.</p>
<p class="body-text">This shows how easily code can exhibit different behavior when it is ported from one platform to another. The real issue here relates to the implicit widening conversion that takes place on assignment of the result. This can be eliminated by ensuring that the expression is always evaluated with the necessary precision using a cast, for example:</p>
<p class="code">u32r = ( u32 ) u16a + u16b;</p>
<p class="body-text">The ( u32 ) cast ensures that the expression is always evaluated in a type with the appropriate precision. In the previous example, this means the expression is evaluated in unsigned long rather than unsigned int. As shown in Figure 1, static analysis can easily detect implicit widening.</p>
<figure>
<table width="480" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '21', 'width=875,height=580,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="21" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD4459%2Ffigures%2F1" title="Static analysis tools such as the LDRA tool suite can highlight issues within valid C code that can cause functional errors when ported. Because the code is valid C, compilers will not detect these issues."><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=470&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD4459%2Ffigures%2F1" alt="21" width="470" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption><b>Figure 1:</b> Static analysis tools such as the LDRA tool suite can highlight issues within valid C code that can cause functional errors when ported. Because the code is valid C, compilers will not detect these issues.</figcaption>
<div class="fig-zoom">(Click graphic to zoom by 1.9x)</div>
</td>
</tr>
</table>
</figure>
<p class="body-text">Integer promotion can also affect other operations. Consider the following:</p>
<p class="code">u16a = 0x1234U;</p>
<p class="code">u16r = ~u16a &gt;&gt; 8;</p>
<p class="body-text">On a 16-bit architecture, this will lead to the bits of u16a being inverted and the top byte shifting into the bottom byte, assigning 0x00ED into u16r.</p>
<p class="body-text">However, on a 32-bit architecture, u16a will be converted to signed int (with 32 bits) before the complement takes place, resulting in the value 0xFFED being assigned into u16r.</p>
<p class="body-text">Once again, the use of a cast will ensure the behavior is as expected:</p>
<p class="code">u16r = ( U16 )~u16a &gt;&gt; 8;</p>
<p class="heading-1">Evaluating code suitability</p>
<p class="body-text">Static analysis tools are an invaluable aid to code porting. As shown in Figure 2,  these tools permit developers to evaluate legacy code and ensure that new code is developed in a way that allows it to be ported.</p>
<figure>
<table width="480" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '22', 'width=875,height=580,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="22" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD4459%2Ffigures%2F2" title="Static analysis tool reporting such as this example from the LDRA tool suite enables efficient evaluation of the suitability of code for porting."><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=470&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD4459%2Ffigures%2F2" alt="22" width="470" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption><b>Figure 2:</b> Static analysis tool reporting such as this example from the LDRA tool suite enables efficient evaluation of the suitability of code for porting.</figcaption>
<div class="fig-zoom">(Click graphic to zoom by 1.9x)</div>
</td>
</tr>
</table>
</figure>
<p class="body-text">Early adoption of static analysis in a project life cycle will ensure that legacy code is validated as early as possible and that any new code is portable from the outset. Developers can rapidly recover the initial outlay involved in using such tools through reduced development time and significantly lower residual defect levels. </p>
<div class="story">  </div>
<p class="author-bio"><span class="author-photo"></span>Chris Tapp is a Field Applications Engineer at LDRA, based in the UK, where he specializes in programming standards. With more than 20 years of experience in embedded software development, he spent most of his career as a consultant in the automotive, industrial control, and information technology industries. Chris serves in the MISRA C working group and is currently chairman of the MISRA C++ working group. He graduated from the University of Durham in 1987.</p>
<p class="contact-info">LDRA +44-0151-649-9300 <a href="mailto:chris.tapp@ldra.com">chris.tapp@ldra.com</a>  <a href="http://www.coware.com">www.ldra.com</a></p>
</p></div>
<p></span></div></li></ul>]]></content:encoded>
			<wfw:commentRss>http://embedded-computing.com/articles/static-latent-defects-legacy-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Integrating static analysis with a compiler and database</title>
		<link>http://embedded-computing.com/articles/integrating-static-analysis-a-compiler-database/</link>
		<comments>http://embedded-computing.com/articles/integrating-static-analysis-a-compiler-database/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 15:00:00 +0000</pubDate>
		<dc:creator>S. Tucker Taft, SofCheck</dc:creator>
				<category><![CDATA[automated source code analysis]]></category>
		<category><![CDATA[c code analyzer]]></category>
		<category><![CDATA[c source code analysis]]></category>
		<category><![CDATA[c static analysis]]></category>
		<category><![CDATA[c# code analysis]]></category>
		<category><![CDATA[code analysis]]></category>
		<category><![CDATA[code analysis software]]></category>
		<category><![CDATA[code analysis tool]]></category>
		<category><![CDATA[code analysis tools]]></category>
		<category><![CDATA[code analyzer]]></category>
		<category><![CDATA[code coverage]]></category>
		<category><![CDATA[code coverage tools]]></category>
		<category><![CDATA[code metrics]]></category>
		<category><![CDATA[code security]]></category>
		<category><![CDATA[code static analysis]]></category>
		<category><![CDATA[computer security software]]></category>
		<category><![CDATA[crossword compiler]]></category>
		<category><![CDATA[cyclomatic complexity]]></category>
		<category><![CDATA[data integration]]></category>
		<category><![CDATA[dynamic analysis software]]></category>
		<category><![CDATA[fast compiler]]></category>
		<category><![CDATA[fortify code analysis]]></category>
		<category><![CDATA[Klocwork]]></category>
		<category><![CDATA[open source code analysis]]></category>
		<category><![CDATA[open source static analysis]]></category>
		<category><![CDATA[open source static analysis tools]]></category>
		<category><![CDATA[open source static code analysis]]></category>
		<category><![CDATA[qbasic compiler]]></category>
		<category><![CDATA[secure c programming]]></category>
		<category><![CDATA[secure software]]></category>
		<category><![CDATA[SofCheck]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[software development]]></category>
		<category><![CDATA[software metrics]]></category>
		<category><![CDATA[software quality]]></category>
		<category><![CDATA[source code analysis]]></category>
		<category><![CDATA[source code analysis tool]]></category>
		<category><![CDATA[source code analysis tools]]></category>
		<category><![CDATA[source code analyzer]]></category>
		<category><![CDATA[source code scan]]></category>
		<category><![CDATA[source code security]]></category>
		<category><![CDATA[static analysis]]></category>
		<category><![CDATA[static analysis tool]]></category>
		<category><![CDATA[static analysis tools]]></category>
		<category><![CDATA[Static code analysis]]></category>
		<category><![CDATA[static code analysis tools]]></category>
		<category><![CDATA[static source code analysis]]></category>

		<guid isPermaLink="false">http://embedded-computing.com/?guid=acd6095dda9b821f78e4c0f35600aa76</guid>
		<description><![CDATA[Static analysis tools are becoming more integrated into the software development process. Saving data from the compiler, change history, and error information during the process instead of as a post-code step can make static analysis more productive.]]></description>
			<content:encoded><![CDATA[<ul style='margin-left: 11px; margin-top: 0px; padding: 2px;'><li style="list-style-type: none; list-style: none; background-position: 0px 8px; background-image: url(http://cloud1.opensystemsmedia.com/arrows/9.gif); background-repeat: no-repeat;  margin-bottom: 11px; margin-top: 6px; padding-left: 19px; padding-top: 5px; font-size: 14px; font-family: arial;" ><div class="story">
<h3 class="abstract">Static analysis tools are becoming more integrated into the software development process. Saving data from the compiler, change history, and error information during the process instead of as a post-code step can make static analysis more productive.</h3>
<p><span id="more-291"></span><span class='body'>
<p class=Bodytext>Advanced static analysis tools are becoming increasingly critical in embedded systems development. Going well beyond older static analysis tools that were, in effect, coding style checkers, new tools statically analyze a source program&#8217;s control and data flow, thereby detecting bugs and vulnerabilities such as potential buffer overflows, uses of uninitialized variables, accesses through null pointers, and susceptibility to security attacks (SQL injection, cross-site scripting, and so on). </p>
<p class=Bodytext>However, these advanced tools raise several issues. First, the tools need to understand the semantics of the program being analyzed &#8211; that is, they have to compile the program &#8211; to perform the required control- and data-flow analysis. To do this, they must be closely integrated into the build environment, so that all include files or other specification modules that might be needed at compile time are identified and available. Second, the amount of output produced by these advanced tools can be daunting, with each diagnostic message requiring careful scrutiny to determine if it reflects a real problem, and if so how, to address it. </p>
<p class=Bodytext>Integrating the static analysis tool more closely with the software development tool chain can alleviate both of these challenges. In the first case, integrating the static analysis tool tightly with the compiler largely eliminates build environment problems and makes the user interface simple and familiar. In the second case, the extensive output can be managed by storing all output in an historical database, allowing the programmer to focus on deltas between a known good release and the current state of the source, rather than dealing with all the messages at each step. </p>
<h1>Integrating with the compiler</h1>
<p class=Bodytext>A static analysis tool that goes beyond simple syntax checking generally needs much of the power of a compiler front end so that it can base its analysis on the semantics of the program. This is because the same syntactic form can often have different interpretations based on the meanings of its constituents. For example, the expression F(N) in Ada might be (among other things) an array reference, function invocation, or type conversion. </p>
<p class=Bodytext>Having access to the underlying semantics of the program allows the tool to follow every name appearing within the program back to the declaration that introduces that name, even in the presence of overloading, generic templates, or renaming. The tool will know the type of every object and every expression, and will identify where any implicit runtime checks occur. These implicit runtime checks might include a check for dereferencing a null pointer and a check for indexing outside the bounds of an array. Even languages without implicit runtime checks can define certain runtime actions to have unspecified semantics, such as an integer arithmetic overflow or an array index that is out of bounds. A static analysis tool will need to know when the language semantics allow such unspecified (and thus unpredictable) behavior. </p>
<p class=Bodytext>Because of the need to include the power of a compiler front end, many static analysis tools are built on top of preexisting compiler technology for the language of interest. Unfortunately, the compiler technology chosen by the tool&#8217;s builder might be unrelated to the compiler used by the tool&#8217;s customer. When this happens, the static analysis tool might not work on the customer&#8217;s code as written. <o:p></o:p></p>
<p class=Bodytext>For example, if the customer program uses compiler-specific features (such as interrupt handling or special memory-mapping facilities), then there is no guarantee that they will be supported at all, or in the same way, by the static analysis tool&#8217;s underlying compiler front end technology. Even for portable code, the customer&#8217;s compiler and the static analysis tool&#8217;s underlying technology might have different bugs or subtly different interpretations of the rules of the language. And even when the interpretations match, the commands to compile the program &#8211; the command line switches that control source code search paths, preprocessor support, and other features &#8211; might differ significantly. Thus, the build process for a complex program can be difficult to translate into a make process for performing static analysis on the program. </p>
<p class=Bodytext>To address these issues, the clear solution is to integrate the advanced static analysis engine with the same compiler technology the customer is using. The static analysis engine must therefore be somewhat independent of the intermediate representation used by any particular compiler technology, so that the tool can be easily adapted to support multiple compiler front ends. <o:p></o:p></p>
<p class=Bodytext>One approach is for the static analysis engine to have its own intermediate representation specifically designed to support the advanced analyses the tool performs. Adapting to support a new compiler front end requires writing a translation module that transforms the compiler&#8217;s intermediate representation (the output of the front end) to the program representation used by the static analysis engine. The translation module outputs the result into a file for later use. The intermediate language translator can either be linked to the compiler front end or run as a stand-alone program, reading the compiler&#8217;s intermediate representation, transforming it, and then writing out the analysis engine&#8217;s intermediate representation. This process is illustrated in Figure 1. </p>
<p class=Figures>
<figure>
<table width="480" border="0" align="center" cellpadding="2" cellspacing="0">
<tr>
<td align="center" >
<p>				<a onclick="popup=window.open(this.href, '21', 'width=875,height=580,scrollbars=no,resizable=yes'); popup.focus(); return false;" id="21" href="http://i.opensystemsmedia.com/?bg=ffffff&#038;q=90&#038;w=871&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD4434%2Ffigures%2F1" title="The intermediate language translator reads the compiler&amp;#8217;s intermediate representation, transforms it, and writes out the static analysis engine&amp;#8217;s intermediate representation."><br />
					<img src="http://i.opensystemsmedia.com/?q=94&#038;bg=ffffff&#038;w=470&#038;f=jpg&#038;src=http%3A%2F%2Fattachments.opensystemsmedia.com%2FECD4434%2Ffigures%2F1" alt="21" width="470" border="0" /><br />
				</a>
				</td>
</tr>
<tr>
<td class="caption" align="center" style="padding-top:10px;line-height:1em">
<figcaption><b>Figure 1:</b> The intermediate language translator reads the compiler&#8217;s intermediate representation, transforms it, and writes out the static analysis engine&#8217;s intermediate representation.</figcaption>
<div class="fig-zoom">(Click graphic to zoom by 1.6x)</div>
</td>
</tr>
</table>
</figure>
<p class=Bodytext>When this integration approach is adopted, static analysis becomes just another part of the build process, performed either during compilation or, to take advantage of whole program analysis, during the link step. A key advantage to users is that the invocation of the static analysis tool only involves providing an additional command line switch to the compiler and/or linker. There is no need to create a specialized build script for the tool or maintain two sets of sources (one that works with the compiler, and one that works with the static analysis tool). </p>
<h1>Integrating with the development environment </h1>
<p class=Bodytext>Because software development is often conducted through graphical Integrated Development Environments (IDEs) such as Eclipse, it is natural to integrate the static analysis tool and the compiler into the IDE. The overall interface to the tool will then be immediately familiar to the programmer, reducing the learning curve and increasing the likelihood that the tool will be used on a regular basis. </p>
<p class=Bodytext>Messages generated by the static analysis tool must be handled like error or warning messages generated by the compiler, and managed and viewed in the same way by the user. Given that multiple IDEs are in use, each with its own message format, the static analysis tool will need to represent its messages so that they can be readily transformed into whatever format the IDE expects. </p>
<p class=Bodytext>A natural choice for message representation is XML, given its tagged, self-describing approach to capturing message characteristics. A side benefit of using XML is that it helps simplify the process of internationalizing the application, so that the messages can be displayed in the natural language preferred by the customer. </p>
<h1>Integrating with an historical database </h1>
<p class=Bodytext>Once the advanced static analysis tool is integrated with the compiler and IDE, the next issue is dealing with the potentially large number of messages that such a tool can provide. Because advanced static analysis tools are looking for possible runtime logic errors and security vulnerabilities, they have to simulate the runtime program execution (identify the set of potential execution states) and determine under what conditions an undesirable state might be reached. Unfortunately, this is rarely a simple case of yes or no. There are many shades of grey where the level of vulnerability depends on factors that might be unknown to the tool or beyond its powers of analysis. </p>
<p class=Bodytext>This issue is sometimes phrased in terms of soundness versus precision. A tool searching for problematic constructs is said to be sound if it identifies all of the problems it is looking for (no false negatives). But soundness generally comes at the expense of precision. The tool could generate a large number of false positives, which are warnings or errors identifying issues that are not real problems. Consider this simple example using C-like syntax: </p>
<p class=Code><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt'>int k, m, n; <o:p></o:p></span></p>
<p class=Code><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt'>&#8230; // Complicated code that assigns a positive value to m <o:p></o:p></span></p>
<p class=Code><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt'>&#8230; // and that does not assign to n <o:p></o:p></span></p>
<p class=Code><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt'>if (m&lt;0){ <o:p></o:p></span></p>
<p class=Code><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt'><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>k=n; <o:p></o:p></span></p>
<p class=Code><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt'><span style="mso-spacerun: yes">&nbsp;&nbsp; </span>&#8230; <o:p></o:p></span></p>
<p class=Code><span style='font-size:9.0pt;mso-bidi-font-size:10.0pt'>}<o:p></o:p></span></p>
<p class=Bodytext>A tool might not be able to deduce that the m&lt;0 condition on the if statement is false, and thus might warn that the body of the if statement is referencing an uninitialized variable (n). The actual problem is the opposite: The body of the if statement is code that will never be executed, sometimes referred to as dead or unreachable code. </p>
<p class=Bodytext>A tool developer must decide whether to opt for soundness (make sure that no actual violations go undetected) or precision (make sure that all reported violations are real errors). When a tool is intended for safety-critical or high-security systems, the scales are tipped to soundness. The developer using such a tool must have confidence that all violations are detected. But this raises the issue mentioned earlier regarding how to deal with the potentially large number of false positives that could be generated. This problem is especially noticeable when the tool is applied to legacy software (code that was developed before applying the static analysis tool). The number of messages a user needs to review for a large application can be daunting. </p>
<p class=Bodytext>Integrating the advanced static analysis tool with an historical database makes productive use of the tool, minimizing the problems caused by false positives, even for a complex application developed prior to the tool&#8217;s use. The critical concept is the notion of a baseline and the ability for the tool to highlight the deltas relative to such a baseline. By recording all the results of each tool run in an historical database, the tool can identify deltas (changes) between any two runs. </p>
<h1>Data becomes more useful</h1>
<p class=Bodytext>For the comparison between analysis runs to work effectively, messages must be uniquely identifiable without referring to specific line numbers, which can switch from one version of the source code to another without any significant change. One way to identify a message without a line number is to record the text of the message (or the corresponding XML), along with the name of the function in which it appears, and a sequence number if the text of the message is identical to some prior message in the same function. </p>
<p class=Bodytext>Presuming messages are stored in the database using this line-number-independent unique identifier as the key, the tool can then easily identify whether a given message is new or has been generated previously. This keeps the overall size of the historical database manageable. Rather than repeatedly storing the text of all messages for all invocations of the tool, the tool only needs to store the text of a given message once, along with an indication of the range of tool invocations where the message appeared (which run was the first where the message was generated, and which run was the first where it did not appear). </p>
<p class=Bodytext>This historical database makes it straightforward for the user interface to display or highlight only those messages that are new since a specified baseline. This allows the tool to be used effectively even on large applications with significant amounts of legacy code. A known good release of the application can be run through the analysis tool as a baseline. The current development version of the application can be analyzed, with the results from analyzing this known good release as the baseline. Those working on the development version can focus on any messages associated with changes they have made since the known good release, rather than having to wade through messages that relate to legacy code. Eventually, effort can be devoted to going through this backlog of messages, but that can be scheduled at a time that is convenient or corresponds to a larger reengineering effort. </p>
<p class=Bodytext>Another benefit provided by integration with an historical database is the ability to collect comments from users who review the analysis results. In some cases, a particular message might require significant investigation to understand the possible implications. It is important that this work be captured. The historical database is a natural place to record what the user learns. <o:p></o:p></p>
<p class=Bodytext>In addition, if the user determines that the identified code is safe and secure, the historical database can record that the given message should be suppressed from subsequent output, and can record the supporting rationale for suppressing the message. Alternatively, if the identified code needs to be changed, the historical database can record the Program Trouble Report (PTR) ID assigned to the problem, allowing traceability between a problem-tracking system and the analysis tool&#8217;s historical results. When the tool detects that a message with an associated PTR ID has disappeared, it can be configured to directly notify the problem-tracking system that the associated PTR record can be closed. Automating the process of closing PTRs can provide significant relief to a typically overburdened quality assurance team. </p>
<h1>Static analysis as a key component of the development process </h1>
<p class=Bodytext>With applications getting larger and more complex, advanced static analysis tools play a key role in modern software development by significantly reducing the effort needed to find bugs and vulnerabilities that can compromise a system&#8217;s reliability, safety, or security. But many organizations are not yet taking full advantage of these tools, often because of the potentially high entry barrier to incorporate them into the daily software development process (builds, regression tests, and other steps). </p>
<p class=Bodytext>As discussed previously, two important steps can reduce this entry barrier: tool integration with the compiler technology and with an historical database. This is not simply a theoretical proposal. CodePeer, an advanced static analysis tool developed jointly by SofCheck and AdaCore, serves as an automated code reviewer for Ada. This tool has been fully integrated into AdaCore&#8217;s GNAT Pro Ada development environment and is invokable through the GNAT Programming Studio IDE. </p>
<p class=Bodytext>Integration with the compiler largely eliminates the challenge of porting the source code to the analysis tool. The same compiler front end that successfully compiles the source code can also generate the intermediate representation that the advanced static analysis engine needs for more in-depth analyses. Furthermore, the same command line switches, source code structure, and make files can be used to compile and statically analyze the code. The compiler front end will automatically handle any implementation-specific features used by the application. </p>
<p class=Bodytext>The second major step toward reducing the entry barrier is integration with an historical database, which allows developers working on large systems to focus on their recent changes and defer reviewing issues in previously released legacy code until a more appropriate time. Additionally, integration with the database allows developers to record the results of reviewing the tool output and the rationale behind decisions to either suppress the message or file it as a PTR. Finally, the database automatically verifies a fix and closes the PTR. With these two steps, static analysis can become an important and productive tool in the embedded software developer&#8217;s toolbox.</p>
<p class=Authorbio><b style='mso-bidi-font-weight:normal'>S. Tucker Taft </b>is founder and CTO of SofCheck, Inc., based in Burlington, Massachusetts. Tucker founded SofCheck in 2002 to provide tools and technology for enhancing software development quality and productivity. Prior to that, he was a Chief Scientist at Intermetrics, Inc., where he led the Ada 95 language revision effort. Tucker holds a BA in Chemistry from Harvard College.</p>
<p class=Contactinfo style='mso-list:none;tab-stops:12.0pt'><b style='mso-bidi-font-weight:normal'>SofCheck</b><br /> 781-750-8068<br /> <a href="mailto:info@sofcheck.com">info@sofcheck.com</a> <br /> <a href="http://www.sofcheck.com">www.sofcheck.com</a></p>
<p></span></div></li></ul>]]></content:encoded>
			<wfw:commentRss>http://embedded-computing.com/articles/static-latent-defects-legacy-software/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
