For inlined subprograms, the "root" inliner means the bottom-most non-inlined function. This subprogram contains all the line data for it's own non-inlined instructions, PLUS line data for all inlined functions that it calls. The inlined functions has empty mLineInfo structures. When we pass a non-NULL value into inlinedSubprogram, we are requesting to ONLY return lines that were emitted from th
| 586 | // the 'this' subprogram. Thus, we do a "get any line" call on the root inliner and then filter the results based |
| 587 | // on whether they are relevant. |
| 588 | DbgLineData* DbgSubprogram::FindClosestLine(addr_target addr, DbgSubprogram** inlinedSubprogram, DbgSrcFile** srcFile, int* outLineIdx) |
| 589 | { |
| 590 | if (mLineInfo == NULL) |
| 591 | { |
| 592 | if (mInlineeInfo == NULL) |
| 593 | return NULL; |
| 594 | |
| 595 | if ((inlinedSubprogram != NULL) && (*inlinedSubprogram != NULL)) |
| 596 | { |
| 597 | // Keep explicit inlinee requirement |
| 598 | return mInlineeInfo->mRootInliner->FindClosestLine(addr, inlinedSubprogram, srcFile, outLineIdx); |
| 599 | } |
| 600 | else |
| 601 | { |
| 602 | DbgSubprogram* rootInlinedSubprogram = NULL; |
| 603 | auto result = mInlineeInfo->mRootInliner->FindClosestLine(addr, &rootInlinedSubprogram, srcFile, outLineIdx); |
| 604 | if (result == NULL) |
| 605 | return NULL; |
| 606 | if (rootInlinedSubprogram == NULL) // Do not allow root parent, as we cannot be a parent to the root parent (duh) |
| 607 | return NULL; |
| 608 | |
| 609 | // We need to check to see if we are a parent of the found line |
| 610 | auto checkSubprogram = rootInlinedSubprogram; |
| 611 | while ((checkSubprogram != NULL) && (checkSubprogram->mInlineeInfo != NULL)) |
| 612 | { |
| 613 | if (checkSubprogram == this) |
| 614 | { |
| 615 | if (inlinedSubprogram != NULL) |
| 616 | *inlinedSubprogram = rootInlinedSubprogram; |
| 617 | return result; |
| 618 | } |
| 619 | checkSubprogram = checkSubprogram->mInlineeInfo->mInlineParent; |
| 620 | } |
| 621 | |
| 622 | return NULL; |
| 623 | } |
| 624 | } |
| 625 | |
| 626 | // Binary search - lineData is sorted |
| 627 | int first = 0; |
| 628 | int last = (int)mLineInfo->mLines.mSize - 1; |
| 629 | int middle = (first + last) / 2; |
| 630 | |
| 631 | int useIdx = -1; |
| 632 | |
| 633 | while (first <= last) |
| 634 | { |
| 635 | addr_target midAddr = (addr_target)(mLineInfo->mLines.mVals[middle].mRelAddress + mCompileUnit->mDbgModule->mImageBase); |
| 636 | if (midAddr < addr) |
| 637 | first = middle + 1; |
| 638 | else if (midAddr == addr) |
| 639 | { |
| 640 | useIdx = middle; |
| 641 | break; |
| 642 | } |
| 643 | else |
| 644 | last = middle - 1; |
| 645 |
no outgoing calls
no test coverage detected