[PATCH 2/4] covoar: Use DWARF to map addresses to source files and lines.

Joel Sherrill joel at rtems.org
Sat May 5 16:17:40 UTC 2018


On Sat, May 5, 2018, 10:57 AM Vijay Kumar Banerjee <vijaykumar9597 at gmail.com>
wrote:

> Hello,
>
> I'm getting this build failure after applying this patch
>
> ---
> Build failed
>  -> task in 'ccovoar' failed with exit status 1:
> {task 140086064254560: cxx app_common.cc -> app_common.cc.1.o}
> ['/usr/bin/g++', '-std=c++11', '-O2', '-g', '-Itester/covoar',
> '-I../tester/covoar', '-Irtemstoolkit', '-I../rtemstoolkit',
> '-Irtemstoolkit/elftoolchain/libelf',
> '-I../rtemstoolkit/elftoolchain/libelf',
> '-Irtemstoolkit/elftoolchain/common',
> '-I../rtemstoolkit/elftoolchain/common', '-Irtemstoolkit/libiberty',
> '-I../rtemstoolkit/libiberty', '../tester/covoar/app_common.cc', '-c',
> '-o/home/lunatic/development/rtems/test/rtems-tools/build/tester/covoar/app_common.cc.1.o']
>

I don't see an error. Just the command. Does waf -v show more? Were there
error messages after the command?

