forked from OSchip/llvm-project
[libclang] Store unsaved file hashes when recording parsing invocations
Storing the contents of unsaved files is too expensive. Instead a hash is stored with a record invocation. When a reproducer is generated, Clang will compare the stored hashes to the new hashes to determine if the contents of a file has changed. This way we'll know when a reproducer was generated for a different source to the one that triggered the original crash. rdar://35322543 llvm-svn: 319729
This commit is contained in:
parent
276c770e57
commit
80b55ee62d
|
@ -0,0 +1,2 @@
|
|||
|
||||
#pragma clang __debug parser_crash
|
|
@ -14,8 +14,15 @@
|
|||
// RUN: env CINDEXTEST_INVOCATION_EMISSION_PATH=%t c-index-test -test-load-source all %s -DAVOID_CRASH
|
||||
// RUN: ls %t | count 0
|
||||
|
||||
// Make sure we record the unsaved file hash.
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir %t
|
||||
// RUN: not env CINDEXTEST_INVOCATION_EMISSION_PATH=%t c-index-test -test-load-source all "-remap-file=%s,%S/Inputs/record-parsing-invocation-remap.c" %s
|
||||
// RUN: cat %t/libclang-* | FileCheck --check-prefix=CHECK-UNSAVED %s
|
||||
|
||||
#ifndef AVOID_CRASH
|
||||
# pragma clang __debug parser_crash
|
||||
#endif
|
||||
|
||||
// CHECK: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"]}
|
||||
// CHECK-UNSAVED: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"unsaved_file_hashes":[{"name":"{{.*}}record-parsing-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]}
|
||||
|
|
|
@ -3438,10 +3438,9 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
|
|||
unsigned PrecompilePreambleAfterNParses =
|
||||
!PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;
|
||||
|
||||
// FIXME: Record the hash of the unsaved files.
|
||||
LibclangInvocationReporter InvocationReporter(
|
||||
*CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
|
||||
options, llvm::makeArrayRef(*Args));
|
||||
options, llvm::makeArrayRef(*Args), unsaved_files);
|
||||
std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
|
||||
Args->data(), Args->data() + Args->size(),
|
||||
CXXIdx->getPCHContainerOperations(), Diags,
|
||||
|
|
|
@ -12,11 +12,13 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CIndexer.h"
|
||||
#include "CXString.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/Version.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Config/llvm-config.h"
|
||||
#include "llvm/Support/MD5.h"
|
||||
#include "llvm/Support/MutexGuard.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/Program.h"
|
||||
|
@ -90,7 +92,8 @@ StringRef CIndexer::getClangToolchainPath() {
|
|||
|
||||
LibclangInvocationReporter::LibclangInvocationReporter(
|
||||
CIndexer &Idx, OperationKind Op, unsigned ParseOptions,
|
||||
llvm::ArrayRef<const char *> Args) {
|
||||
llvm::ArrayRef<const char *> Args,
|
||||
llvm::ArrayRef<CXUnsavedFile> UnsavedFiles) {
|
||||
StringRef Path = Idx.getInvocationEmissionPath();
|
||||
if (Path.empty())
|
||||
return;
|
||||
|
@ -124,6 +127,23 @@ LibclangInvocationReporter::LibclangInvocationReporter(
|
|||
OS << ',';
|
||||
OS << '"' << I.value() << '"';
|
||||
}
|
||||
if (!UnsavedFiles.empty()) {
|
||||
OS << R"(],"unsaved_file_hashes":[)";
|
||||
for (const auto &UF : llvm::enumerate(UnsavedFiles)) {
|
||||
if (UF.index())
|
||||
OS << ',';
|
||||
OS << '{';
|
||||
WriteStringKey("name", UF.value().Filename);
|
||||
OS << ',';
|
||||
llvm::MD5 Hash;
|
||||
Hash.update(getContents(UF.value()));
|
||||
llvm::MD5::MD5Result Result;
|
||||
Hash.final(Result);
|
||||
SmallString<32> Digest = Result.digest();
|
||||
WriteStringKey("md5", Digest);
|
||||
OS << '}';
|
||||
}
|
||||
}
|
||||
OS << "]}";
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,8 @@ public:
|
|||
|
||||
LibclangInvocationReporter(CIndexer &Idx, OperationKind Op,
|
||||
unsigned ParseOptions,
|
||||
llvm::ArrayRef<const char *> Args);
|
||||
llvm::ArrayRef<const char *> Args,
|
||||
llvm::ArrayRef<CXUnsavedFile> UnsavedFiles);
|
||||
~LibclangInvocationReporter();
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue