mirror of
https://git.rtems.org/rtems-tools/
synced 2025-06-12 15:31:26 +08:00
GcovData: Convert to C++
Change C-style code to C++
This commit is contained in:
parent
a08a5644c4
commit
c3762cd29c
@ -1,9 +1,3 @@
|
|||||||
/*
|
|
||||||
* TODO: use strings instead of cstrings for reliability and saving memory
|
|
||||||
* TODO: use global buffers
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*! @file GcovData.cc
|
/*! @file GcovData.cc
|
||||||
* @brief GcovData Implementation
|
* @brief GcovData Implementation
|
||||||
*
|
*
|
||||||
@ -35,62 +29,64 @@ namespace Gcov {
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GcovData::readGcnoFile( const char* const fileName )
|
bool GcovData::readGcnoFile( const std::string& fileName )
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
FILE* gcovFile;
|
std::ifstream gcovFile;
|
||||||
char* tempString;
|
std::string tempString;
|
||||||
char* tempString2;
|
std::string tempString2;
|
||||||
char* tempString3;
|
std::string tempString3;
|
||||||
|
size_t index;
|
||||||
|
|
||||||
if ( strlen(fileName) >= FILE_NAME_LENGTH ){
|
if ( fileName.length() >= FILE_NAME_LENGTH ) {
|
||||||
fprintf(
|
std::cerr << "ERROR: File name is too long to be correctly stored: "
|
||||||
stderr,
|
<< fileName.length() << std::endl;
|
||||||
"ERROR: File name is too long to be correctly stored: %u\n",
|
|
||||||
(unsigned int) strlen(fileName)
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
strcpy( gcnoFileName, fileName );
|
|
||||||
strcpy( gcdaFileName, fileName );
|
|
||||||
strcpy( textFileName, fileName );
|
|
||||||
strcpy( cFileName, fileName );
|
|
||||||
tempString = strstr( gcdaFileName,".gcno" );
|
|
||||||
tempString2 = strstr( textFileName,".gcno" );
|
|
||||||
tempString3 = strstr( cFileName,".gcno" );
|
|
||||||
|
|
||||||
if ( (tempString == NULL) && (tempString2 == NULL) ){
|
gcnoFileName = fileName;
|
||||||
fprintf(stderr, "ERROR: incorrect name of *.gcno file\n");
|
gcdaFileName = fileName;
|
||||||
}
|
textFileName = fileName;
|
||||||
else
|
cFileName = fileName;
|
||||||
{
|
tempString = gcdaFileName;
|
||||||
strcpy( tempString, ".gcda"); // construct gcda file name
|
tempString2 = textFileName;
|
||||||
strcpy( tempString2, ".txt"); // construct report file name
|
tempString3 = cFileName;
|
||||||
strcpy( tempString3, ".c"); // construct source file name
|
|
||||||
|
index = tempString.find( ".gcno" );
|
||||||
|
if ( index == std::string::npos ) {
|
||||||
|
std::cerr << "ERROR: incorrect name of *.gcno file" << std::endl;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// construct gcda file name
|
||||||
|
tempString = tempString.replace( index, strlen( ".gcno" ), ".gcda" );
|
||||||
|
|
||||||
|
// construct report file name
|
||||||
|
tempString2 = tempString2.replace( index, strlen( ".gcno" ), ".txt" );
|
||||||
|
|
||||||
|
// construct source file name
|
||||||
|
tempString3 = tempString3.replace( index, strlen( ".gcno" ), ".c" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug message
|
// Debug message
|
||||||
// fprintf( stderr, "Readning file: %s\n", gcnoFileName);
|
// std::cerr << "Reading file: " << gcnoFileName << std::endl;
|
||||||
|
|
||||||
// Open the notes file.
|
// Open the notes file.
|
||||||
gcovFile = fopen( gcnoFileName, "r" );
|
gcovFile.open( gcnoFileName );
|
||||||
if ( !gcovFile ) {
|
if ( !gcovFile ) {
|
||||||
fprintf( stderr, "Unable to open %s\n", gcnoFileName );
|
std::cerr << "Unable to open " << gcnoFileName << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read and validate the gcnoPreamble (magic, version, timestamp) from the file
|
// Read and validate the gcnoPreamble (magic, version, timestamp) from the file
|
||||||
status = readFilePreamble( &gcnoPreamble, gcovFile, GCNO_MAGIC );
|
status = readFilePreamble( &gcnoPreamble, gcovFile, GCNO_MAGIC );
|
||||||
if ( status <= 0 ){
|
if ( status <= 0 ){
|
||||||
fprintf( stderr, "Unable to read %s\n", gcnoFileName );
|
std::cerr << "Unable to read " << gcnoFileName << std::endl;
|
||||||
fclose( gcovFile );
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read all remaining frames from file
|
//Read all remaining frames from file
|
||||||
while( readFrame(gcovFile) ){}
|
while( readFrame(gcovFile) ){}
|
||||||
|
|
||||||
fclose( gcovFile );
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +95,7 @@ namespace Gcov {
|
|||||||
{
|
{
|
||||||
gcov_preamble preamble;
|
gcov_preamble preamble;
|
||||||
gcov_frame_header header;
|
gcov_frame_header header;
|
||||||
FILE* gcdaFile;
|
std::ofstream gcdaFile;
|
||||||
functions_iterator_t currentFunction;
|
functions_iterator_t currentFunction;
|
||||||
arcs_iterator_t currentArc;
|
arcs_iterator_t currentArc;
|
||||||
uint32_t buffer;
|
uint32_t buffer;
|
||||||
@ -110,10 +106,10 @@ namespace Gcov {
|
|||||||
uint64_t llBuffer[4096]; // TODO: Use common buffer
|
uint64_t llBuffer[4096]; // TODO: Use common buffer
|
||||||
gcov_statistics objectStats;
|
gcov_statistics objectStats;
|
||||||
gcov_statistics programStats;
|
gcov_statistics programStats;
|
||||||
size_t status;
|
long int bytes_before;
|
||||||
|
|
||||||
// Debug message
|
// Debug message
|
||||||
// fprintf( stderr, "Writing file: %s\n", gcdaFileName);
|
//std::cerr << "Writing file: " << gcdaFileName << std::endl;
|
||||||
|
|
||||||
// Lets clear counters sumators
|
// Lets clear counters sumators
|
||||||
countersSum = 0;
|
countersSum = 0;
|
||||||
@ -121,9 +117,9 @@ namespace Gcov {
|
|||||||
countersFoundSum = 0;
|
countersFoundSum = 0;
|
||||||
|
|
||||||
// Open the data file.
|
// Open the data file.
|
||||||
gcdaFile = fopen( gcdaFileName, "w" );
|
gcdaFile.open( gcdaFileName );
|
||||||
if ( !gcdaFile ) {
|
if ( !gcdaFile ) {
|
||||||
fprintf( stderr, "Unable to create %s\n", gcdaFileName );
|
std::cerr << "Unable to create " << gcdaFileName << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,9 +129,11 @@ namespace Gcov {
|
|||||||
preamble.timestamp = gcnoPreamble.timestamp;
|
preamble.timestamp = gcnoPreamble.timestamp;
|
||||||
|
|
||||||
//Write preamble
|
//Write preamble
|
||||||
status = fwrite (&preamble , sizeof( preamble ), 1 , gcdaFile );
|
gcdaFile.write( (char *) &preamble , 4 * sizeof( preamble ) );
|
||||||
if ( status != 1 )
|
if ( gcdaFile.fail() ) {
|
||||||
fprintf( stderr, "Error while writing gcda preamble to a file %s\n", gcdaFileName );
|
std::cerr << "Error while writing gcda preamble to a file "
|
||||||
|
<< gcdaFileName << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
//Write function info and counter counts
|
//Write function info and counter counts
|
||||||
for (
|
for (
|
||||||
@ -147,21 +145,27 @@ namespace Gcov {
|
|||||||
//Write function announcement frame header (length always equals 2)
|
//Write function announcement frame header (length always equals 2)
|
||||||
header.tag = GCOV_TAG_FUNCTION;
|
header.tag = GCOV_TAG_FUNCTION;
|
||||||
header.length = 2;
|
header.length = 2;
|
||||||
status = fwrite (&header, sizeof(header), 1, gcdaFile );
|
gcdaFile.write( (char *) &header, sizeof( header ) );
|
||||||
if ( status != 1 )
|
if ( gcdaFile.fail() ) {
|
||||||
fprintf( stderr, "Error while writing function announcement to a file %s\n", gcdaFileName );
|
std::cerr << "Error while writing function announcement to a file "
|
||||||
|
<< gcdaFileName << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
//Write function id
|
//Write function id
|
||||||
buffer = (*currentFunction).getId();
|
buffer = (*currentFunction).getId();
|
||||||
status = fwrite (&buffer, sizeof( buffer ), 1, gcdaFile );
|
gcdaFile.write( (char *) &buffer, sizeof( buffer ) );
|
||||||
if ( status != 1 )
|
if ( gcdaFile.fail() ) {
|
||||||
fprintf( stderr, "Error while writing function id to a file %s\n", gcdaFileName );
|
std::cerr << "Error while writing function id to a file "
|
||||||
|
<< gcdaFileName << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
//Write function checksum
|
//Write function checksum
|
||||||
buffer = (*currentFunction).getChecksum();
|
buffer = (*currentFunction).getChecksum();
|
||||||
status = fwrite (&buffer, sizeof( buffer ), 1, gcdaFile );
|
gcdaFile.write( (char *) &buffer, sizeof( buffer ) );
|
||||||
if ( status != 1 )
|
if ( gcdaFile.fail() ) {
|
||||||
fprintf( stderr, "Error while writing function checksum to a file %s\n", gcdaFileName );
|
std::cerr << "Error while writing function checksum to a file "
|
||||||
|
<< gcdaFileName << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Determine how many counters there are
|
// Determine how many counters there are
|
||||||
// and store their counts in buffer
|
// and store their counts in buffer
|
||||||
@ -172,13 +176,19 @@ namespace Gcov {
|
|||||||
//Write info about counters
|
//Write info about counters
|
||||||
header.tag = GCOV_TAG_COUNTER;
|
header.tag = GCOV_TAG_COUNTER;
|
||||||
header.length = countersFound * 2;
|
header.length = countersFound * 2;
|
||||||
status = fwrite (&header, sizeof( header ), 1, gcdaFile );
|
gcdaFile.write( (char *) &header, sizeof( header ) );
|
||||||
if ( status != 1 )
|
if ( gcdaFile.fail() ) {
|
||||||
fprintf( stderr, "Error while writing counter header to a file %s\n", gcdaFileName );
|
std::cerr << "Error while writing counter header to a file "
|
||||||
|
<< gcdaFileName << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
status = fwrite (llBuffer, sizeof( uint64_t ), countersFound , gcdaFile );
|
bytes_before = gcdaFile.tellp();
|
||||||
if ( status != countersFound )
|
|
||||||
fprintf( stderr, "Error while writing counter data to a file %s\n", gcdaFileName );
|
gcdaFile.write( (char *) llBuffer, sizeof( uint64_t ) * countersFound );
|
||||||
|
if ( gcdaFile.tellp() - bytes_before != countersFound ) {
|
||||||
|
std::cerr << "Error while writing counter data to a file "
|
||||||
|
<< gcdaFileName << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare frame with object file statistics
|
// Prepare frame with object file statistics
|
||||||
@ -192,12 +202,17 @@ namespace Gcov {
|
|||||||
objectStats.sumMax = countersMax; // we have no clue
|
objectStats.sumMax = countersMax; // we have no clue
|
||||||
|
|
||||||
// Write data
|
// Write data
|
||||||
status = fwrite (&header, sizeof( header ), 1, gcdaFile );
|
gcdaFile.write( (char *) &header, sizeof( header ) );
|
||||||
if ( status != 1 )
|
if ( gcdaFile.fail() ) {
|
||||||
fprintf( stderr, "Error while writing stats header to a file %s\n", gcdaFileName );
|
std::cerr << "Error while writing stats header to a file "
|
||||||
status = fwrite (&objectStats, sizeof( objectStats ), 1, gcdaFile );
|
<< gcdaFileName << std::endl;
|
||||||
if ( status != 1 )
|
}
|
||||||
fprintf( stderr, "Error while writing object stats to a file %s\n", gcdaFileName );
|
|
||||||
|
gcdaFile.write( (char *) &objectStats, sizeof( objectStats ) );
|
||||||
|
if ( gcdaFile.fail() ) {
|
||||||
|
std::cerr << "Error while writing object stats to a file "
|
||||||
|
<< gcdaFileName << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Prepare frame with program statistics
|
// Prepare frame with program statistics
|
||||||
@ -211,25 +226,26 @@ namespace Gcov {
|
|||||||
programStats.sumMax = countersMax; // we have no clue
|
programStats.sumMax = countersMax; // we have no clue
|
||||||
|
|
||||||
// Write data
|
// Write data
|
||||||
status = fwrite (&header, sizeof( header ), 1, gcdaFile );
|
gcdaFile.write( (char *) &header, sizeof( header ) );
|
||||||
if ( status != 1 )
|
if ( gcdaFile.fail() ) {
|
||||||
fprintf( stderr, "Error while writing stats header to a file %s\n", gcdaFileName );
|
std::cerr << "Error while writing stats header to a file "
|
||||||
status = fwrite (&programStats, sizeof( programStats ), 1, gcdaFile );
|
<< gcdaFileName << std::endl;
|
||||||
if ( status != 1 )
|
}
|
||||||
fprintf( stderr, "Error while writing program stats to a file %s\n", gcdaFileName );
|
|
||||||
|
|
||||||
fclose( gcdaFile );
|
gcdaFile.write( (char *) &programStats, sizeof( programStats ) );
|
||||||
|
if ( gcdaFile.fail() ) {
|
||||||
|
std::cerr << "Error while writing program stats to a file "
|
||||||
|
<< gcdaFileName << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GcovData::readFrame(
|
bool GcovData::readFrame( std::ifstream& gcovFile )
|
||||||
FILE* gcovFile
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
gcov_frame_header header;
|
gcov_frame_header header;
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
uint32_t intBuffer[4096];
|
char intBuffer[16384];
|
||||||
uint32_t tempBlockId;
|
uint32_t tempBlockId;
|
||||||
blocks_iterator_t tempBlockIterator;
|
blocks_iterator_t tempBlockIterator;
|
||||||
int status;
|
int status;
|
||||||
@ -251,7 +267,8 @@ namespace Gcov {
|
|||||||
GcovFunctionData newFunction;
|
GcovFunctionData newFunction;
|
||||||
|
|
||||||
if ( !readFunctionFrame(header, gcovFile, &newFunction) ){
|
if ( !readFunctionFrame(header, gcovFile, &newFunction) ){
|
||||||
fprintf( stderr, "Error while reading FUNCTION from gcov file...\n" );
|
std::cerr << "Error while reading FUNCTION from gcov file..."
|
||||||
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,14 +279,13 @@ namespace Gcov {
|
|||||||
|
|
||||||
case GCOV_TAG_BLOCKS:
|
case GCOV_TAG_BLOCKS:
|
||||||
|
|
||||||
status = fread( &intBuffer, 4, header.length, gcovFile );
|
gcovFile.read( intBuffer, header.length );
|
||||||
if ( status != (int) header.length){
|
if ( gcovFile.gcount() != (int) header.length ) {
|
||||||
fprintf(
|
std::cerr << "Error while reading BLOCKS from gcov file..."
|
||||||
stderr, "Error while reading BLOCKS from gcov file...\n"
|
<< std::endl
|
||||||
"Header lenght is %u instead of %u\n",
|
<< "Header length is " << header.length
|
||||||
header.length,
|
<< " instead of " << gcovFile.gcount()
|
||||||
status
|
<< std::endl;
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,8 +296,8 @@ namespace Gcov {
|
|||||||
|
|
||||||
case GCOV_TAG_ARCS:
|
case GCOV_TAG_ARCS:
|
||||||
|
|
||||||
status = fread( &intBuffer, 4, header.length, gcovFile );
|
gcovFile.read( intBuffer, header.length );
|
||||||
if (status != (int) header.length){
|
if ( gcovFile.gcount() != (int) header.length ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,12 +308,10 @@ namespace Gcov {
|
|||||||
|
|
||||||
case GCOV_TAG_LINES:
|
case GCOV_TAG_LINES:
|
||||||
|
|
||||||
status = fread( &intBuffer, 4, 2, gcovFile );
|
gcovFile.read( intBuffer, 2 );
|
||||||
if (status != 2 || intBuffer[1] != 0){
|
if ( gcovFile.gcount() != 2 || intBuffer[1] != 0 ) {
|
||||||
fprintf(
|
std::cerr << "Error while reading block id for LINES from gcov "
|
||||||
stderr,
|
<< "file..." << std::endl;
|
||||||
"Error while reading block id for LINES from gcov file..."
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
tempBlockId = intBuffer[0];
|
tempBlockId = intBuffer[0];
|
||||||
@ -309,9 +323,10 @@ namespace Gcov {
|
|||||||
header.length -= readString(buffer, gcovFile);
|
header.length -= readString(buffer, gcovFile);
|
||||||
functions.back().setBlockFileName( tempBlockIterator, buffer );
|
functions.back().setBlockFileName( tempBlockIterator, buffer );
|
||||||
|
|
||||||
status = fread( &intBuffer, 4, header.length, gcovFile );
|
gcovFile.read( intBuffer, header.length );
|
||||||
if (status != (int) header.length){
|
if ( gcovFile.gcount() != (int) header.length ) {
|
||||||
fprintf( stderr, "Error while reading LINES from gcov file..." );
|
std::cerr << "Error while reading LINES from gcov file..."
|
||||||
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,30 +338,30 @@ namespace Gcov {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
fprintf( stderr, "\n\nERROR - encountered unknown *.gcno tag : 0x%x\n", header.tag );
|
std::cerr << std::endl << std::endl
|
||||||
|
<< "ERROR - encountered unknown *.gcno tag : 0x"
|
||||||
|
<< std::hex << header.tag << std::dec << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GcovData::readString(
|
int GcovData::readString( char* buffer, std::ifstream& gcovFile )
|
||||||
char* buffer, //TODO: use global buffer here
|
|
||||||
FILE* gcovFile
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
int status;
|
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
status = fread( &length, sizeof(int), 1, gcovFile );
|
gcovFile.read( (char *) &length, sizeof( int ) );
|
||||||
if (status != 1){
|
if ( gcovFile.gcount() != sizeof( int ) ) {
|
||||||
fprintf( stderr, "ERROR: Unable to read string length from gcov file\n" );
|
std::cerr << "ERROR: Unable to read string length from gcov file"
|
||||||
|
<< std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = fread( buffer, length * 4 , 1, gcovFile );
|
gcovFile.read( buffer, length * 4 );
|
||||||
if (status != 1){
|
if ( gcovFile.gcount() != length * 4 ) {
|
||||||
fprintf( stderr, "ERROR: Unable to read string from gcov file\n" );
|
std::cerr << "ERROR: Unable to read string from gcov file"
|
||||||
|
<< std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,16 +372,16 @@ namespace Gcov {
|
|||||||
|
|
||||||
int GcovData::readFrameHeader(
|
int GcovData::readFrameHeader(
|
||||||
gcov_frame_header* header,
|
gcov_frame_header* header,
|
||||||
FILE* gcovFile
|
std::ifstream& gcovFile
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int status;
|
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
length = sizeof(gcov_frame_header);
|
length = sizeof(gcov_frame_header);
|
||||||
status = fread( header, length, 1, gcovFile );
|
gcovFile.read( (char *) header, length );
|
||||||
if (status != 1){
|
if ( gcovFile.gcount() != length ) {
|
||||||
//fprintf( stderr, "ERROR: Unable to read frame header from gcov file\n" );
|
std::cerr << "ERROR: Unable to read frame header from gcov file"
|
||||||
|
<< std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,22 +390,23 @@ namespace Gcov {
|
|||||||
|
|
||||||
int GcovData::readFilePreamble(
|
int GcovData::readFilePreamble(
|
||||||
gcov_preamble* preamble,
|
gcov_preamble* preamble,
|
||||||
FILE* gcovFile,
|
std::ifstream& gcovFile,
|
||||||
uint32_t desiredMagic
|
uint32_t desiredMagic
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
int status;
|
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
length = sizeof( gcov_preamble );
|
length = sizeof( gcov_preamble );
|
||||||
status = fread( preamble, sizeof( gcov_preamble), 1, gcovFile );
|
gcovFile.read( (char *) &preamble, 4 * sizeof( gcov_preamble ) );
|
||||||
if (status <= 0) {
|
if ( gcovFile.gcount() != 4 * sizeof( gcov_preamble ) ) {
|
||||||
fprintf( stderr, "Error while reading file preamble\n" );
|
std::cerr << "Error while reading file preamble" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( preamble->magic != GCNO_MAGIC ) {
|
if ( preamble->magic != GCNO_MAGIC ) {
|
||||||
fprintf( stderr, "File is not a valid *.gcno output (magic: 0x%4x)\n", preamble->magic );
|
std::cerr << "File is not a valid *.gcno output (magic: 0x"
|
||||||
|
<< std::hex << std::setw( 4 ) << preamble->magic
|
||||||
|
<< ")" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,17 +415,16 @@ namespace Gcov {
|
|||||||
|
|
||||||
bool GcovData::readFunctionFrame(
|
bool GcovData::readFunctionFrame(
|
||||||
gcov_frame_header header,
|
gcov_frame_header header,
|
||||||
FILE* gcovFile,
|
std::ifstream& gcovFile,
|
||||||
GcovFunctionData* function
|
GcovFunctionData* function
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
char buffer[512]; //TODO: use common buffers
|
char buffer[512]; //TODO: use common buffers
|
||||||
uint32_t intBuffer[4096];
|
char intBuffer[16384];
|
||||||
int status;
|
|
||||||
|
|
||||||
status = fread( &intBuffer, 8, 1, gcovFile );
|
gcovFile.read( (char *) &intBuffer, 8 );
|
||||||
if (status != 1){
|
if ( gcovFile.gcount() != 8 ) {
|
||||||
fprintf( stderr, "ERROR: Unable to read Function ID & checksum\n" );
|
std::cerr << "ERROR: Unable to read Function ID & checksum" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
header.length -= 2;
|
header.length -= 2;
|
||||||
@ -420,9 +435,10 @@ namespace Gcov {
|
|||||||
function->setFunctionName( buffer, symbolsToAnalyze_m );
|
function->setFunctionName( buffer, symbolsToAnalyze_m );
|
||||||
header.length -= readString( buffer, gcovFile );
|
header.length -= readString( buffer, gcovFile );
|
||||||
function->setFileName( buffer );
|
function->setFileName( buffer );
|
||||||
status = fread( &intBuffer, 4, header.length, gcovFile );
|
gcovFile.read( (char*) &intBuffer, 4 * header.length );
|
||||||
if (status <= 0){
|
if (gcovFile.gcount() != 4 * header.length ) {
|
||||||
fprintf( stderr, "ERROR: Unable to read Function starting line number\n" );
|
std::cerr << "ERROR: Unable to read Function starting line number"
|
||||||
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
function->setFirstLineNumber( intBuffer[0] );
|
function->setFirstLineNumber( intBuffer[0] );
|
||||||
@ -434,15 +450,15 @@ namespace Gcov {
|
|||||||
{
|
{
|
||||||
functions_iterator_t currentFunction;
|
functions_iterator_t currentFunction;
|
||||||
uint32_t i = 1; //iterator
|
uint32_t i = 1; //iterator
|
||||||
FILE* textFile;
|
std::ofstream textFile;
|
||||||
|
|
||||||
// Debug message
|
// Debug message
|
||||||
// fprintf( stderr, "Writing file: %s\n", textFileName);
|
// std::cerr << "Writing file: " << textFileName << std::endl;
|
||||||
|
|
||||||
// Open the data file.
|
// Open the data file.
|
||||||
textFile = fopen( textFileName, "w" );
|
textFile.open( textFileName );
|
||||||
if ( !textFile ) {
|
if ( !textFile.is_open() ) {
|
||||||
fprintf( stderr, "Unable to create %s\n", textFileName );
|
std::cerr << "Unable to create " << textFileName << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -459,25 +475,20 @@ namespace Gcov {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose ( textFile );
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GcovData::printGcnoFileInfo( FILE * textFile )
|
void GcovData::printGcnoFileInfo( std::ofstream& textFile )
|
||||||
{
|
{
|
||||||
fprintf(
|
textFile << std::endl << "FILE:\t\t\t" << gcnoFileName
|
||||||
textFile,
|
<< std::endl << std::hex
|
||||||
"\nFILE:\t\t\t%s\n"
|
<< "magic:\t\t\t" << gcnoPreamble.magic << std::endl
|
||||||
"magic:\t\t\t%x\n"
|
<< "version:\t\t" << gcnoPreamble.version << std::endl
|
||||||
"version:\t\t%x\n"
|
<< "timestamp:\t\t" << gcnoPreamble.timestamp << std::endl
|
||||||
"timestamp:\t\t%x\n"
|
<< std::dec
|
||||||
"functions found: \t%u\n\n",
|
<< "functions found: \t"
|
||||||
gcnoFileName,
|
<< std::endl << std::endl << gcnoPreamble.timestamp
|
||||||
gcnoPreamble.magic,
|
<< std::endl << std::endl;
|
||||||
gcnoPreamble.version,
|
|
||||||
gcnoPreamble.timestamp,
|
|
||||||
numberOfFunctions
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GcovData::writeGcovFile( )
|
void GcovData::writeGcovFile( )
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <fstream>
|
||||||
#include "GcovFunctionData.h"
|
#include "GcovFunctionData.h"
|
||||||
#include "DesiredSymbols.h"
|
#include "DesiredSymbols.h"
|
||||||
|
|
||||||
@ -86,7 +88,7 @@ class DesiredSymbols;
|
|||||||
*
|
*
|
||||||
* @return Returns TRUE if the method succeeded and FALSE if it failed.
|
* @return Returns TRUE if the method succeeded and FALSE if it failed.
|
||||||
*/
|
*/
|
||||||
bool readGcnoFile( const char* const fileName );
|
bool readGcnoFile( const std::string& fileName );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method writes the *.gcda file. It also produces and stores
|
* This method writes the *.gcda file. It also produces and stores
|
||||||
@ -118,10 +120,10 @@ class DesiredSymbols;
|
|||||||
|
|
||||||
uint32_t numberOfFunctions;
|
uint32_t numberOfFunctions;
|
||||||
gcov_preamble gcnoPreamble;
|
gcov_preamble gcnoPreamble;
|
||||||
char gcnoFileName[FILE_NAME_LENGTH];
|
std::string gcnoFileName;
|
||||||
char gcdaFileName[FILE_NAME_LENGTH];
|
std::string gcdaFileName;
|
||||||
char textFileName[FILE_NAME_LENGTH];
|
std::string textFileName;
|
||||||
char cFileName[FILE_NAME_LENGTH];
|
std::string cFileName;
|
||||||
functions_t functions;
|
functions_t functions;
|
||||||
|
|
||||||
|
|
||||||
@ -132,9 +134,7 @@ class DesiredSymbols;
|
|||||||
*
|
*
|
||||||
* @return true if read was succesfull, false otherwise
|
* @return true if read was succesfull, false otherwise
|
||||||
*/
|
*/
|
||||||
bool readFrame(
|
bool readFrame( std::ifstream& gcovFile );
|
||||||
FILE* gcovFile
|
|
||||||
);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method reads a string from gcov file
|
* This method reads a string from gcov file
|
||||||
@ -144,10 +144,7 @@ class DesiredSymbols;
|
|||||||
*
|
*
|
||||||
* @return Returns length of words read (word = 32bit) or -1 if error ocurred
|
* @return Returns length of words read (word = 32bit) or -1 if error ocurred
|
||||||
*/
|
*/
|
||||||
int readString(
|
int readString( char* buffer, std::ifstream& gcovFile );
|
||||||
char* buffer,
|
|
||||||
FILE* gcovFile
|
|
||||||
);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method reads a frame header from gcov file
|
* This method reads a frame header from gcov file
|
||||||
@ -158,10 +155,7 @@ class DesiredSymbols;
|
|||||||
* @return Returns length of words read (word = 32bit)
|
* @return Returns length of words read (word = 32bit)
|
||||||
* or -1 if error ocurred
|
* or -1 if error ocurred
|
||||||
*/
|
*/
|
||||||
int readFrameHeader(
|
int readFrameHeader( gcov_frame_header* header, std::ifstream& gcovFile );
|
||||||
gcov_frame_header* header,
|
|
||||||
FILE* gcovFile
|
|
||||||
);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method reads a frame header from gcov file
|
* This method reads a frame header from gcov file
|
||||||
@ -175,7 +169,7 @@ class DesiredSymbols;
|
|||||||
*/
|
*/
|
||||||
int readFilePreamble(
|
int readFilePreamble(
|
||||||
gcov_preamble* preamble,
|
gcov_preamble* preamble,
|
||||||
FILE* gcovFile,
|
std::ifstream& gcovFile,
|
||||||
const uint32_t desiredMagic
|
const uint32_t desiredMagic
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -190,7 +184,7 @@ class DesiredSymbols;
|
|||||||
*/
|
*/
|
||||||
bool readFunctionFrame(
|
bool readFunctionFrame(
|
||||||
gcov_frame_header header,
|
gcov_frame_header header,
|
||||||
FILE* gcovFile,
|
std::ifstream& gcovFile,
|
||||||
GcovFunctionData* function
|
GcovFunctionData* function
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -198,7 +192,7 @@ class DesiredSymbols;
|
|||||||
* This method prints info about previously read *.gcno file
|
* This method prints info about previously read *.gcno file
|
||||||
* to a specified report file
|
* to a specified report file
|
||||||
*/
|
*/
|
||||||
void printGcnoFileInfo( FILE * textFile );
|
void printGcnoFileInfo( std::ofstream& textFile );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This member variable contains the symbols to be analyzed
|
* This member variable contains the symbols to be analyzed
|
||||||
|
@ -45,7 +45,7 @@ namespace Gcov {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GcovFunctionData::setFunctionName(
|
bool GcovFunctionData::setFunctionName(
|
||||||
const char* fcnName,
|
const std::string& fcnName,
|
||||||
Coverage::DesiredSymbols& symbolsToAnalyze
|
Coverage::DesiredSymbols& symbolsToAnalyze
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -53,16 +53,13 @@ namespace Gcov {
|
|||||||
|
|
||||||
symbolName = fcnName;
|
symbolName = fcnName;
|
||||||
|
|
||||||
if ( strlen(fcnName) >= FUNCTION_NAME_LENGTH ) {
|
if ( fcnName.length() >= FUNCTION_NAME_LENGTH ) {
|
||||||
fprintf(
|
std::cerr << "ERROR: Function name is too long to be correctly stored: "
|
||||||
stderr,
|
<< fcnName.length() << std::endl;
|
||||||
"ERROR: Function name is too long to be correctly stored: %u\n",
|
|
||||||
(unsigned int) strlen(fcnName)
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy (functionName, fcnName);
|
functionName = fcnName;
|
||||||
|
|
||||||
// Tie function to its coverage map
|
// Tie function to its coverage map
|
||||||
symbolInfo = symbolsToAnalyze.find( symbolName );
|
symbolInfo = symbolsToAnalyze.find( symbolName );
|
||||||
@ -70,34 +67,26 @@ namespace Gcov {
|
|||||||
coverageMap = symbolInfo->unifiedCoverageMap;
|
coverageMap = symbolInfo->unifiedCoverageMap;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if ( coverageMap == NULL) {
|
if ( coverageMap == NULL ) {
|
||||||
fprintf(
|
std::cerr << "ERROR: Could not find coverage map for: " << symbolName
|
||||||
stderr,
|
<< std::endl;
|
||||||
"ERROR: Could not find coverage map for: %s\n",
|
|
||||||
symbolName.c_str()
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(
|
std::cerr << "SUCCESS: Found coverage map for: " << symbolName
|
||||||
stderr,
|
<< std::endl;
|
||||||
"SUCCESS: Hound coverage map for: %s\n",
|
}
|
||||||
symbolName.c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GcovFunctionData::setFileName( const char* fileName ) {
|
bool GcovFunctionData::setFileName( const std::string& fileName ) {
|
||||||
if ( strlen(fileName) >= FILE_NAME_LENGTH ){
|
if ( fileName.length() >= FILE_NAME_LENGTH ) {
|
||||||
fprintf(
|
std::cerr << "ERROR: File name is too long to be correctly stored: "
|
||||||
stderr,
|
<< fileName.length() << std::endl;
|
||||||
"ERROR: File name is too long to be correctly stored: %u\n",
|
|
||||||
(unsigned int) strlen(fileName)
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
strcpy (sourceFileName, fileName);
|
|
||||||
|
sourceFileName = fileName;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,9 +161,9 @@ namespace Gcov {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GcovFunctionData::addBlock(
|
void GcovFunctionData::addBlock(
|
||||||
const uint32_t id,
|
const uint32_t id,
|
||||||
const uint32_t flags,
|
const uint32_t flags,
|
||||||
const char * sourceFileName
|
const std::string& sourceFileName
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
gcov_block_info block;
|
gcov_block_info block;
|
||||||
@ -184,44 +173,35 @@ namespace Gcov {
|
|||||||
block.flags = flags;
|
block.flags = flags;
|
||||||
block.numberOfLines = 0;
|
block.numberOfLines = 0;
|
||||||
block.counter = 0;
|
block.counter = 0;
|
||||||
strcpy (block.sourceFileName, sourceFileName);
|
block.sourceFileName = sourceFileName;
|
||||||
blocks.push_back(block);
|
blocks.push_back(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GcovFunctionData::printFunctionInfo(
|
void GcovFunctionData::printFunctionInfo(
|
||||||
FILE * textFile,
|
std::ofstream& textFile,
|
||||||
uint32_t function_number
|
uint32_t function_number
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
blocks_iterator_t currentBlock;
|
blocks_iterator_t currentBlock;
|
||||||
arcs_iterator_t currentArc;
|
arcs_iterator_t currentArc;
|
||||||
|
|
||||||
fprintf(
|
textFile << std::endl << std::endl
|
||||||
textFile,
|
<< "=========================="
|
||||||
"\n\n=========================="
|
<< "FUNCTION " << std::setw( 3 ) << function_number
|
||||||
"FUNCTION %3d "
|
<< "=========================="
|
||||||
"==========================\n\n",
|
<< std::endl << std::endl
|
||||||
function_number
|
<< "Name: " << functionName << std::endl
|
||||||
);
|
<< "File: " << sourceFileName << std::endl
|
||||||
fprintf(
|
<< "Line: " << firstLineNumber << std::endl
|
||||||
textFile,
|
<< "Id: " << id << std::endl
|
||||||
"Name: %s\n"
|
<< "Checksum: 0x" << std::hex << checksum << std::dec
|
||||||
"File: %s\n"
|
<< std::endl << std::endl;
|
||||||
"Line: %u\n"
|
|
||||||
"Id: %u\n"
|
|
||||||
"Checksum: 0x%x\n\n",
|
|
||||||
functionName,
|
|
||||||
sourceFileName,
|
|
||||||
firstLineNumber,
|
|
||||||
id,
|
|
||||||
checksum
|
|
||||||
);
|
|
||||||
|
|
||||||
// Print arcs info
|
// Print arcs info
|
||||||
for ( currentArc = arcs.begin(); currentArc != arcs.end(); currentArc++ ) {
|
for ( currentArc = arcs.begin(); currentArc != arcs.end(); currentArc++ ) {
|
||||||
printArcInfo( textFile, currentArc );
|
printArcInfo( textFile, currentArc );
|
||||||
}
|
}
|
||||||
fprintf( textFile, "\n");
|
textFile << std::endl;
|
||||||
|
|
||||||
// Print blocks info
|
// Print blocks info
|
||||||
for ( currentBlock = blocks.begin();
|
for ( currentBlock = blocks.begin();
|
||||||
@ -233,8 +213,8 @@ namespace Gcov {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GcovFunctionData::printCoverageInfo(
|
void GcovFunctionData::printCoverageInfo(
|
||||||
FILE *textFile,
|
std::ofstream& textFile,
|
||||||
uint32_t function_number
|
uint32_t function_number
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint32_t baseAddress = 0;
|
uint32_t baseAddress = 0;
|
||||||
@ -254,12 +234,12 @@ namespace Gcov {
|
|||||||
}
|
}
|
||||||
baseSize = coverageMap->getSize();
|
baseSize = coverageMap->getSize();
|
||||||
|
|
||||||
fprintf(
|
textFile << std::endl << "Instructions (Base address: 0x"
|
||||||
textFile,
|
<< std::setfill( '0' ) << std::setw( 8 )
|
||||||
"\nInstructions (Base address: 0x%08x, Size: %4u): \n\n",
|
<< std::hex << baseAddress << std::dec << std::setfill( ' ' )
|
||||||
baseAddress,
|
<< ", Size: " << std::setw( 4 ) << baseSize
|
||||||
baseSize
|
<< "):" << std::endl << std::endl;
|
||||||
);
|
|
||||||
for ( instruction = symbolInfo->instructions.begin();
|
for ( instruction = symbolInfo->instructions.begin();
|
||||||
instruction != symbolInfo->instructions.end();
|
instruction != symbolInfo->instructions.end();
|
||||||
instruction++
|
instruction++
|
||||||
@ -267,27 +247,30 @@ namespace Gcov {
|
|||||||
{
|
{
|
||||||
if ( instruction->isInstruction ) {
|
if ( instruction->isInstruction ) {
|
||||||
currentAddress = instruction->address - baseAddress;
|
currentAddress = instruction->address - baseAddress;
|
||||||
fprintf( textFile, "0x%-70s ", instruction->line.c_str() );
|
|
||||||
fprintf( textFile, "| 0x%08x ", currentAddress );
|
textFile << std::left << "0x" << std::setw( 70 )
|
||||||
fprintf( textFile, "*");
|
<< instruction->line.c_str() << " " << std::right
|
||||||
fprintf( textFile,
|
<< "| 0x" << std::hex << std::setfill( '0' )
|
||||||
"| exec: %4u ",
|
<< std::setw( 8 ) << currentAddress << " "
|
||||||
coverageMap->getWasExecuted( currentAddress )
|
<< std::dec << std::setfill( ' ' )
|
||||||
);
|
<< "*| exec: " << std::setw( 4 )
|
||||||
fprintf( textFile, "| taken/not: %4u/%4u ",
|
<< coverageMap->getWasExecuted( currentAddress )
|
||||||
coverageMap->getWasTaken( currentAddress ),
|
<< " | taken/not: " << std::setw( 4 )
|
||||||
coverageMap->getWasNotTaken( currentAddress )
|
<< coverageMap->getWasTaken( currentAddress )
|
||||||
);
|
<< "/" << std::setw( 4 )
|
||||||
|
<< coverageMap->getWasNotTaken( currentAddress )
|
||||||
|
<< " ";
|
||||||
|
|
||||||
if ( instruction->isBranch )
|
if ( instruction->isBranch )
|
||||||
fprintf( textFile, "| Branch " );
|
textFile << "| Branch ";
|
||||||
else
|
else
|
||||||
fprintf( textFile, " " );
|
textFile << " ";
|
||||||
|
|
||||||
if ( instruction->isNop )
|
if ( instruction->isNop )
|
||||||
fprintf( textFile, "| NOP(%3u) \n", instruction->nopSize );
|
textFile << "| NOP(" << std::setw( 3 ) << instruction->nopSize
|
||||||
|
<< ") " << std::endl;
|
||||||
else
|
else
|
||||||
fprintf( textFile, " \n" );
|
textFile << " " << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,10 +278,10 @@ namespace Gcov {
|
|||||||
|
|
||||||
void GcovFunctionData::setBlockFileName(
|
void GcovFunctionData::setBlockFileName(
|
||||||
const blocks_iterator_t block,
|
const blocks_iterator_t block,
|
||||||
const char *fileName
|
const std::string& fileName
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
strcpy(block->sourceFileName, fileName);
|
block->sourceFileName = fileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GcovFunctionData::addBlockLine(
|
void GcovFunctionData::addBlockLine(
|
||||||
@ -310,9 +293,7 @@ namespace Gcov {
|
|||||||
(block->numberOfLines)++;
|
(block->numberOfLines)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
blocks_iterator_t GcovFunctionData::findBlockById(
|
blocks_iterator_t GcovFunctionData::findBlockById( const uint32_t id )
|
||||||
const uint32_t id
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
blocks_iterator_t blockIterator;
|
blocks_iterator_t blockIterator;
|
||||||
|
|
||||||
@ -324,78 +305,70 @@ namespace Gcov {
|
|||||||
blockIterator++;
|
blockIterator++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fprintf(
|
std::cerr << "ERROR: GcovFunctionData::findBlockById() failed"
|
||||||
stderr,
|
<< ", no blocks present" << std::endl;
|
||||||
"ERROR: GcovFunctionData::findBlockById() failed, no blocks present\n"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return blockIterator;
|
return blockIterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GcovFunctionData::printArcInfo(
|
void GcovFunctionData::printArcInfo(
|
||||||
FILE * textFile, arcs_iterator_t arc
|
std::ofstream& textFile,
|
||||||
|
arcs_iterator_t arc
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
fprintf(
|
textFile << " > ARC " << std::setw( 3 ) << arc->sourceBlock
|
||||||
textFile,
|
<< " -> " << arc->destinationBlock << " ";
|
||||||
" > ARC %3u -> %3u ",
|
|
||||||
arc->sourceBlock,
|
|
||||||
arc->destinationBlock
|
|
||||||
);
|
|
||||||
|
|
||||||
fprintf( textFile, "\tFLAGS: ");
|
textFile << "\tFLAGS: ";
|
||||||
switch ( arc->flags ){
|
switch ( arc->flags ) {
|
||||||
case 0:
|
case 0:
|
||||||
fprintf( textFile, "( ___________ ____ _______ )");
|
textFile << "( ___________ ____ _______ )";
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
fprintf( textFile, "( ___________ ____ ON_TREE )");
|
textFile << "( ___________ ____ ON_TREE )";
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
fprintf( textFile, "( ___________ FAKE _______ )");
|
textFile << "( ___________ FAKE _______ )";
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
fprintf( textFile, "( ___________ FAKE ON_TREE )");
|
textFile << "( ___________ FAKE ON_TREE )";
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
fprintf( textFile, "( FALLTHROUGH ____ _______ )");
|
textFile << "( FALLTHROUGH ____ _______ )";
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
fprintf( textFile, "( FALLTHROUGH ____ ON_TREE )");
|
textFile << "( FALLTHROUGH ____ ON_TREE )";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf( textFile, "( =======FLAGS_ERROR====== )");
|
textFile << "( =======FLAGS_ERROR====== )";
|
||||||
fprintf( stderr,
|
std::cerr << " ERROR: Unknown arc flag: 0x"
|
||||||
" ERROR: Unknown arc flag: 0x%x\n",
|
<< std::hex << arcs.back().flags << std::endl
|
||||||
arcs.back().flags
|
<< std::dec;
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf( textFile, "\tTaken: %5" PRIu64 "\n", (uint64_t) arc->counter );
|
|
||||||
|
textFile << "\tTaken: " << std::setw( 5 ) << arc->counter << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GcovFunctionData::printBlockInfo(
|
void GcovFunctionData::printBlockInfo(
|
||||||
FILE * textFile,
|
std::ofstream& textFile,
|
||||||
blocks_iterator_t block
|
blocks_iterator_t block
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
std::list<uint32_t>::iterator line;
|
std::list<uint32_t>::iterator line;
|
||||||
|
|
||||||
fprintf(
|
textFile << " > BLOCK " << std::setw( 3 ) << block->id
|
||||||
textFile,
|
<< " from " << block->sourceFileName << std::endl
|
||||||
" > BLOCK %3u from %s\n"
|
<< " -counter: " << std::setw( 5 ) << block->counter << std::endl
|
||||||
" -counter: %5" PRIu64 "\n"
|
<< " -flags: 0x" << std::hex << block->flags << std::endl
|
||||||
" -flags: 0x%" PRIx32 "\n"
|
<< " -lines: ";
|
||||||
" -lines: ",
|
|
||||||
block->id,
|
if ( !block->lines.empty() )
|
||||||
block->sourceFileName,
|
for ( line = block->lines.begin(); line != block->lines.end(); line++ ) {
|
||||||
(uint64_t) block->counter,
|
textFile << *line << ", ";
|
||||||
block->flags
|
}
|
||||||
);
|
|
||||||
if ( !block->lines.empty( ) )
|
textFile << std::endl;
|
||||||
for ( line = block->lines.begin() ; line != block->lines.end(); line++ )
|
|
||||||
fprintf ( textFile, "%u, ", *line);
|
|
||||||
fprintf ( textFile, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GcovFunctionData::processFunctionCounters( void ) {
|
bool GcovFunctionData::processFunctionCounters( void ) {
|
||||||
@ -410,14 +383,12 @@ namespace Gcov {
|
|||||||
std::list<uint64_t> taken; // List of taken counts for branches
|
std::list<uint64_t> taken; // List of taken counts for branches
|
||||||
std::list<uint64_t> notTaken; // List of not taken counts for branches
|
std::list<uint64_t> notTaken; // List of not taken counts for branches
|
||||||
|
|
||||||
//fprintf( stderr, "DEBUG: Processing counters for file: %s\n", sourceFileName );
|
//std::cerr << "DEBUG: Processing counters for file: " << sourceFileName
|
||||||
if ( blocks.empty() || arcs.empty() || coverageMap == NULL || symbolInfo->instructions.empty())
|
// << std::endl;
|
||||||
{
|
if ( blocks.empty() || arcs.empty() || coverageMap == NULL || symbolInfo->instructions.empty()) {
|
||||||
//fprintf( stderr,
|
//std::cerr << "DEBUG: sanity check returned false for function: "
|
||||||
// "DEBUG: sanity check returned false for function: %s from file: %s\n",
|
// << functionName << " from file: " << sourceFileName
|
||||||
// functionName,
|
// << std::endl;
|
||||||
// sourceFileName
|
|
||||||
//);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,20 +404,19 @@ namespace Gcov {
|
|||||||
// Find taken/not taken values for branches
|
// Find taken/not taken values for branches
|
||||||
if ( !processBranches( &taken , ¬Taken ) )
|
if ( !processBranches( &taken , ¬Taken ) )
|
||||||
{
|
{
|
||||||
//fprintf( stderr,
|
//std::cerr << "ERROR: Failed to process branches for function: "
|
||||||
// "ERROR: Failed to process branches for function: %s from file: %s\n",
|
// << functionName << " from file: " << sourceFileName
|
||||||
// functionName,
|
// << std::endl;
|
||||||
// sourceFileName
|
|
||||||
//);
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Process the branching arcs
|
// Process the branching arcs
|
||||||
while ( blockIterator != blocks.end() ) {
|
while ( blockIterator != blocks.end() ) {
|
||||||
//fprintf( stderr, "DEBUG: Processing branches\n" );
|
//std::cerr << "DEBUG: Processing branches" << std::endl;
|
||||||
while ( arcIterator->sourceBlock != blockIterator->id ) {
|
while ( arcIterator->sourceBlock != blockIterator->id ) {
|
||||||
if ( arcIterator == arcs.end() ) {
|
if ( arcIterator == arcs.end() ) {
|
||||||
//fprintf( stderr, "ERROR: Unexpectedly runned out of arcs to analyze\n" );
|
//std::cerr << "ERROR: Unexpectedly runned out of arcs to analyze"
|
||||||
|
// << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
arcIterator++;
|
arcIterator++;
|
||||||
@ -464,15 +434,16 @@ namespace Gcov {
|
|||||||
!( arcIterator2->flags & FAKE_ARC_FLAG )
|
!( arcIterator2->flags & FAKE_ARC_FLAG )
|
||||||
) {
|
) {
|
||||||
if ( taken.empty() || notTaken.empty() ) {
|
if ( taken.empty() || notTaken.empty() ) {
|
||||||
fprintf(
|
std::cerr << "ERROR: Branches missing for function: "
|
||||||
stderr,
|
<< functionName << " from file: " << sourceFileName
|
||||||
"ERROR: Branchess missing for function: %s from file: %s\n",
|
<< std::endl;
|
||||||
functionName,
|
|
||||||
sourceFileName
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//fprintf( stderr, "DEBUG: Found true branching arc %3u -> %3u\n", arcIterator->sourceBlock, arcIterator->destinationBlock );
|
|
||||||
|
//std::cerr << "DEBUG: Found true branching arc "
|
||||||
|
// << std::setw( 3 ) << arcIterator->sourceBlock << " -> "
|
||||||
|
// << std::setw( 3 ) << arcIteratior->destinationBlock
|
||||||
|
// << std::endl;
|
||||||
if ( arcIterator->flags & FALLTHROUGH_ARC_FLAG ) {
|
if ( arcIterator->flags & FALLTHROUGH_ARC_FLAG ) {
|
||||||
arcIterator->counter = notTaken.front();
|
arcIterator->counter = notTaken.front();
|
||||||
notTaken.pop_front();
|
notTaken.pop_front();
|
||||||
@ -513,7 +484,8 @@ namespace Gcov {
|
|||||||
while ( blockIterator != blocks.end() ) {
|
while ( blockIterator != blocks.end() ) {
|
||||||
while ( arcIterator->sourceBlock != blockIterator->id ) {
|
while ( arcIterator->sourceBlock != blockIterator->id ) {
|
||||||
if ( arcIterator == arcs.end() ) {
|
if ( arcIterator == arcs.end() ) {
|
||||||
fprintf( stderr, "ERROR: Unexpectedly runned out of arcs to analyze\n" );
|
std::cerr << "ERROR: Unexpectedly runned out of arcs to analyze"
|
||||||
|
<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
arcIterator++;
|
arcIterator++;
|
||||||
@ -522,11 +494,9 @@ namespace Gcov {
|
|||||||
|
|
||||||
// If this is the last arc, propagate counter and exit
|
// If this is the last arc, propagate counter and exit
|
||||||
if ( arcIterator2 == arcs.end() ) {
|
if ( arcIterator2 == arcs.end() ) {
|
||||||
//fprintf( stderr,
|
//std::cerr << "DEBUG: Found last arc " << std::setw( 3 )
|
||||||
// "DEBUG: Found last arc %3u -> %3u\n",
|
// << arcIterator->sourceBlock << " -> " << std::setw( 3 )
|
||||||
// arcIterator->sourceBlock,
|
// << arcIterator->destinationBlock << std::endl;
|
||||||
// arcIterator->destinationBlock
|
|
||||||
//);
|
|
||||||
arcIterator->counter = blockIterator->counter;
|
arcIterator->counter = blockIterator->counter;
|
||||||
blockIterator2 = blocks.begin();
|
blockIterator2 = blocks.begin();
|
||||||
while ( arcIterator->destinationBlock != blockIterator2->id) //TODO: ADD FAILSAFE
|
while ( arcIterator->destinationBlock != blockIterator2->id) //TODO: ADD FAILSAFE
|
||||||
@ -537,7 +507,9 @@ namespace Gcov {
|
|||||||
|
|
||||||
// If this is not a branch, propagate counter and continue
|
// If this is not a branch, propagate counter and continue
|
||||||
if ( arcIterator->sourceBlock != arcIterator2->sourceBlock ) {
|
if ( arcIterator->sourceBlock != arcIterator2->sourceBlock ) {
|
||||||
//fprintf( stderr, "DEBUG: Found simple arc %3u -> %3u\n", arcIterator->sourceBlock, arcIterator->destinationBlock );
|
//std::cerr << "DEBUG: Found simple arc " << std::setw( 3 )
|
||||||
|
// << arcIterator->sourceBlock << " -> " << std::setw( 3 )
|
||||||
|
// << arcIterator->destinationBlock << std::endl;
|
||||||
arcIterator->counter = blockIterator->counter;
|
arcIterator->counter = blockIterator->counter;
|
||||||
blockIterator2 = blocks.begin();;
|
blockIterator2 = blocks.begin();;
|
||||||
while ( arcIterator->destinationBlock != blockIterator2->id) //TODO: ADD FAILSAFE
|
while ( arcIterator->destinationBlock != blockIterator2->id) //TODO: ADD FAILSAFE
|
||||||
@ -548,7 +520,9 @@ namespace Gcov {
|
|||||||
// If this is a branch with FAKE arc
|
// If this is a branch with FAKE arc
|
||||||
else if ( (arcIterator->sourceBlock == arcIterator2->sourceBlock ) && ( arcIterator2->flags & FAKE_ARC_FLAG ))
|
else if ( (arcIterator->sourceBlock == arcIterator2->sourceBlock ) && ( arcIterator2->flags & FAKE_ARC_FLAG ))
|
||||||
{
|
{
|
||||||
//fprintf( stderr, "DEBUG: Found fake branching arc %3u -> %3u\n", arcIterator->sourceBlock, arcIterator->destinationBlock );
|
//std::cerr << "DEBUG: Found fake branching arc " << std::setw( 3 )
|
||||||
|
// << arcIterator->sourceBlock << " -> " << std::setw( 3 )
|
||||||
|
// << arcIterator->destinationBlock << std::endl;
|
||||||
arcIterator->counter = blockIterator->counter;
|
arcIterator->counter = blockIterator->counter;
|
||||||
blockIterator2 = blocks.begin();
|
blockIterator2 = blocks.begin();
|
||||||
while ( arcIterator->destinationBlock != blockIterator2->id) //TODO: ADD FAILSAFE
|
while ( arcIterator->destinationBlock != blockIterator2->id) //TODO: ADD FAILSAFE
|
||||||
@ -582,7 +556,8 @@ namespace Gcov {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//fprintf( stderr, "DEBUG: Processing instructions in search of branches\n" );
|
// std::cerr << "DEBUG: Processing instructions in search of branches"
|
||||||
|
// << std::endl;
|
||||||
for (instruction = symbolInfo->instructions.begin(); instruction != symbolInfo->instructions.end(); instruction++)
|
for (instruction = symbolInfo->instructions.begin(); instruction != symbolInfo->instructions.end(); instruction++)
|
||||||
{
|
{
|
||||||
if ( instruction->isInstruction) {
|
if ( instruction->isInstruction) {
|
||||||
@ -590,11 +565,12 @@ namespace Gcov {
|
|||||||
if ( instruction->isBranch ) {
|
if ( instruction->isBranch ) {
|
||||||
taken->push_back ( (uint64_t) coverageMap->getWasTaken( currentAddress ) );
|
taken->push_back ( (uint64_t) coverageMap->getWasTaken( currentAddress ) );
|
||||||
notTaken->push_back ( (uint64_t) coverageMap->getWasNotTaken( currentAddress ) );
|
notTaken->push_back ( (uint64_t) coverageMap->getWasNotTaken( currentAddress ) );
|
||||||
//fprintf( stderr,
|
|
||||||
// "Added branch to list taken/not: %4u/%4u\n",
|
//std::cerr << "Added branch to list taken/not: " << std::setw( 4 )
|
||||||
// coverageMap->getWasTaken( currentAddress ),
|
// << coverageMap->getWasTaken( currentAddress )
|
||||||
// coverageMap->getWasNotTaken( currentAddress )
|
// << "/" << std::setw( 4 )
|
||||||
//);
|
// << coverageMap->getWasNotTaken( currentAddress )
|
||||||
|
// << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
#include "CoverageMapBase.h"
|
#include "CoverageMapBase.h"
|
||||||
#include "DesiredSymbols.h"
|
#include "DesiredSymbols.h"
|
||||||
|
|
||||||
@ -35,7 +37,7 @@ struct gcov_block_info
|
|||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t numberOfLines;
|
uint32_t numberOfLines;
|
||||||
uint64_t counter;
|
uint64_t counter;
|
||||||
char sourceFileName[FILE_NAME_LENGTH];
|
std::string sourceFileName;
|
||||||
std::list<uint32_t> lines;
|
std::list<uint32_t> lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -101,7 +103,7 @@ class DesiredSymbols;
|
|||||||
* @return Returns TRUE if the method succeeded and FALSE if it failed.
|
* @return Returns TRUE if the method succeeded and FALSE if it failed.
|
||||||
*/
|
*/
|
||||||
bool setFunctionName(
|
bool setFunctionName(
|
||||||
const char* fcnName,
|
const std::string& fcnName,
|
||||||
Coverage::DesiredSymbols& symbolsToAnalyze
|
Coverage::DesiredSymbols& symbolsToAnalyze
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -112,9 +114,7 @@ class DesiredSymbols;
|
|||||||
*
|
*
|
||||||
* @return Returns TRUE if the method succeeded and FALSE if it failed.
|
* @return Returns TRUE if the method succeeded and FALSE if it failed.
|
||||||
*/
|
*/
|
||||||
bool setFileName(
|
bool setFileName( const std::string& fileName );
|
||||||
const char* fileName
|
|
||||||
);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method stores name of the source file where block is located
|
* This method stores name of the source file where block is located
|
||||||
@ -126,7 +126,7 @@ class DesiredSymbols;
|
|||||||
*/
|
*/
|
||||||
void setBlockFileName(
|
void setBlockFileName(
|
||||||
const blocks_iterator_t block,
|
const blocks_iterator_t block,
|
||||||
const char* fileName
|
const std::string& fileName
|
||||||
);
|
);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -194,9 +194,7 @@ class DesiredSymbols;
|
|||||||
*
|
*
|
||||||
* @return Returns iterator to a matching block or NULL for error.
|
* @return Returns iterator to a matching block or NULL for error.
|
||||||
*/
|
*/
|
||||||
blocks_iterator_t findBlockById(
|
blocks_iterator_t findBlockById( const uint32_t id );
|
||||||
const uint32_t id
|
|
||||||
);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method adds new block to block list
|
* This method adds new block to block list
|
||||||
@ -208,18 +206,24 @@ class DesiredSymbols;
|
|||||||
void addBlock(
|
void addBlock(
|
||||||
const uint32_t id,
|
const uint32_t id,
|
||||||
const uint32_t flags,
|
const uint32_t flags,
|
||||||
const char * sourceFileName
|
const std::string& sourceFileName
|
||||||
);
|
);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method prints info about function
|
* This method prints info about function
|
||||||
*/
|
*/
|
||||||
void printFunctionInfo( FILE * textFile, uint32_t function_number );
|
void printFunctionInfo(
|
||||||
|
std::ofstream& textFile,
|
||||||
|
uint32_t function_number
|
||||||
|
);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method prints info about coverage of this function
|
* This method prints info about coverage of this function
|
||||||
*/
|
*/
|
||||||
void printCoverageInfo( FILE * textFile, uint32_t function_number );
|
void printCoverageInfo(
|
||||||
|
std::ofstream& textFile,
|
||||||
|
uint32_t function_number
|
||||||
|
);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method prints info about chosen arc in arcs list
|
* This method prints info about chosen arc in arcs list
|
||||||
@ -227,20 +231,14 @@ class DesiredSymbols;
|
|||||||
* @param[in] textFile specifies output file
|
* @param[in] textFile specifies output file
|
||||||
* @param[in] arc passes iterator identifying arc
|
* @param[in] arc passes iterator identifying arc
|
||||||
*/
|
*/
|
||||||
void printArcInfo(
|
void printArcInfo( std::ofstream& textFile, arcs_iterator_t arc );
|
||||||
FILE * textFile,
|
|
||||||
arcs_iterator_t arc
|
|
||||||
);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method prints info about chosen block in blocks list
|
* This method prints info about chosen block in blocks list
|
||||||
*
|
*
|
||||||
* @param[in] block passes iterator identifying block
|
* @param[in] block passes iterator identifying block
|
||||||
*/
|
*/
|
||||||
void printBlockInfo(
|
void printBlockInfo( std::ofstream& textFile, blocks_iterator_t block );
|
||||||
FILE * textFile,
|
|
||||||
blocks_iterator_t block
|
|
||||||
);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This method calculates values of arc counters
|
* This method calculates values of arc counters
|
||||||
@ -256,8 +254,8 @@ class DesiredSymbols;
|
|||||||
uint32_t numberOfArcs;
|
uint32_t numberOfArcs;
|
||||||
arcs_t arcs;
|
arcs_t arcs;
|
||||||
blocks_t blocks;
|
blocks_t blocks;
|
||||||
char functionName[FUNCTION_NAME_LENGTH];
|
std::string functionName;
|
||||||
char sourceFileName[FILE_NAME_LENGTH];
|
std::string sourceFileName;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* This member contains the unified or merged coverage map
|
* This member contains the unified or merged coverage map
|
||||||
|
Loading…
x
Reference in New Issue
Block a user