Add a debuginfo version check for RenderScript modules

Added an extra field parser to the `RSModuleDescriptor` class enabling us to
check whether the versions of LLVM used to generated the debug symbols match
across the RenderScript compiler frontend (llvm-rs-cc) and backend (bcc); if
they do not, we warn the user that the debugging experience may be suboptimal
as LLVM IR debug information has no compatibility guarantees.

llvm-svn: 290957
This commit is contained in:
Luke Drummond
2017-01-04 12:11:04 +00:00
parent 939b8cd708
commit 47d6416189
2 changed files with 53 additions and 1 deletions

View File

@@ -2854,6 +2854,11 @@ bool RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) {
module_desc.reset(new RSModuleDescriptor(module_sp));
if (module_desc->ParseRSInfo()) {
m_rsmodules.push_back(module_desc);
module_desc->WarnIfVersionMismatch(GetProcess()
->GetTarget()
.GetDebugger()
.GetAsyncOutputStream()
.get());
module_loaded = true;
}
if (module_loaded) {
@@ -2923,6 +2928,25 @@ void RenderScriptRuntime::Update() {
}
}
void RSModuleDescriptor::WarnIfVersionMismatch(lldb_private::Stream *s) const {
if (!s)
return;
if (m_slang_version.empty() || m_bcc_version.empty()) {
s->PutCString("WARNING: Unknown bcc or slang (llvm-rs-cc) version; debug "
"experience may be unreliable");
s->EOL();
} else if (m_slang_version != m_bcc_version) {
s->Printf("WARNING: The debug info emitted by the slang frontend "
"(llvm-rs-cc) used to build this module (%s) does not match the "
"version of bcc used to generate the debug information (%s). "
"This is an unsupported configuration and may result in a poor "
"debugging experience; proceed with caution",
m_slang_version.c_str(), m_bcc_version.c_str());
s->EOL();
}
}
bool RSModuleDescriptor::ParsePragmaCount(llvm::StringRef *lines,
size_t n_lines) {
// Skip the pragma prototype line
@@ -2990,6 +3014,22 @@ bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines,
return true;
}
bool RSModuleDescriptor::ParseVersionInfo(llvm::StringRef *lines,
size_t n_lines) {
// Skip the versionInfo line
++lines;
for (; n_lines--; ++lines) {
// We're only interested in bcc and slang versions, and ignore all other
// versionInfo lines
const auto kv_pair = lines->split(" - ");
if (kv_pair.first == "slang")
m_slang_version = kv_pair.second.str();
else if (kv_pair.first == "bcc")
m_bcc_version = kv_pair.second.str();
}
return true;
}
bool RSModuleDescriptor::ParseExportForeachCount(llvm::StringRef *lines,
size_t n_lines) {
// Skip the exportForeachCount line
@@ -3054,7 +3094,8 @@ bool RSModuleDescriptor::ParseRSInfo() {
eExportReduce,
ePragma,
eBuildChecksum,
eObjectSlot
eObjectSlot,
eVersionInfo,
};
const auto rs_info_handler = [](llvm::StringRef name) -> int {
@@ -3070,6 +3111,7 @@ bool RSModuleDescriptor::ParseRSInfo() {
// script
.Case("pragmaCount", ePragma)
.Case("objectSlotCount", eObjectSlot)
.Case("versionInfo", eVersionInfo)
.Default(-1);
};
@@ -3108,6 +3150,9 @@ bool RSModuleDescriptor::ParseRSInfo() {
case ePragma:
success = ParsePragmaCount(line, n_lines);
break;
case eVersionInfo:
success = ParseVersionInfo(line, n_lines);
break;
default: {
if (log)
log->Printf("%s - skipping .rs.info field '%s'", __FUNCTION__,