>
>
> -- vijay
>
> On 5 May 2018 at 14:10, Chris Johns <chrisj at rtems.org> wrote:
>
>> ---
>>  tester/covoar/DesiredSymbols.cc | 122
>> ++--------------------------------------
>>  tester/covoar/ExecutableInfo.cc |  80 +++++++++++++++++---------
>>  tester/covoar/ExecutableInfo.h  |  41 +++++++++++---
>>  tester/covoar/covoar.cc         |   2 +-
>>  tester/covoar/wscript           |   2 +-
>>  5 files changed, 94 insertions(+), 153 deletions(-)
>>
>> diff --git a/tester/covoar/DesiredSymbols.cc
>> b/tester/covoar/DesiredSymbols.cc
>> index 9957b28..79ee78d 100644
>> --- a/tester/covoar/DesiredSymbols.cc
>> +++ b/tester/covoar/DesiredSymbols.cc
>> @@ -449,123 +449,13 @@ namespace Coverage {
>>
>>    )
>>    {
>> -    char*                              base;
>> -    char*                              cStatus;
>> -    char                               command[512];
>> -    std::string                        fileName;
>> -    CoverageRanges::ranges_t::iterator ritr;
>> -    char                               rpath[PATH_MAX];
>> -    FILE*                              tmpfile;
>> -
>> -    // Open a temporary file for the uncovered ranges.
>> -    tmpfile = fopen( "ranges1.tmp", "w" );
>> -    if ( !tmpfile ) {
>> -      fprintf(
>> -        stderr,
>> -        "ERROR: DesiredSymbols::determineSourceLines - "
>> -        "unable to open %s\n",
>> -        "ranges1.tmp"
>> -      );
>> -      exit(-1);
>> -    }
>> -
>> -    // Write the range addresses to the temporary file.
>> -    for (ritr =  theRanges->set.begin();
>> -         ritr != theRanges->set.end();
>> -         ritr++ ) {
>> -      fprintf(
>> -        tmpfile,
>> -        "0x%08x\n0x%08x\n",
>> -        ritr->lowAddress - theExecutable->getLoadAddress(),
>> -        ritr->highAddress - theExecutable->getLoadAddress()
>> -      );
>> -    }
>> -
>> -    fclose( tmpfile );
>> -
>> -    // Invoke addr2line to generate the source lines for each address.
>> -    if (theExecutable->hasDynamicLibrary())
>> -      fileName = theExecutable->getLibraryName();
>> -    else
>> -      fileName = theExecutable->getFileName();
>> -
>> -    sprintf(
>> -      command,
>> -      "%s -Ce %s <%s | dos2unix >%s",
>> -      TargetInfo->getAddr2line(),
>> -      fileName.c_str(),
>> -      "ranges1.tmp",
>> -      "ranges2.tmp"
>> -    );
>> -
>> -    if (system( command )) {
>> -      fprintf(
>> -        stderr,
>> -        "ERROR: DesiredSymbols::determineSourceLines - "
>> -        "command (%s) failed\n",
>> -        command
>> -      );
>> -      exit( -1 );
>> -    }
>> -
>> -    // Open the addr2line output file.
>> -    tmpfile = fopen( "ranges2.tmp", "r" );
>> -    if ( !tmpfile ) {
>> -      fprintf(
>> -        stderr,
>> -        "ERROR: DesiredSymbols::determineSourceLines - "
>> -        "unable to open %s\n",
>> -        "ranges2.tmp"
>> -      );
>> -      exit(-1);
>> +    for (auto& r : theRanges->set) {
>> +      std::string location;
>> +      theExecutable->getSourceAndLine(r.lowAddress, location);
>> +      r.lowSourceLine = rld::path::basename (location);
>> +      theExecutable->getSourceAndLine(r.highAddress, location);
>> +      r.highSourceLine = rld::path::basename (location);
>>      }
>> -
>> -    // Process the addr2line output.
>> -    for (ritr =  theRanges->set.begin();
>> -         ritr != theRanges->set.end();
>> -         ritr++ ) {
>> -
>> -      cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, tmpfile );
>> -      if ( cStatus == NULL ) {
>> -        fprintf(
>> -          stderr,
>> -          "ERROR: DesiredSymbols::determineSourceLines - "
>> -          "Out of sync in addr2line output\n"
>> -        );
>> -        exit( -1 );
>> -      }
>> -      inputBuffer[ strlen(inputBuffer) - 1] = '\0';
>> -
>> -      // Use only the base filename without directory path.
>> -#ifdef _WIN32
>> -      #define realpath(N,R) _fullpath((R),(N),_MAX_PATH)
>> -#endif
>> -      realpath( inputBuffer, rpath );
>> -      base = basename( rpath );
>> -
>> -      ritr->lowSourceLine = std::string( base );
>> -
>> -      cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, tmpfile );
>> -      if ( cStatus == NULL ) {
>> -        fprintf(
>> -          stderr,
>> -          "ERROR: DesiredSymbols::determineSourceLines - "
>> -          "Out of sync in addr2line output\n"
>> -        );
>> -        exit( -1 );
>> -      }
>> -      inputBuffer[ strlen(inputBuffer) - 1] = '\0';
>> -
>> -      // Use only the base filename without directory path.
>> -      realpath( inputBuffer, rpath );
>> -      base = basename( rpath );
>> -
>> -      ritr->highSourceLine = std::string( base );
>> -    }
>> -
>> -    fclose( tmpfile );
>> -    unlink( "ranges1.tmp" );
>> -    unlink( "ranges2.tmp" );
>>    }
>>
>>    SymbolInformation* DesiredSymbols::find(
>> diff --git a/tester/covoar/ExecutableInfo.cc
>> b/tester/covoar/ExecutableInfo.cc
>> index c41d931..1755e93 100644
>> --- a/tester/covoar/ExecutableInfo.cc
>> +++ b/tester/covoar/ExecutableInfo.cc
>> @@ -7,6 +7,8 @@
>>
>>  #include <stdio.h>
>>
>> +#include <rld.h>
>> +
>>  #include "ExecutableInfo.h"
>>  #include "app_common.h"
>>  #include "CoverageMap.h"
>> @@ -18,24 +20,36 @@ namespace Coverage {
>>    ExecutableInfo::ExecutableInfo(
>>      const char* const theExecutableName,
>>      const char* const theLibraryName
>> -  )
>> +    ) : executable(theExecutableName),
>> +        loadAddress(0)
>>    {
>> -    executableName = theExecutableName;
>> -    loadAddress = 0;
>> -    libraryName = "";
>>      if (theLibraryName)
>>        libraryName = theLibraryName;
>> -    theSymbolTable = new SymbolTable();
>> +    try {
>> +      executable.open();
>> +      executable.begin();
>> +      executable.load_symbols(symbols);
>> +      debug.begin(executable.elf());
>> +      debug.load_debug();
>> +    } catch (rld::error re) {
>> +      std::cerr << "error: "
>> +                << re.where << ": " << re.what
>> +                << std::endl;
>> +      exit(2);
>> +    } catch (...) {
>> +      exit(2);
>> +    }
>>    }
>>
>>    ExecutableInfo::~ExecutableInfo()
>>    {
>> -    if (theSymbolTable)
>> -      delete theSymbolTable;
>> +    debug.end();
>> +    executable.end();
>> +    executable.close();
>>    }
>>
>>    void ExecutableInfo::dumpCoverageMaps( void ) {
>> -    ExecutableInfo::coverageMaps_t::iterator  itr;
>> +    ExecutableInfo::CoverageMaps::iterator  itr;
>>
>>      for (itr = coverageMaps.begin(); itr != coverageMaps.end(); itr++) {
>>        fprintf( stderr, "Coverage Map for %s\n", ((*itr).first).c_str()
>> );;
>> @@ -44,21 +58,22 @@ namespace Coverage {
>>    }
>>
>>    void ExecutableInfo::dumpExecutableInfo( void ){
>> -    fprintf( stdout, "\n== Executable info ==\n");
>> -    fprintf( stdout, "executableName = %s\n", executableName.c_str());
>> -    fprintf( stdout, "libraryName = %s\n", libraryName.c_str());
>> -    fprintf( stdout, "loadAddress = %u\n", loadAddress);
>> -    theSymbolTable->dumpSymbolTable();
>> +    std::cout << std::endl
>> +              << "== Executable info ==" << std::endl
>> +              << "executable = " << getFileName () << std::endl
>> +              << "library = " << libraryName << std::endl
>> +              << "loadAddress = " << loadAddress << std::endl;
>> +    theSymbolTable.dumpSymbolTable();
>>    }
>>
>>    CoverageMapBase* ExecutableInfo::getCoverageMap ( uint32_t address )
>>    {
>> -    CoverageMapBase*         aCoverageMap = NULL;
>> -    coverageMaps_t::iterator it;
>> -    std::string              itsSymbol;
>> +    CoverageMapBase*       aCoverageMap = NULL;
>> +    CoverageMaps::iterator it;
>> +    std::string            itsSymbol;
>>
>>      // Obtain the coverage map containing the specified address.
>> -    itsSymbol = theSymbolTable->getSymbol( address );
>> +    itsSymbol = theSymbolTable.getSymbol( address );
>>      if (itsSymbol != "") {
>>        it = coverageMaps.find( itsSymbol );
>>        aCoverageMap = (*it).second;
>> @@ -67,12 +82,12 @@ namespace Coverage {
>>      return aCoverageMap;
>>    }
>>
>> -  const std::string& ExecutableInfo::getFileName ( void ) const
>> +  const std::string ExecutableInfo::getFileName ( void ) const
>>    {
>> -    return executableName;
>> +    return executable.name().full();
>>    }
>>
>> -  const std::string& ExecutableInfo::getLibraryName( void ) const
>> +  const std::string ExecutableInfo::getLibraryName( void ) const
>>    {
>>      return libraryName;
>>    }
>> @@ -83,9 +98,9 @@ namespace Coverage {
>>    }
>>
>>
>> -  SymbolTable* ExecutableInfo::getSymbolTable ( void ) const
>> +  SymbolTable* ExecutableInfo::getSymbolTable ( void )
>>    {
>> -    return theSymbolTable;
>> +    return &theSymbolTable;
>>    }
>>
>>    CoverageMapBase* ExecutableInfo::createCoverageMap (
>> @@ -95,8 +110,8 @@ namespace Coverage {
>>      uint32_t           highAddress
>>    )
>>    {
>> -    CoverageMapBase                          *theMap;
>> -    ExecutableInfo::coverageMaps_t::iterator  itr;
>> +    CoverageMapBase                        *theMap;
>> +    ExecutableInfo::CoverageMaps::iterator  itr;
>>
>>      itr = coverageMaps.find( symbolName );
>>      if ( itr == coverageMaps.end() ) {
>> @@ -109,13 +124,26 @@ namespace Coverage {
>>      return theMap;
>>    }
>>
>> +  void ExecutableInfo::getSourceAndLine(
>> +    const unsigned int address,
>> +    std::string&       line
>> +  )
>> +  {
>> +    std::string file;
>> +    int         lno;
>> +    debug.get_source (address, file, lno);
>> +    std::ostringstream ss;
>> +    ss << file << ':' << lno;
>> +    line = ss.str ();
>> +  }
>> +
>>    bool ExecutableInfo::hasDynamicLibrary( void )
>>    {
>> -     return (libraryName != "");
>> +    return !libraryName.empty();
>>    }
>>
>>    void ExecutableInfo::mergeCoverage( void ) {
>> -    ExecutableInfo::coverageMaps_t::iterator  itr;
>> +    ExecutableInfo::CoverageMaps::iterator  itr;
>>
>>      for (itr = coverageMaps.begin(); itr != coverageMaps.end(); itr++) {
>>        SymbolsToAnalyze->mergeCoverageMap( (*itr).first, (*itr).second );
>> diff --git a/tester/covoar/ExecutableInfo.h
>> b/tester/covoar/ExecutableInfo.h
>> index 20ea9bf..9106db3 100644
>> --- a/tester/covoar/ExecutableInfo.h
>> +++ b/tester/covoar/ExecutableInfo.h
>> @@ -11,6 +11,10 @@
>>  #include <stdint.h>
>>  #include <string>
>>
>> +#include <rld-dwarf.h>
>> +#include <rld-files.h>
>> +#include <rld-symbols.h>
>> +
>>  #include "CoverageMapBase.h"
>>  #include "SymbolTable.h"
>>
>> @@ -67,14 +71,14 @@ namespace Coverage {
>>       *
>>       *  @return Returns the executable's file name
>>       */
>> -    const std::string& getFileName( void ) const;
>> +    const std::string getFileName( void ) const;
>>
>>      /*!
>>       *  This method returns the library name associated with the
>> executable.
>>       *
>>       *  @return Returns the executable's library name
>>       */
>> -    const std::string& getLibraryName( void ) const;
>> +    const std::string getLibraryName( void ) const;
>>
>>      /*!
>>       *  This method returns the load address of the dynamic library
>> @@ -88,7 +92,7 @@ namespace Coverage {
>>       *
>>       *  @return Returns a pointer to the symbol table.
>>       */
>> -    SymbolTable* getSymbolTable( void ) const;
>> +    SymbolTable* getSymbolTable( void );
>>
>>      /*!
>>       *  This method creates a coverage map for the specified symbol.
>> @@ -107,6 +111,15 @@ namespace Coverage {
>>        uint32_t           highAddress
>>      );
>>
>> +    /*!
>> +     *  This method gets the source location, the file and line number
>> given an
>> +     *  address.
>> +     */
>> +    void getSourceAndLine(
>> +      const unsigned int address,
>> +      std::string&       location
>> +    );
>> +
>>      /*!
>>       *  This method indicates whether a dynamic library has been
>>       *  associated with the executable.
>> @@ -132,15 +145,25 @@ namespace Coverage {
>>    private:
>>
>>      /*!
>> -     *  This map associates a symbol with its coverage map.
>> +     *  The ELF executable.
>>       */
>> -    typedef std::map<std::string, CoverageMapBase *> coverageMaps_t;
>> -    coverageMaps_t coverageMaps;
>> +    rld::files::object executable;
>>
>>      /*!
>> -     *  This member variable contains the name of the executable.
>> +     *  The DWARF data to the ELF executable.
>> +     */
>> +    rld::dwarf::file debug;
>> +
>> +    /*!
>> +     *  The executable's symbol table.
>> +     */
>> +    rld::symbols::table symbols;
>> +
>> +    /*!
>> +     *  This map associates a symbol with its coverage map.
>>       */
>> -    std::string executableName;
>> +    typedef std::map<std::string, CoverageMapBase *> CoverageMaps;
>> +    CoverageMaps coverageMaps;
>>
>>      /*!
>>       *  This member variable contains the name of a dynamic library
>> @@ -158,7 +181,7 @@ namespace Coverage {
>>       *  This member variable contains a pointer to the symbol table
>>       *  of the executable or library.
>>       */
>> -    SymbolTable* theSymbolTable;
>> +    SymbolTable theSymbolTable;
>>
>>    };
>>  }
>> diff --git a/tester/covoar/covoar.cc b/tester/covoar/covoar.cc
>> index 5c87402..09c86c2 100644
>> --- a/tester/covoar/covoar.cc
>> +++ b/tester/covoar/covoar.cc
>> @@ -186,7 +186,7 @@ int main(
>>    Coverage::ExecutableInfo*     executableInfo = NULL;
>>    std::string                   executableExtension = "exe";
>>    std::string                   coverageExtension = "cov";
>> -  Coverage::CoverageFormats_t   coverageFormat;
>> +  Coverage::CoverageFormats_t   coverageFormat =
>> Coverage::COVERAGE_FORMAT_QEMU;
>>    Coverage::CoverageReaderBase* coverageReader = NULL;
>>    char*                         executable = NULL;
>>    const char*                   explanations = NULL;
>> diff --git a/tester/covoar/wscript b/tester/covoar/wscript
>> index c0270d8..55d5ec9 100644
>> --- a/tester/covoar/wscript
>> +++ b/tester/covoar/wscript
>> @@ -70,7 +70,7 @@ def build(bld):
>>      #
>>      # The list of modules.
>>      #
>> -    modules = ['rld', 'elf', 'iberty']
>> +    modules = ['rld', 'dwarf', 'elf', 'iberty']
>>
>>      bld.stlib(target = 'ccovoar',
>>                source = ['app_common.cc',
>> --
>> 2.15.1
>>
>> _______________________________________________
>> devel mailing list
>> devel at rtems.org
>> http://lists.rtems.org/mailman/listinfo/devel
>>
>
> _______________________________________________
> devel mailing list
> devel at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20180505/b121545e/attachment-0001.html>


More information about the devel mailing list