Thursday, May 30, 2013

Congratulations RTEMS GSoC 2013 Students

Congratulations to the accepted students in GSoC 2013 for the RTEMS Project! We had many fine applicants again this year, and were able to accept 9 students to do projects with us this summer. In alphabetical order by project name, we accepted these students/projects:
  • Shubham Somani
    • Application Configuration GUI for RTEMS.
  • Deng Hengyi
    • Atomic Operations and SMP lock debug tool for RTEMS
  • Dhananjay M Balan
    • Better debugging support for RTEMS in GDB.
  • Hesham Moustafa AL-matary
    • Enhance low-level API of libmm (Memory Protection & Caches)
  • Philipp E
    • Paravirtualization layer in RTEMS
  • Jin Yang
    • Porting CAN driver, LinCAN, to RTEMS
  • Peng Fan
    • RTEMS Runtime Loader
  • Sree Harsha Konduri
    • SMP Aware Scheduler
  • Vipul Nayyar
    • Unified APIs
These are all important, ambitious projects that will be of great benefit to RTEMS if successful, and will definitely teach the students a lot about project management and open source development.

Thursday, May 9, 2013

Who's calling me? Visualizing function callers

My problem today was to determine and visualize the set of functions (callers) that call another set of functions (callees). For this purpose, I knew the callees function names all started with the same word, say "Callee", and that none of the caller's names start with Callee. For C programs, namespaces are often formed by a coding convention that specifies the format of function names and groups related functions by a common "first name".

I found a simple tool, egypt, that relies on gcc and GraphViz to generate a visualization of a program's static call graph. A call graph is a natural way to visualize what I need, but my requirements are slightly different than the usual. Normally a call graph will include all of the directed edges from callers to callees in an entire program or subset of its functions. What I need is just the nodes of immediate callers of the Callee functions, that is, the subgraph induced by the caller and callee vertices in the call graph.

For my needs, the tool lacks the ability to specify a set of vertices and generate the subgraph they induce. The induced subgraph could be found if I could:
  • specify terminal nodes (callees)
  • filter nodes that do not have an edge to terminal nodes
Rather than implement this ability, I realized I could wrap egypt with a bit of shell code to produce the graph(s) I want.

egypt processes RTL dumps produced by gcc. It outputs a call graph for the RTL dump files passed in. The first thing to do then is to compile the project to visualize using gcc with the -fdump-rtl-expand flag. This produces the *.expand files required by egypt. My first attempt was using gcc 4.4.7, which dumps all of the .expand files in the root directory of the build. For projects with multiple source files having the same name, the .expand files overwrite each other. I switched to gcc 4.7.1 because it dumps the .expand files in the same directory as the .o files are generated. Then, I revisited some old tricks to gather the .expand files into a separate directory for analysis while keeping the project's directory structure.

Now, if I just wanted the callgraph of the Callees, I could easily grep for the .expand files containing functions that start with Callee and pass them to egypt. However, to get the subgraph of caller->Callee is trickier. What I did was to use egypt on each of the .expand files individually and filter the output for edges to a Callee. This gives exactly the set of nodes and edges I need. Then I just need to wrap the output similarly to how egypt does to produce a graph file for GraphViz. The resulting script looks something like,
echo "digraph callgraph {"
files=`find . -name "*.expand"`
for f in $files
  egypt --include-external $f | grep Callee_ \
        | grep -v Callee_.*-\> | grep -v Callee_.*\"\;
echo "}"
The --include-external is necessary to force egypt to produce caller nodes for which it does not find a definition. The second line of greps are to exclude any calls originating from Callee, and to discard any uncalled Callee. Redirect the output of the script to a file, say, and then it can be processed with one of the layout engines in the dot tools, like
$> dot -Teps -o callgraph-neato.eps

As an example, I processed the RTEMS Supercore Scheduler package. For this package, the Callee is _Scheduler. I processed the output with the circo drawing filter.
Supercore Scheduler Callers, with Scheduling Functions filled in Grey

Some further improvements could be made. It might also be interesting to visualize the paths (open walks) that end at the Callees. Also, the egypt tool works only on the static call graph, so indirect function calls e.g. through function pointers are not captured. Making use of dynamic profiling tools that generate a call graph, such as gprof or callgrind, could improve the accuracy of the visualization.

Tuesday, May 7, 2013

Software Licenses with RTEMS

The RTEMS license is a modified version of the GPL version 2 that includes an exception to permit including headers and linking against RTEMS object files statically. Normally, the GPL can only be linked statically with other GPL code, or rather, linking statically with GPL code would cause your code to become GPL code. The LGPL is not a suitable alternative, because it either requires use of a shared library that can be re-linked, or release of the linked (application) code. And newer versions (GPL version 3) are completely unsuitable for embedded systems due to the relinking restriction which is technically challenging.

A problem for RTEMS is there are no copyleft licenses that are compatible with the RTEMS license. Thus, RTEMS Project has to reject any code that uses the GPL or LGPL, even though RTEMS seems to use the GPL itself---this is because of the exception for static linking, and also because an upstream GPL version 2 project could at any time switch to GPL version 3 and become totally unusable. In practice, RTEMS can only accept original code contributed under the RTEMS License and code that has a permissive license.

I could not find any license that provides the copyleft protection of a software project while still allowing static linking of proprietary software. Maybe there is some subtle legal or technical issue that I do not understand, but it seems like such a license ought to exist somewhere that protects the free software while permitting applications to use it; a sort-of "Embedded GPL".

Some things that RTEMS could do better include:
  • Collect all of the copyright and license disclaimers for users
  • Collect all of the advertising restrictions, or move those encumbered files to a secondary repository
  • Switch from the GPL + linking exception, but to what I do not know
Update 5/8/13: Identified that RTEMS uses version 2 of the GPL, and give some background on why RTEMS has not and will never switch to version 3.