summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Kulaychuk <igor.kulaychuk@gmail.com>2016-12-19 14:03:59 +0300
committerJan Vorlicek <janvorli@microsoft.com>2016-12-19 12:03:59 +0100
commitd23b78ce50d04e97cc23f997fab8c0ce5faa8726 (patch)
tree595aa07ab83ff85d0a3332425afd88967ee6404f /src
parent6fce053a60454b76e09a0677ea0568de1d165b43 (diff)
downloadcoreclr-d23b78ce50d04e97cc23f997fab8c0ce5faa8726.tar.gz
coreclr-d23b78ce50d04e97cc23f997fab8c0ce5faa8726.tar.bz2
coreclr-d23b78ce50d04e97cc23f997fab8c0ce5faa8726.zip
[Linux][GDB-JIT] Fix bugs in gdbjit that break lldb stepping (#8637)
* Fix .text and .thunk symbols overlapping When current method calls itself, a __thunk* symbol might be generated with the same address as the method symbol in .text section. Avoid generating such __thunk* symbol. * Do not create DWARF line table entries with the same address * For each HiddenLine assign a zero line number in DWARF Allow LLDB to to skip HiddenLines when stepping. * Fix __thunk symbols containing garbage Fix a bug when __thunk* symbols of previously compiled methods cause generation of __thunk* symbols for currently compiled method without filling symbol info. * Fix missing check for the end of list of compiled methods * Remove unnecessary check for zero prevLine in gdbjit
Diffstat (limited to 'src')
-rw-r--r--src/vm/gdbjit.cpp44
-rw-r--r--src/vm/gdbjit.h2
2 files changed, 33 insertions, 13 deletions
diff --git a/src/vm/gdbjit.cpp b/src/vm/gdbjit.cpp
index 96f8f8f93d..8e728839d6 100644
--- a/src/vm/gdbjit.cpp
+++ b/src/vm/gdbjit.cpp
@@ -1648,13 +1648,11 @@ void NotifyGdb::MethodCompiled(MethodDesc* MethodDescPtr)
CodeHeader* pCH = (CodeHeader*)pCode - 1;
CalledMethod* pCalledMethods = reinterpret_cast<CalledMethod*>(pCH->GetCalledMethods());
/* Collect addresses of thunks called by method */
- if (!CollectCalledMethods(pCalledMethods))
+ if (!CollectCalledMethods(pCalledMethods, (TADDR)MethodDescPtr->GetNativeCode()))
{
return;
}
pCH->SetCalledMethods(NULL);
- if (!codeAddrs.Contains((TADDR)pCode))
- codeAddrs.Add((TADDR)pCode);
MetaSig sig(MethodDescPtr);
int nArgsCount = sig.NumFixedArgs();
@@ -2102,18 +2100,17 @@ static void fixLineMapping(SymbolsInfo* lines, unsigned nlines)
int prevLine = 0;
for (int i = 0; i < nlines; ++i)
{
+ if (lines[i].lineNumber == HiddenLine)
+ continue;
if (lines[i].ilOffset == ICorDebugInfo::PROLOG) // will be fixed in next step
{
prevLine = 0;
}
else
{
- if (lines[i].lineNumber == 0 || lines[i].lineNumber == HiddenLine)
+ if (lines[i].lineNumber == 0)
{
- if (prevLine != 0)
- {
- lines[i].lineNumber = prevLine;
- }
+ lines[i].lineNumber = prevLine;
}
else
{
@@ -2125,11 +2122,23 @@ static void fixLineMapping(SymbolsInfo* lines, unsigned nlines)
prevLine = lines[nlines - 1].lineNumber;
for (int i = nlines - 1; i >= 0; --i)
{
- if (lines[i].lineNumber == 0 || lines[i].lineNumber == HiddenLine)
+ if (lines[i].lineNumber == HiddenLine)
+ continue;
+ if (lines[i].lineNumber == 0)
lines[i].lineNumber = prevLine;
else
prevLine = lines[i].lineNumber;
}
+ // Skip HiddenLines
+ for (int i = 0; i < nlines; ++i)
+ {
+ if (lines[i].lineNumber == HiddenLine)
+ {
+ lines[i].lineNumber = 0;
+ if (i + 1 < nlines && lines[i + 1].ilOffset == ICorDebugInfo::NO_MAPPING)
+ lines[i + 1].lineNumber = 0;
+ }
+ }
}
/* Build program for DWARF source line section */
@@ -2166,6 +2175,13 @@ bool NotifyGdb::BuildLineProg(MemBuf& buf, PCODE startAddr, TADDR codeSize, Symb
prevFile = lines[i].fileIndex;
}
+ // GCC don't use the is_prologue_end flag to mark the first instruction after the prologue.
+ // Instead of it it is issueing a line table entry for the first instruction of the prologue
+ // and one for the first instruction after the prologue.
+ // We do not want to confuse the debugger so we have to avoid adding a line in such case.
+ if (i > 0 && lines[i - 1].nativeOffset == lines[i].nativeOffset)
+ continue;
+
IssueSetAddress(ptr, startAddr + lines[i].nativeOffset);
if (lines[i].lineNumber != prevLine) {
@@ -2369,10 +2385,13 @@ bool NotifyGdb::BuildDebugPub(MemBuf& buf, const char* name, uint32_t size, uint
}
/* Store addresses and names of the called methods into symbol table */
-bool NotifyGdb::CollectCalledMethods(CalledMethod* pCalledMethods)
+bool NotifyGdb::CollectCalledMethods(CalledMethod* pCalledMethods, TADDR nativeCode)
{
AddrSet tmpCodeAddrs;
+ if (!codeAddrs.Contains(nativeCode))
+ codeAddrs.Add(nativeCode);
+
CalledMethod* pList = pCalledMethods;
/* count called methods */
@@ -2389,7 +2408,8 @@ bool NotifyGdb::CollectCalledMethods(CalledMethod* pCalledMethods)
SymbolNames = new (nothrow) Elf_Symbol[SymbolCount];
pList = pCalledMethods;
- for (int i = 1 + method.GetCount(); i < SymbolCount;)
+ int i = 1 + method.GetCount();
+ while (i < SymbolCount && pList != NULL)
{
TADDR callAddr = (TADDR)pList->GetCallAddr();
if (!codeAddrs.Contains(callAddr))
@@ -2408,7 +2428,7 @@ bool NotifyGdb::CollectCalledMethods(CalledMethod* pCalledMethods)
pList = pList->GetNext();
delete ptr;
}
-
+ SymbolCount = i;
return true;
}
diff --git a/src/vm/gdbjit.h b/src/vm/gdbjit.h
index 7d440b7e93..3160eccf57 100644
--- a/src/vm/gdbjit.h
+++ b/src/vm/gdbjit.h
@@ -401,7 +401,7 @@ private:
static void IssueSimpleCommand(char*& ptr, uint8_t command);
static void IssueParamCommand(char*& ptr, uint8_t command, char* param, int param_len);
static void SplitPathname(const char* path, const char*& pathName, const char*& fileName);
- static bool CollectCalledMethods(CalledMethod* pCM);
+ static bool CollectCalledMethods(CalledMethod* pCM, TADDR nativeCode);
#ifdef _DEBUG
static void DumpElf(const char* methodName, const MemBuf& buf);
#endif