Hi all,
I'm trying to use the new loop API to find the head basic block
for loops in the applications we are doing performance analysis
on.
The old api had a function for that:
BPatch_basicBlock* head = loop->getLoopHead();
but now, we need to figure it out on our own.
I must be doing something wrong because I never get any source
lines returned from the
bool linesFound = module->getSourceLines(
bbstartAddr, filesAndlines);
call below.ÂÂ The new code is bracketed by the #if
DyninstAPI_VERSION_MAJOR >= 9 line below.
Does anyone see anything obvious that I'm doing wrong?Â
I checked for the presence of the dwarf information via
dwarfdump and there appears to be statement information present.
This is the function from DyninstSymbols.cxx from our
OpenSpeedShop code, that I'm working on to get loop info:
/** Get the loops containing the specified
address. */
std::vector<LoopInfo> getLoopsAt(const Address&
address, BPatch_image& image)
{
ÂÂÂ std::vector<LoopInfo> retval;
ÂÂ Â
ÂÂÂ // Iterate over each module within the specified image
ÂÂ Â
ÂÂÂ BPatch_Vector<BPatch_module*>* modules =
image.getModules();
ÂÂ Â
ÂÂÂ if (modules == NULL)
ÂÂÂ {
ÂÂÂÂÂÂÂ return retval;
ÂÂÂ }
ÂÂ Â
ÂÂÂ for (unsigned int m = 0; m < modules->size();
++m)
ÂÂÂ {
ÂÂÂÂÂÂÂ BPatch_module* module = (*modules)[m];
ÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂ if (module == NULL)
ÂÂÂÂÂÂÂ {
ÂÂÂÂÂÂÂÂÂÂÂ continue;
ÂÂÂÂÂÂÂ }
ÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂ Address module_base =
(uint64_t)module->getBaseAddr();
ÂÂÂÂÂÂÂ // Find the function(s) containing the specified
address
ÂÂÂÂÂÂÂ BPatch_Vector<BPatch_function*> functions;
ÂÂÂÂÂÂÂ module->findFunctionByAddress(
ÂÂÂÂÂÂÂÂÂÂÂ (void*)((module_base + address).getValue()),
functions, false, false
ÂÂÂÂÂÂÂÂÂÂÂ );
ÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂ for (unsigned int f = 0; f < functions.size();
++f)
ÂÂÂÂÂÂÂ {
ÂÂÂÂÂÂÂÂÂÂÂ BPatch_function* function = functions[f];
ÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂ if (function == NULL)
ÂÂÂÂÂÂÂÂÂÂÂ {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ continue;
ÂÂÂÂÂÂÂÂÂÂÂ }
ÂÂÂÂÂÂÂÂÂÂÂ // Find the loops containing the specified
address
ÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂ BPatch_flowGraph* cfg = function->getCFG();
ÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂ if (cfg == NULL)
ÂÂÂÂÂÂÂÂÂÂÂ {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ continue;
ÂÂÂÂÂÂÂÂÂÂÂ }
ÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂ BPatch_Vector<BPatch_basicBlockLoop*>
loops;
ÂÂÂÂÂÂÂÂÂÂÂ cfg->getLoops(loops);
ÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂ for (unsigned int l = 0; l < loops.size();
++l)
ÂÂÂÂÂÂÂÂÂÂÂ {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ BPatch_basicBlockLoop* loop = loops[l];
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ if ((loop == NULL) ||
!loop->containsAddressInclusive(
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ (module_base + address).getValue()
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ ))
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ continue;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ }
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // A loop containing this address has been
found! Rejoice!
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // And, of course, obtain the loop's head
address and basic
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // block address ranges...
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ #if DyninstAPI_VERSION_MAJOR >= 9
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // Need to use the new dyninst API for
finding the head of the loop
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // One possibility - from wdh - might be to
call getLoopEntries() to
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // get the basic block of each entry. Then,
for each of these, take
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // the first address of that basic block
and query the source
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // file/line containing that address.
Assuming that all line numbers are within
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // a single source file, the minimum line
number is probably reasonably the
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // loop definition. And the first address
in that basic block would be the one
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // to use for âaddr_headâ in the Open|SS
database.
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ BPatch_basicBlock* head;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ std::vector<BPatch_basicBlock*>
entries;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ loop->getLoopEntries(entries);
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ std::cerr << " entries.size()="
<< entries.size() << std::endl;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // bbe: Loop through the basic block
entries
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ
std::vector<BPatch_basicBlock*>::iterator bbe;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ std::cerr << "entries.begin() !=
entries.end()=" << (entries.begin() != entries.end())
<< std::endl;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // filesAndlines: Return value file names
and line numbers from getSourceLines
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ std::vector<BPatch_statement >
filesAndlines ;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // Loop through the loops basic blocks, get
the starting address of the block
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // Then use that address to get the
filename and line number for that address
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // We are looking for the minimum line
number for the blocks in the loop to use
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // as the loop head basic block.
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ head = entries[0]; // give an intial value
to the loop head
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ for (bbe = entries.begin(); bbe !=
entries.end(); ++bbe) {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ unsigned long bbstartAddr =
(*bbe)->getStartAddress();
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ std::cerr << "module=" <<
module << " bbe=" << (*bbe) << "
bbstartAddr=" << std::hex << bbstartAddr <<
std::endl;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ bool linesFound =
module->getSourceLines( bbstartAddr, filesAndlines);
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ std::cerr << "linesFound=" <<
linesFound << std::endl;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ std::cerr << " filesAlines.size()="
<< filesAndlines.size() << std::endl;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ if (linesFound) {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ std::cerr << "
filesAlines.size()=" << filesAndlines.size() <<
std::endl;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ
std::vector<BPatch_statement>::iterator lf_dx;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ for (lf_dx = filesAndlines.begin();
lf_dx != filesAndlines.end(); ++lf_dx) {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ std::cerr << "fileName="
<< (*lf_dx).fileName() << " lineNumber=" <<
(*lf_dx).lineNumber() << std::endl;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ }
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ } // linesFound
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ } // entries
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ #else
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ BPatch_basicBlock* head =
loop->getLoopHead();
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ #endif
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ if (head == NULL)
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ continue;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ }
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ // Use the loop head basic block to create
the necessary loop information to return
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ LoopInfo
info(Address(head->getStartAddress()) - module_base);
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ BPatch_Vector<BPatch_basicBlock*>
blocks;
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ loop->getLoopBasicBlocks(blocks);
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ for (unsigned int i = 0; i <
blocks.size(); ++i)
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ BPatch_basicBlock* block = blocks[i];
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ if (block != NULL)
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ {
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ info.dm_ranges.push_back(
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ AddressRange(
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ
Address(block->getStartAddress()) - module_base,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ
Address(block->getEndAddress()) - module_base
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ )
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ );
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ }
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ }
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ retval.push_back(info);
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂ Â
ÂÂÂÂÂÂÂÂÂÂÂ } // l
ÂÂÂÂÂÂÂ } // f
ÂÂÂ } // m
ÂÂÂ return retval;
}
I never get any lines returned from getSourceLines even though I
can see them in the dwarfdump output.
I attached the full dwarfdump output and the smg2000 run with
the debug output (snippet below).
[openss]: Converting raw data from /opt/shared/offline-oss into
temp file X.0.openss
Processing raw data for smg2000 ...
Processing processes and threads ...
Processing performance data ...
Processing symbols ...
Resolving symbols for
/home/jeg/DEMOS/demos/mpi/openmpi-1.8.2/smg2000/test/smg2000
Âentries.size()=1
entries.begin() != entries.end()=1
module=0x1bd6810 bbe=0x200f980 bbstartAddr=4020d3
linesFound=0
ÂfilesAlines.size()=0
Âentries.size()=1
entries.begin() != entries.end()=1
module=0x1bd6810 bbe=0x20111e0 bbstartAddr=40215f
linesFound=0
ÂfilesAlines.size()=0
Âentries.size()=1
entries.begin() != entries.end()=1
module=0x1bd6810 bbe=0x2012b70 bbstartAddr=4021f3
linesFound=0
ÂfilesAlines.size()=0
Âentries.size()=1
entries.begin() != entries.end()=1
module=0x1bd6810 bbe=0x20464a0 bbstartAddr=4036a9
linesFound=0
...
...