Changeset 6a4859e in rtems-tools


Ignore:
Timestamp:
Aug 26, 2017, 8:15:56 AM (22 months ago)
Author:
Cillian O'Donnell <cpodonnell8@…>
Branches:
master
Children:
4600903
Parents:
4cee5c3
git-author:
Cillian O'Donnell <cpodonnell8@…> (08/26/17 08:15:56)
git-committer:
Chris Johns <chrisj@…> (08/29/17 08:06:11)
Message:

covoar: Use rld tempfile and add signals to clean up in event of crash.

Use rld tempfile for temporary files and add fatal signal handling to clean
them up in the event of a crash.

Location:
tester/covoar
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • tester/covoar/ObjdumpProcessor.cc

    r4cee5c3 r6a4859e  
    2121#include "SymbolTable.h"
    2222#include "TargetFactory.h"
     23
     24#include "rld.h"
     25#include "rld-process.h"
    2326
    2427namespace Coverage {
     
    232235  }
    233236
    234   FILE* ObjdumpProcessor::getFile( std::string fileName )
    235   {
    236     char               dumpFile[128];
    237     FILE*              objdumpFile;
    238     char               buffer[ 512 ];
    239     int                status;
    240 
    241     sprintf( dumpFile, "%s.dmp", fileName.c_str() );
    242 
    243     // Generate the objdump.
    244     if (FileIsNewer( fileName.c_str(), dumpFile )) {
    245       sprintf(
    246         buffer,
    247         "%s -Cda --section=.text --source %s | sed -e \'s/ *$//\' >%s",
    248         TargetInfo->getObjdump(),
    249         fileName.c_str(),
    250         dumpFile
    251       );
    252 
    253       status = system( buffer );
    254       if (status) {
    255         fprintf(
    256           stderr,
    257           "ERROR: ObjdumpProcessor::getFile - command (%s) failed with %d\n",
    258           buffer,
    259           status
    260         );
    261         exit( -1 );
    262       }
    263     }
    264 
    265     // Open the objdump file.
    266     objdumpFile = fopen( dumpFile, "r" );
    267     if (!objdumpFile) {
    268       fprintf(
    269         stderr,
    270         "ERROR: ObjdumpProcessor::getFile - unable to open %s\n",
    271         dumpFile
    272       );
    273       exit(-1);
    274     }
    275 
    276     return objdumpFile;
     237  void ObjdumpProcessor::getFile(
     238    std::string fileName,
     239    rld::process::tempfile& objdumpFile,
     240    rld::process::tempfile& err
     241    )
     242  {
     243    rld::process::status        status;
     244    rld::process::arg_container args = { TargetInfo->getObjdump(),
     245                                         "-Cda", "--section=.text", "--source",
     246                                         fileName };
     247    try
     248    {
     249      status = rld::process::execute( TargetInfo->getObjdump(),
     250               args, objdumpFile.name(), err.name() );
     251      if ( (status.type != rld::process::status::normal)
     252           || (status.code != 0) ) {
     253        throw rld::error( "Objdump error", "generating objdump" );
     254      }
     255    } catch( rld::error& err )
     256      {
     257        std::cout << "Error while running" << TargetInfo->getObjdump()
     258                  << "for" << fileName << std::endl;
     259        std::cout << err.what << " in " << err.where << std::endl;
     260        return;
     261      }
     262
     263    objdumpFile.open( true );
    277264  }
    278265
     
    296283
    297284  void ObjdumpProcessor::loadAddressTable (
    298     ExecutableInfo* const executableInformation
    299   )
    300   {
    301     char*              cStatus;
    302     int                items;
    303     FILE*              objdumpFile;
    304     uint32_t           offset;
    305     char               terminator;
     285    ExecutableInfo* const    executableInformation,
     286    rld::process::tempfile&  objdumpFile,
     287    rld::process::tempfile&  err
     288  )
     289  {
     290    int          items;
     291    uint32_t     offset;
     292    char         terminator;
     293    std::string  line;
    306294
    307295    // Obtain the objdump file.
    308     if (!executableInformation->hasDynamicLibrary())
    309       objdumpFile = getFile( executableInformation->getFileName() );
     296    if ( !executableInformation->hasDynamicLibrary() )
     297      getFile( executableInformation->getFileName(), objdumpFile, err );
    310298    else
    311       objdumpFile = getFile( executableInformation->getLibraryName() );
     299      getFile( executableInformation->getLibraryName(), objdumpFile, err );
    312300
    313301    // Process all lines from the objdump file.
    314     while ( 1 ) {
     302    while ( true ) {
    315303
    316304      // Get the line.
    317       cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, objdumpFile );
    318       if (cStatus == NULL) {
     305      objdumpFile.read_line( line );
     306      if ( line.empty() ) {
    319307        break;
    320308      }
    321       inputBuffer[ strlen(inputBuffer) - 1] = '\0';
    322309
    323310      // See if it is the dump of an instruction.
    324311      items = sscanf(
    325         inputBuffer,
     312        line.c_str(),
    326313        "%x%c",
    327314        &offset, &terminator
     
    329316
    330317      // If it looks like an instruction ...
    331       if ((items == 2) && (terminator == ':')){
     318      if ((items == 2) && (terminator == ':')) {
    332319        objdumpList.push_back(
    333320          executableInformation->getLoadAddress() + offset
     
    338325
    339326  void ObjdumpProcessor::load(
    340     ExecutableInfo* const executableInformation
    341   )
    342   {
    343     char*              cStatus;
    344     std::string        currentSymbol = "";
    345     uint32_t           endAddress;
    346     uint32_t           instructionOffset;
    347     int                items;
    348     int                found;
    349     objdumpLine_t      lineInfo;
    350     FILE*              objdumpFile;
    351     uint32_t           offset;
    352     bool               processSymbol = false;
    353     uint32_t           startAddress = 0;
    354     char               symbol[ MAX_LINE_LENGTH ];
    355     char               terminator1;
    356     char               terminatorOne;
    357     char               terminator2;
    358     objdumpLines_t     theInstructions;
    359     char               instruction[ MAX_LINE_LENGTH ];
    360     char               ID[ MAX_LINE_LENGTH ];
    361     std::string        call = "";
    362     std::string        jumpTableID = "";
     327    ExecutableInfo* const    executableInformation,
     328    rld::process::tempfile&  objdumpFile,
     329    rld::process::tempfile&  err
     330  )
     331  {
     332    std::string     currentSymbol = "";
     333    uint32_t        endAddress;
     334    uint32_t        instructionOffset;
     335    int             items;
     336    int             found;
     337    objdumpLine_t   lineInfo;
     338    uint32_t        offset;
     339    bool            processSymbol = false;
     340    uint32_t        startAddress = 0;
     341    char            symbol[ MAX_LINE_LENGTH ];
     342    char            terminator1;
     343    char            terminatorOne;
     344    char            terminator2;
     345    objdumpLines_t  theInstructions;
     346    char            instruction[ MAX_LINE_LENGTH ];
     347    char            ID[ MAX_LINE_LENGTH ];
     348    std::string     call = "";
     349    std::string     jumpTableID = "";
     350    std::string     line = "";
    363351
    364352    // Obtain the objdump file.
    365     if (!executableInformation->hasDynamicLibrary())
    366       objdumpFile = getFile( executableInformation->getFileName() );
     353    if ( !executableInformation->hasDynamicLibrary() )
     354      getFile( executableInformation->getFileName(), objdumpFile, err );
    367355    else
    368       objdumpFile = getFile( executableInformation->getLibraryName() );
    369 
    370     // Process all lines from the objdump file.
    371     while ( 1 ) {
     356      getFile( executableInformation->getLibraryName(), objdumpFile, err );
     357
     358    while ( true ) {
    372359
    373360      // Get the line.
    374       cStatus = fgets( inputBuffer, MAX_LINE_LENGTH, objdumpFile );
    375       if (cStatus == NULL) {
     361      objdumpFile.read_line( line );
     362      if ( line.empty() ) {
    376363
    377364        // If we are currently processing a symbol, finalize it.
     
    394381          );
    395382        }
     383        objdumpFile.close();
    396384        break;
    397385      }
    398386
    399       inputBuffer[ strlen(inputBuffer) - 1] = '\0';
    400 
    401       lineInfo.line          = inputBuffer;
     387      lineInfo.line          = line;
    402388      lineInfo.address       = 0xffffffff;
    403389      lineInfo.isInstruction = false;
     
    409395      // offset and symbol (i.e. offset <symbolname>:).
    410396      items = sscanf(
    411         inputBuffer,
     397        line.c_str(),
    412398        "%x <%[^>]>%c",
    413399        &offset, symbol, &terminator1
     
    416402      // See if it is a jump table.
    417403      found = sscanf(
    418         inputBuffer,
     404        line.c_str(),
    419405        "%x%c\t%*[^\t]%c%s %*x %*[^+]%s",
    420406        &instructionOffset, &terminatorOne, &terminator2, instruction, ID
     
    478464        // See if it is the dump of an instruction.
    479465        items = sscanf(
    480           inputBuffer,
     466          line.c_str(),
    481467          "%x%c\t%*[^\t]%c",
    482468          &instructionOffset, &terminator1, &terminator2
     
    490476           executableInformation->getLoadAddress() + instructionOffset;
    491477          lineInfo.isInstruction = true;
    492           lineInfo.isNop         = isNop( inputBuffer, lineInfo.nopSize );
    493           lineInfo.isBranch      = isBranchLine( inputBuffer );
     478          lineInfo.isNop         = isNop( line.c_str(), lineInfo.nopSize );
     479          lineInfo.isBranch      = isBranchLine( line.c_str() );
    494480        }
    495481
  • tester/covoar/ObjdumpProcessor.h

    r4cee5c3 r6a4859e  
    1313#include "ExecutableInfo.h"
    1414#include "TargetBase.h"
     15
     16#include "rld-process.h"
    1517
    1618namespace Coverage {
     
    7577    typedef std::list<objdumpLine_t> objdumpLines_t;
    7678
    77    
     79
    7880    /*!
    7981     *  This object defines a list of instruction addresses
    8082     *  that will be extracted from the objdump file.
    81      */ 
     83     */
    8284    typedef std::list<uint32_t> objdumpFile_t;
    8385
     
    9799
    98100    /*!
    99      *  This method returns a file pointer to the objdump file
    100      *  for the given file name. 
     101     *  This method fills a tempfile with the .text section of objdump
     102     *  for the given file name.
    101103     */
    102     FILE* getFile( std::string fileName );
     104    void getFile( std::string fileName,
     105                  rld::process::tempfile& dmp,
     106                  rld::process::tempfile& err );
    103107
    104108    /*!
    105      *  This method fills the objdumpList list with all the 
     109     *  This method fills the objdumpList list with all the
    106110     *  instruction addresses in the object dump file.
    107111     */
    108112    void loadAddressTable (
    109       ExecutableInfo* const executableInformation
     113      ExecutableInfo* const executableInformation,
     114      rld::process::tempfile& dmp,
     115      rld::process::tempfile& err
    110116    );
    111117
     
    115121     */
    116122    void load(
    117       ExecutableInfo* const executableInformation
     123      ExecutableInfo* const executableInformation,
     124      rld::process::tempfile& dmp,
     125      rld::process::tempfile& err
    118126    );
    119127
    120128    /*!
    121      *  This method returns the next address in othe objdumpList.
     129     *  This method returns the next address in the objdumpList.
    122130     */
    123131    uint32_t getAddressAfter( uint32_t address );
    124132
    125133    /*!
    126      *  This method returns true if the instrucation is
     134     *  This method returns true if the instruction is
    127135     *  an instruction that results in a code branch, otherwise
    128136     *  it returns false.
     
    131139
    132140    /*!
    133      *  This method returns true if the instruction from 
     141     *  This method returns true if the instruction from
    134142     *  the given line in the objdmp file is a branch instruction,
    135143     *  otherwise it returns false.
  • tester/covoar/TraceConverter.cc

    r4cee5c3 r6a4859e  
    1111#include <string.h>
    1212#include <getopt.h>
     13#include <signal.h>
     14#include <unistd.h>
    1315
    1416#include "qemu-log.h"
    15 
    1617#include "TraceReaderLogQEMU.h"
    1718#include "TraceWriterQEMU.h"
     
    2021#include "app_common.h"
    2122#include "TargetFactory.h"
     23
     24#include "rld.h"
     25#include "rld-process.h"
    2226
    2327char*       progname;
     
    3135  );
    3236  exit(1);
     37}
     38
     39static void
     40fatal_signal( int signum )
     41{
     42  signal( signum, SIG_DFL );
     43
     44  rld::process::temporaries_clean_up();
     45
     46  /*
     47   * Get the same signal again, this time not handled, so its normal effect
     48   * occurs.
     49   */
     50  kill( getpid(), signum );
     51}
     52
     53static void
     54setup_signals( void )
     55{
     56  if ( signal (SIGINT, SIG_IGN) != SIG_IGN )
     57    signal( SIGINT, fatal_signal );
     58#ifdef SIGHUP
     59  if ( signal( SIGHUP, SIG_IGN ) != SIG_IGN )
     60    signal( SIGHUP, fatal_signal );
     61#endif
     62  if ( signal( SIGTERM, SIG_IGN ) != SIG_IGN )
     63    signal( SIGTERM, fatal_signal );
     64#ifdef SIGPIPE
     65  if ( signal( SIGPIPE, SIG_IGN ) != SIG_IGN )
     66    signal( SIGPIPE, fatal_signal );
     67#endif
     68#ifdef SIGCHLD
     69  signal( SIGCHLD, SIG_DFL );
     70#endif
    3371}
    3472
     
    4684  const char                  *logname = "/tmp/qemu.log";
    4785  Coverage::ExecutableInfo*    executableInfo;
    48    
    49   //
    50   // Process command line options.
    51   //
     86  rld::process::tempfile       objdumpFile( ".dmp" );
     87  rld::process::tempfile       err( ".err" );
     88
     89  setup_signals();
     90
     91   //
     92   // Process command line options.
     93   //
    5294  progname = argv[0];
    5395
     
    89131
    90132  objdumpProcessor = new Coverage::ObjdumpProcessor();
    91  
     133
    92134  // If a dynamic library was specified, determine the load address.
    93135  if (dynamicLibrary)
     
    95137      objdumpProcessor->determineLoadAddress( executableInfo )
    96138    );
    97 
    98   objdumpProcessor->loadAddressTable( executableInfo );
    99 
     139  objdumpProcessor->loadAddressTable( executableInfo, objdumpFile, err );
    100140  log.processFile( logname );
    101 
    102141  trace.writeFile( tracefile, &log );
    103 
    104142}
  • tester/covoar/TraceReaderLogQEMU.cc

    r4cee5c3 r6a4859e  
    3636 */
    3737
    38 #include "covoar-config.h"
    39 
    4038#include <stdio.h>
    4139#include <stdlib.h>
     
    4442
    4543#include "qemu-log.h"
    46 
    4744#include "app_common.h"
    4845#include "TraceReaderBase.h"
    4946#include "TraceReaderLogQEMU.h"
    5047#include "TraceList.h"
    51 
    52 /* XXX really not always right */
    53 typedef uint32_t target_ulong;
    54 
    5548#include "qemu-traces.h"
     49
     50#include "rld-process.h"
    5651
    5752#if HAVE_STAT64
  • tester/covoar/TraceReaderLogQEMU.h

    r4cee5c3 r6a4859e  
    99
    1010#include "TraceReaderBase.h"
     11
     12#include "rld-process.h"
    1113
    1214namespace Trace {
  • tester/covoar/TraceWriterQEMU.cc

    r4cee5c3 r6a4859e  
    3535 */
    3636
    37 #include "covoar-config.h"
    38 
    3937#include <stdio.h>
    4038#include <stdlib.h>
     
    4543#include "ExecutableInfo.h"
    4644#include "CoverageMap.h"
     45#include "qemu-traces.h"
    4746
    48 /* XXX really not always right */
    49 typedef uint32_t target_ulong;
    50 
    51 #include "qemu-traces.h"
     47#include "rld-process.h"
    5248
    5349#if HAVE_STAT64
     
    168164      status = fwrite( &entry, sizeof(entry), 1, traceFile );
    169165      if (status != 1) {
    170         fprintf( stderr, "Unable to emtry to %s\n", file );
     166        fprintf( stderr, "Unable to write entry to %s\n", file );
    171167        return false;
    172168      }
  • tester/covoar/TraceWriterQEMU.h

    r4cee5c3 r6a4859e  
    1111#include "TraceReaderBase.h"
    1212#include "TraceWriterBase.h"
     13
     14#include "rld-process.h"
    1315
    1416namespace Trace {
  • tester/covoar/covoar.cc

    r4cee5c3 r6a4859e  
    2323#include "TargetFactory.h"
    2424#include "GcovData.h"
     25
     26#include "rld-process.h"
    2527
    2628/*
     
    4648const char*                          format = NULL;
    4749FILE*                                gcnosFile = NULL;
    48 Gcov::GcovData*                      gcovFile;
     50Gcov::GcovData*          gcovFile;
    4951
    5052/*
     
    147149}
    148150
     151static void
     152fatal_signal( int signum )
     153{
     154  signal( signum, SIG_DFL );
     155
     156  rld::process::temporaries_clean_up();
     157
     158  /*
     159   * Get the same signal again, this time not handled, so its normal effect
     160   * occurs.
     161   */
     162  kill( getpid(), signum );
     163}
     164
     165static void
     166setup_signals( void )
     167{
     168  if ( signal( SIGINT, SIG_IGN ) != SIG_IGN )
     169    signal( SIGINT, fatal_signal );
     170#ifdef SIGHUP
     171  if ( signal( SIGHUP, SIG_IGN ) != SIG_IGN )
     172    signal( SIGHUP, fatal_signal );
     173#endif
     174  if ( signal( SIGTERM, SIG_IGN ) != SIG_IGN )
     175    signal( SIGTERM, fatal_signal );
     176#ifdef SIGPIPE
     177  if ( signal( SIGPIPE, SIG_IGN ) != SIG_IGN )
     178    signal( SIGPIPE, fatal_signal );
     179#endif
     180#ifdef SIGCHLD
     181  signal( SIGCHLD, SIG_DFL );
     182#endif
     183}
     184
    149185int main(
    150186  int    argc,
     
    159195  int                                            opt;
    160196  const char*                                    singleExecutable = NULL;
     197  rld::process::tempfile                         objdumpFile( ".dmp" );
     198  rld::process::tempfile                         err( ".err" );
     199  bool                                           debug = false;
     200
     201  setup_signals();
    161202
    162203  CoverageConfiguration = new Configuration::FileReader(Options);
     
    167208  progname = argv[0];
    168209
    169   while ((opt = getopt(argc, argv, "C:1:L:e:c:g:E:f:s:T:O:p:v")) != -1) {
     210  while ((opt = getopt(argc, argv, "C:1:L:e:c:g:E:f:s:T:O:p:v:d")) != -1) {
    170211    switch (opt) {
    171212      case 'C': CoverageConfiguration->processFile( optarg ); break;
     
    182223      case 'v': Verbose               = true;   break;
    183224      case 'p': projectName           = optarg; break;
     225      case 'd': debug                 = true;   break;
    184226      default: /* '?' */
    185227        usage();
     
    395437
    396438    // Load the objdump for the symbols in this executable.
    397     objdumpProcessor->load( *eitr );
     439    objdumpProcessor->load( *eitr, objdumpFile, err );
    398440  }
    399441
     
    504546  }
    505547
     548  //Leave tempfiles around if debug flag (-d) is enabled.
     549  if ( debug ) {
     550        objdumpFile.override( "objdump_file" );
     551        objdumpFile.keep();
     552        err.override( "objdump_exec_log" );
     553        err.keep();
     554  }
    506555  return 0;
    507556}
Note: See TracChangeset for help on using the changeset viewer.