Autobuild & Code Sanity

Under:

This page will contain results from code-sanity tools i.e. tools checking for code syntax, memory leak, profiling etc ... and tips on how to correct those problems.
Most, if not all, pages here are generated automatically. If you encountered an error in the formatting, please send me a note ...

 



AutoBuild

AutoBuild is a tool which automatically builds/compiles our libraries based on what has been committed during the day. From time to time, please consult those pages and remember the following guideline for code submission into the repository :

  • Code submitted to cvs must compile and run under Linux platform.
  • Compilation should not give any serious warnings.

AutoBuild is self documented, just type AutoBuild.pl -h for all command line options.

AutoBuild behavior may be altered using directives. Directives are tags (key=value pairs) to be placed in a configuration file. The configuration file name is .ABrc_$^O where $^O is the string returned by the perl command % perl -e 'print $^O'. The following directives are allowed. If you have multiple values for one directive, each should be on a separate line.

  • SKIP_DIRS=XXX
    Excludes XXX from compilation, this directive will be passed to cons (the build system in STAR). This works only for directories.
    Example:
    SKIP_DIRS=StEbyePool
     
  • CO_DIRS=XXX   
    This directive forces the full tree to be CVS check out. Normally, AutoBuild only updates trees (which means that new sub-directories would not appear by defaults). This directive only works on directories and should not be used extensively as it is resource intensive (re-check out the entire directory).
    Example:
    CO_DIRS=StRoot/StEEmcPool
     
  • EX_DIRS=XXX     - This directives indicates that the item XXX (already present and deployed) should be ignored from CVS UPDATE. Practically, AutoBuild will rename the item XXX to a temporary name and restore. This directive works on files or directories.
    Example:
    EX_DIRS=StChain
     
  • #
    Not a directive per-se, this is indicate the start of a comment (the rest of the line is ignored)
    Examples: 
    SKIP_DIRS=StJetmaker  # Disabled 2008/07/23
    # the following lines are for blabla
    
     

 


Valgrind

Valgrind is a flexible tool for debugging and profiling Linux-x86 executable. The tool consists of a core, which provides a synthetic x86 CPU in software, and a series of "skins", each of which is a debugging or profiling tool.For more information valgrind, check its documentation page and the quick tutorial for STAR.


Profiling, Valgrind Results

  • Run-time - sorry, runtime profiling results were removed (nobody looked at them and it used lots of resources).

 


Profiling using gprof

gprof is the gcc based profiler and requires your code to be compiled with special options as well as the main executable (root4star or starsim). However, STAR make (a.k.a. 'cons') fully supports compiling with gprof options and our "dev" library level should have a gprof ready library version.

To compile your own code with gprof option and switch to the gprof based environment, do:

% setup gprof
% cons

It should suffice. This is equivalent of

% setenv GPROF yes
% stardev
% cons

gprof is generally enabled using the -pg option with gcc.

Do not use optiomization when using profiling.

How to use gprof information?

After you run your executable, a file called gmon.out created in the current directory.

  • A "flat profile" can be obtained with the gprof command, passing the executable itself and the gmon.out file as follows
    % gprof `which root4star` gmon.out -p >root4star_flat.txt
    You may get warnings like the following
    BFD: .sl44_gcc346/GBIN/root4star(.rel.plt): relocation 601 has invalid symbol index 11543
    
    Ignore them to first order. The output is a flat file which may look like the below example:
    Each sample counts as 0.01 seconds.
      %   cumulative   self              self     total           
     time   seconds   seconds    calls   s/call   s/call  name    
     15.84      1.92     1.92                             TNamed::~TNamed()
     14.93      3.73     1.81        1     1.81     1.81  TNamed::TNamed(char const*, char const*)
      7.76      4.67     0.94  1330034     0.00     0.00  TString::Length() const
      7.18      5.54     0.87                             iucomp_
      6.85      6.37     0.83                             TNamed::TNamed()
      6.44      7.15     0.78 23558243     0.00     0.00  TString::Pref() const
      4.95      7.75     0.60                             TNamed::Hash() const
      4.37      8.28     0.53    69453     0.00     0.00  agsvolu_
      3.55      8.71     0.43                             main
      2.89      9.06     0.35      558     0.00     0.00  mzrelb_
      2.48      9.36     0.30        1     0.30     0.30  TObject::operator new(unsigned int)
      1.82      9.58     0.22        1     0.22     0.29  ggclos_
      1.65      9.78     0.20   197509     0.00     0.00  agsmate_
      1.65      9.98     0.20                             glvolu_
      1.16     10.12     0.14                             TNamed::IsSortable() const
      0.91     10.23     0.11  2487240     0.00     0.00  gstint_
      0.83     10.33     0.10                             longest_match
      0.83     10.43     0.10                             mzchln_
    ...
    
    This output will be followed by a lexicon explaining all columns. Note that lines wihout a number of calls is a function which was found on the stack but not compiled with profiling options (this may happen for some of the ROOT functions as seen above).
     
  • A call graph can be generated by using a command similar to
    % gprof `which root4star` gmon.out -q >root4star_callg.txt
    An example of such output may be (same program)
    index % time    self  children    called     name
                                                     
    [1] 30.2 0.00 3.67 TGiant3::TGiant3(char const*, int, int, int) [1]
    0.00 1.86 1/1 TGiant3::Aginit(int&, int&, int&) [3]
    0.00 1.81 1/1 StarMC::StarMC(char const*, char const*) [4]
    0.00 0.00 1/1 TGiant3::LoadAddress() [10142]
    -----------------------------------------------

    [2] 15.8 1.92 0.00 TNamed::~TNamed() [2]
    -----------------------------------------------
    ...
    0.07 1.72 61289/61289 TString::operator+=(char const*) [6]
    [7] 14.8 0.07 1.72 61289 TString::Append(char const*, int) [7]
    0.94 0.78 1330020/1330034 TString::Length() const [8]
    -----------------------------------------------
    0.00 0.00 14/1330034 TGiant3::Aginit(char const*) [55]
    0.94 0.78 1330020/1330034 TString::Append(char const*, int) [7]
    [8] 14.2 0.94 0.78 1330034 TString::Length() const [8]
    0.78 0.00 23558243/23558243 TString::Pref() const [13]
    ...
    -----------------------------------------------
    <spontaneous> [72] 0.2 0.03 0.00 deflate_slow [72]
    as for the flat profile, gprof will add the report a lexicon explaining the diverse fields. The interpretation is less obvious so, let us explain the base principles.
    • The call graph shows how much time was spent in each function and its children. In other words, the %tage and time are cumulative for all children.
    • The lines full of dashes divide this table into entries, one for each function.
    • Each entry has one or more lines. In each entry, the primary line is the one that starts with an index number in square brackets. The end of this line says which function the entry is for.
    • The preceding lines in the entry describe the callers of this function and the following lines describe its subroutines (also called children when we speak of the call graph). If the caller of a function cannot be determined, <spontaneous> is printed instead.
    • The entries are sorted by time spent in the function and its subroutines.
    In our example, TGiant3::TGiant3(char const*, int, int, int) is the first entry, TNamed::~TNamed() is the second and so on. Our example chain spent (for what it could profile and measure) 30.2% of its time in TGiant3::TGiant3() and its children in the stack (so,don't add up the %tage but rather, follow the call stack and see where the program spend most of its time). In the clal stack of TGiant3::TGiant3(), TGiant3::Aginit is next but the program spend in this branch 15.3% of its time (again, this is this function and any other derived from this call stack). If an entry has no other lines afterward, the %tage then is indicative ofn the real time the program has spent in that routine.
     

More information could be found on the gprof help pages.