[runtime][source info][mac] return inline at position for stack trace

This commit is contained in:
Vasily Levchenko
2020-04-16 11:33:16 +02:00
parent a39b496938
commit 0ffd518a38
+53 -11
View File
@@ -22,6 +22,7 @@
#include <limits.h> #include <limits.h>
#include <stdint.h> #include <stdint.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
typedef struct _CSTypeRef { typedef struct _CSTypeRef {
unsigned long type; unsigned long type;
@@ -100,8 +101,16 @@ bool TryInitializeCoreSymbolication() {
} // namespace } // namespace
typedef struct {
const char * fileName;
int start;
int end;
} SymbolSourceInfoLimits;
extern "C" struct SourceInfo Kotlin_getSourceInfo(void* addr) { extern "C" struct SourceInfo Kotlin_getSourceInfo(void* addr) {
__block SourceInfo result = { .fileName = nullptr, .lineNumber = -1, .column = -1 }; __block SourceInfo result = { .fileName = nullptr, .lineNumber = -1, .column = -1 };
__block bool continueUpdateResult = true;
__block SymbolSourceInfoLimits limits = {.start = -1, .end = -1};
static bool csIsAvailable = TryInitializeCoreSymbolication(); static bool csIsAvailable = TryInitializeCoreSymbolication();
@@ -115,21 +124,54 @@ extern "C" struct SourceInfo Kotlin_getSourceInfo(void* addr) {
if (CSIsNull(symbol)) if (CSIsNull(symbol))
return result; return result;
/**
* ASSUMPTION: we assume that the _first_ and the _last_ source infos should belong to real function(symbol) the rest might belong to
* inlined functions.
*/
CSSymbolForeachSourceInfo(symbol,
^(CSSourceInfoRef ref) {
uint32_t lineNumber = CSSourceInfoGetLineNumber(ref);
if (lineNumber == 0)
return 0;
if (limits.start == -1) {
limits.start = lineNumber;
limits.fileName = CSSourceInfoGetPath(ref);
} else {
limits.end = lineNumber;
}
return 0;
});
result.fileName = limits.fileName;
CSSymbolForeachSourceInfo(symbol, CSSymbolForeachSourceInfo(symbol,
^(CSSourceInfoRef ref) { ^(CSSourceInfoRef ref) {
uint32_t lineNumber = CSSourceInfoGetLineNumber(ref); uint32_t lineNumber = CSSourceInfoGetLineNumber(ref);
if (lineNumber == 0)
return 0;
CSRange range = CSSourceInfoGetRange(ref); CSRange range = CSSourceInfoGetRange(ref);
if (lineNumber != 0 const char* fileName = CSSourceInfoGetPath(ref);
&& address >= range.location /**
&& address < range.location + range.length) { * We need to change API fo Kotlin_getSourceInfo to return information about inlines,
const char* fileName = CSSourceInfoGetPath(ref); * but for a moment we have to track that we updating result info _only_ for upper level or _inlined at_ and
if (fileName != nullptr) { * don't go deeper. at deeper level we check only that we at the right _inlined at_ position.
result.fileName = fileName; */
result.lineNumber = lineNumber; if (continueUpdateResult
result.column = CSSourceInfoGetColumn(ref); && strcmp(limits.fileName, fileName) == 0
} && lineNumber >= limits.start
} && lineNumber <= limits.end) {
return 0; result.lineNumber = lineNumber;
result.column = CSSourceInfoGetColumn(ref);
}
/**
* if found right inlined function don't bother with
* updating high level inlined _at_ source info
*/
if (continueUpdateResult && (address >= range.location
&& address < range.location + range.length))
continueUpdateResult = false;
return 0;
}); });
} }
return result; return result;