Merging //UE4/Dev-Main to Dev-Sequencer (//UE4/Dev-Sequencer)

#rb none

[CL 6643490 by Max Chen in Dev-Sequencer branch]
This commit is contained in:
Max Chen
2019-05-25 03:15:46 -04:00
parent 07e1eeadd5
commit 697a6f07ef
1812 changed files with 96339 additions and 32883 deletions

View File

@@ -7,8 +7,9 @@ public class LiveCodingServer : ModuleRules
{
public LiveCodingServer(ReadOnlyTargetRules Target) : base(Target)
{
PrivateDependencyModuleNames.Add("Core");
PrivateDependencyModuleNames.Add("LiveCoding");
PrivateDependencyModuleNames.Add("Core");
PrivateDependencyModuleNames.Add("Json");
PrivateDependencyModuleNames.Add("LiveCoding");
AddEngineThirdPartyPrivateStaticDependencies(Target, "Distorm");

View File

@@ -1,16 +1,14 @@
// Copyright 2011-2019 Molecular Matters GmbH, all rights reserved.
#include "LC_CodeCave.h"
#include "LC_VirtualMemory.h"
#include "LC_Patch.h"
#include "LC_Thread.h"
CodeCave::CodeCave(process::Handle processHandle, unsigned int processId, unsigned int commandThreadId)
CodeCave::CodeCave(process::Handle processHandle, unsigned int processId, unsigned int commandThreadId, const void* jumpToSelf)
: m_processHandle(processHandle)
, m_processId(processId)
, m_commandThreadId(commandThreadId)
, m_cave(nullptr)
, m_jumpToSelf(jumpToSelf)
, m_perThreadData()
{
m_perThreadData.reserve(128u);
@@ -21,11 +19,6 @@ void CodeCave::Install(void)
{
process::Suspend(m_processHandle);
// prepare jump-to-self code cave
const uint32_t pageSize = virtualMemory::GetPageSize();
m_cave = virtualMemory::Allocate(m_processHandle, pageSize, virtualMemory::PageType::EXECUTE_READ_WRITE);
patch::InstallJumpToSelf(m_processHandle, m_cave);
// enumerate all threads of the process now that it's suspended
const std::vector<unsigned int>& threadIds = process::EnumerateThreads(m_processId);
@@ -52,7 +45,7 @@ void CodeCave::Install(void)
m_perThreadData[i].priority = thread::GetPriority(threadHandle);
m_perThreadData[i].originalIp = thread::ReadInstructionPointer(context);
thread::SetPriority(threadHandle, THREAD_PRIORITY_IDLE);
thread::WriteInstructionPointer(context, m_cave);
thread::WriteInstructionPointer(context, m_jumpToSelf);
thread::SetContext(threadHandle, context);
thread::Close(threadHandle);
}
@@ -84,7 +77,7 @@ void CodeCave::Uninstall(void)
// only set the original instruction pointer if the thread is really being held in the cave.
// in certain situations (e.g. after an exception), the debugger/OS already restored the context
// of all threads, and it would be fatal to interfere with this.
if (currentIp == m_cave)
if (currentIp == m_jumpToSelf)
{
thread::SetPriority(threadHandle, m_perThreadData[i].priority);
thread::WriteInstructionPointer(context, m_perThreadData[i].originalIp);
@@ -93,8 +86,5 @@ void CodeCave::Uninstall(void)
thread::Close(threadHandle);
}
// get rid of the code cave
virtualMemory::Free(m_processHandle, m_cave);
process::Resume(m_processHandle);
}

View File

@@ -10,7 +10,8 @@
class CodeCave
{
public:
CodeCave(process::Handle processHandle, unsigned int processId, unsigned int commandThreadId);
// the jump-to-self code needs to be available in the address space of the given process
CodeCave(process::Handle processHandle, unsigned int processId, unsigned int commandThreadId, const void* jumpToSelf);
void Install(void);
void Uninstall(void);
@@ -19,8 +20,7 @@ private:
process::Handle m_processHandle;
unsigned int m_processId;
unsigned int m_commandThreadId;
void* m_cave;
const void* m_jumpToSelf;
struct PerThreadData
{

View File

@@ -7,7 +7,7 @@
#include "LC_FileUtil.h"
#include "LC_SymbolPatterns.h"
#include "LC_Symbols.h"
#include "LC_MemoryBlock.h"
#include "LC_MemoryStream.h"
#include "LC_UniqueId.h"
#include "LC_Allocators.h"
#include <algorithm>
@@ -631,7 +631,7 @@ namespace coff
// keeping the section data, relocations, and line numbers at the end of the file makes it easier to keep track
// of file offsets that are stored in the section headers.
MemoryBlock outputData(static_cast<size_t>(rawCoff->size));
memoryStream::Writer outputData(static_cast<size_t>(rawCoff->size));
CoffHeader coffHeader(rawCoff->header);
// careful: the number of sections is of type WORD, but DWORD in files compiled with /bigobj!
@@ -641,7 +641,7 @@ namespace coff
coffHeader.NumberOfSymbols = static_cast<DWORD>(rawCoff->symbols.size());
coffHeader.PointerToSymbolTable = static_cast<DWORD>(sizeof(CoffHeader) + rawCoff->sections.size() * sizeof(IMAGE_SECTION_HEADER));
outputData.Insert(coffHeader);
outputData.Write(coffHeader);
const size_t baseOffset =
sizeof(CoffHeader) +
rawCoff->sections.size() * sizeof(IMAGE_SECTION_HEADER) +
@@ -697,22 +697,22 @@ namespace coff
}
sectionHeader.NumberOfLinenumbers = static_cast<WORD>(section.lineNumbers.size());
outputData.Insert(sectionHeader);
outputData.Write(sectionHeader);
}
for (size_t i = 0u; i < rawCoff->symbols.size(); ++i)
{
outputData.Insert(rawCoff->symbols[i]);
outputData.Write(rawCoff->symbols[i]);
}
outputData.Insert(rawCoff->rawStringTable.data, rawCoff->rawStringTable.size);
outputData.Write(rawCoff->rawStringTable.data, rawCoff->rawStringTable.size);
for (size_t i = 0u; i < rawCoff->sections.size(); ++i)
{
const RawSection& section = rawCoff->sections[i];
if (section.header.PointerToRawData != 0u)
{
outputData.Insert(section.data, section.header.SizeOfRawData);
outputData.Write(section.data, section.header.SizeOfRawData);
}
const size_t relocationCount = section.relocations.size();
@@ -722,7 +722,7 @@ namespace coff
// the actual number of relocations.
IMAGE_RELOCATION dummyRelocation = {};
dummyRelocation.RelocCount = static_cast<DWORD>(relocationCount);
outputData.Insert(dummyRelocation);
outputData.Write(dummyRelocation);
}
if (removalStrategy == SymbolRemovalStrategy::Enum::MSVC_COMPATIBLE)
@@ -730,7 +730,7 @@ namespace coff
for (size_t j = 0u; j < relocationCount; ++j)
{
const IMAGE_RELOCATION& relocation = section.relocations[j];
outputData.Insert(relocation);
outputData.Write(relocation);
}
}
else if (removalStrategy == SymbolRemovalStrategy::Enum::LLD_COMPATIBLE)
@@ -756,13 +756,13 @@ namespace coff
}
}
outputData.Insert(relocation);
outputData.Write(relocation);
}
}
for (size_t j = 0u; j < section.lineNumbers.size(); ++j)
{
outputData.Insert(section.lineNumbers[j]);
outputData.Write(section.lineNumbers[j]);
}
}

View File

@@ -1,7 +1,6 @@
// Copyright 2011-2019 Molecular Matters GmbH, all rights reserved.
#include "LC_Hook.h"
#include "LC_PointerUtil.h"
#include "LC_Symbols.h"
@@ -27,9 +26,3 @@ uint32_t hook::FindLastInSection(const symbols::ImageSectionDB* imageSectionDb,
return 0u;
}
const hook::Function* hook::MakeFunction(const void* moduleBase, uint32_t rva)
{
return pointer::Offset<const hook::Function*>(moduleBase, rva);
}

View File

@@ -15,10 +15,46 @@ namespace symbols
namespace hook
{
typedef void (*Function)(void);
struct Type
{
enum Enum
{
PREPATCH = 0,
POSTPATCH,
COMPILE_START,
COMPILE_SUCCESS,
COMPILE_ERROR,
COMPILE_ERROR_MESSAGE
};
};
typedef void (*PrepatchFunction)(void);
typedef void (*PostpatchFunction)(void);
typedef void (*CompileStartFunction)(void);
typedef void (*CompileSuccessFunction)(void);
typedef void (*CompileErrorFunction)(void);
typedef void (*CompileErrorMessageFunction)(const wchar_t*);
uint32_t FindFirstInSection(const symbols::ImageSectionDB* imageSectionDb, const ImmutableString& sectionName);
uint32_t FindLastInSection(const symbols::ImageSectionDB* imageSectionDb, const ImmutableString& sectionName);
const Function* MakeFunction(const void* moduleBase, uint32_t rva);
// calls arbitrary hooks in a given range
template <typename T, typename... Args>
void CallHooksInRange(const void* rangeBegin, const void* rangeEnd, Args&&... args)
{
const T* firstHook = static_cast<const T*>(rangeBegin);
const T* lastHook = static_cast<const T*>(rangeEnd);
for (const T* hook = firstHook; hook < lastHook; ++hook)
{
// note that sections are often padded with zeroes, so skip everything that's zero
T function = *hook;
if (function)
{
function(args...);
}
}
}
}

View File

@@ -99,12 +99,21 @@ private:
void OnCompiledFile(const symbols::ObjPath& objPath, symbols::Compiland* compiland, const CompileResult& compileResult, double compileTime, bool forceAmalgamationPartsLinkage);
// actions
struct LoadPatchInfoAction
struct actions
{
typedef commands::LoadPatchInfo CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
#define DECLARE_ACTION(_name) \
struct _name \
{ \
typedef ::commands::_name CommandType; \
static bool Execute(const CommandType* command, const DuplexPipe* pipe, void* context, const void* payload, size_t payloadSize); \
}
DECLARE_ACTION(LoadPatchInfo);
#undef DECLARE_ACTION
};
std::wstring m_moduleName;
executable::Header m_imageHeader;
RunMode::Enum m_runMode;
@@ -140,4 +149,8 @@ private:
// all patches loaded so far along with recorded data how to load them into other processes
types::vector<ModulePatch*> m_compiledModulePatches;
// BEGIN EPIC MOD - Allow mapping from object files to their unity object file
types::StringMap<uint32_t> m_objFileToCompilandId;
// END EPIC MOD
};

View File

@@ -5,10 +5,11 @@
#include "LC_CodeCave.h"
LiveProcess::LiveProcess(process::Handle processHandle, unsigned int processId, unsigned int commandThreadId, const DuplexPipe* pipe)
LiveProcess::LiveProcess(process::Handle processHandle, unsigned int processId, unsigned int commandThreadId, const void* jumpToSelf, const DuplexPipe* pipe)
: m_processHandle(processHandle)
, m_processId(processId)
, m_commandThreadId(commandThreadId)
, m_jumpToSelf(jumpToSelf)
, m_pipe(pipe)
, m_imagesTriedToLoad()
, m_heartBeatDelta(0ull)
@@ -41,7 +42,7 @@ bool LiveProcess::MadeProgress(void) const
void LiveProcess::InstallCodeCave(void)
{
m_codeCave = new CodeCave(m_processHandle, m_processId, m_commandThreadId);
m_codeCave = new CodeCave(m_processHandle, m_processId, m_commandThreadId, m_jumpToSelf);
m_codeCave->Install();
}

View File

@@ -14,7 +14,7 @@ class CodeCave;
class LiveProcess
{
public:
LiveProcess(process::Handle processHandle, unsigned int processId, unsigned int commandThreadId, const DuplexPipe* pipe);
LiveProcess(process::Handle processHandle, unsigned int processId, unsigned int commandThreadId, const void* jumpToSelf, const DuplexPipe* pipe);
void ReadHeartBeatDelta(const wchar_t* const processGroupName);
@@ -47,6 +47,11 @@ public:
return m_commandThreadId;
}
inline const void* GetJumpToSelf(void) const
{
return m_jumpToSelf;
}
inline const DuplexPipe* GetPipe(void) const
{
return m_pipe;
@@ -75,6 +80,7 @@ private:
process::Handle m_processHandle;
unsigned int m_processId;
unsigned int m_commandThreadId;
const void* m_jumpToSelf;
const DuplexPipe* m_pipe;
// BEGIN EPIC MOD - Add build arguments

View File

@@ -1,28 +0,0 @@
// Copyright 2011-2019 Molecular Matters GmbH, all rights reserved.
#include "LC_MemoryBlock.h"
#include "LC_Logging.h"
#include "Windows/WindowsHWrapper.h"
MemoryBlock::MemoryBlock(size_t capacity)
: m_capacity(capacity)
, m_size(0u)
, m_data(new uint8_t[capacity])
{
}
MemoryBlock::~MemoryBlock(void)
{
delete[] m_data;
}
void MemoryBlock::Insert(const void* data, size_t size)
{
LC_ASSERT(m_size + size <= m_capacity, "Not enough space to insert data.");
memcpy(m_data + m_size, data, size);
m_size += size;
}

View File

@@ -1,43 +0,0 @@
// Copyright 2011-2019 Molecular Matters GmbH, all rights reserved.
#pragma once
#include "CoreTypes.h"
#include "LC_Platform.h"
#include <stdint.h>
class MemoryBlock
{
public:
explicit MemoryBlock(size_t capacity);
~MemoryBlock(void);
void Insert(const void* data, size_t size);
template <typename T>
inline void Insert(const T& data)
{
Insert(&data, sizeof(T));
}
inline const void* GetData(void) const
{
return m_data;
}
inline size_t GetSize(void) const
{
return m_size;
}
private:
size_t m_capacity;
size_t m_size;
uint8_t* m_data;
LC_DISABLE_COPY(MemoryBlock);
LC_DISABLE_MOVE(MemoryBlock);
LC_DISABLE_ASSIGNMENT(MemoryBlock);
LC_DISABLE_MOVE_ASSIGNMENT(MemoryBlock);
};

View File

@@ -16,7 +16,9 @@ namespace scheduler
// simple multi-producer, multi-consumer queue
class TaskQueue
{
static const unsigned int TASK_COUNT = 1024u;
// BEGIN EPIC MOD - Increasing task count due to hangs when enabling for all editor modules
static const unsigned int TASK_COUNT = 4096u;// 1024u;
// END EPIC MOD
static const unsigned int ACCESS_MASK = TASK_COUNT - 1u;
public:

View File

@@ -5,24 +5,10 @@
#include "LC_SchedulerTask.h"
namespace
{
struct ThreadContext
{
scheduler::WorkerThread* instance;
scheduler::TaskQueue* queue;
};
}
scheduler::WorkerThread::WorkerThread(TaskQueue* queue)
: m_thread()
{
ThreadContext* context = new ThreadContext;
context->instance = this;
context->queue = queue;
m_thread = thread::Create(128u * 1024u, &ThreadProxy, context);
m_thread = thread::Create("Live coding worker", 128u * 1024u, &scheduler::WorkerThread::ThreadFunction, this, queue);
}
@@ -32,19 +18,6 @@ scheduler::WorkerThread::~WorkerThread(void)
}
unsigned int __stdcall scheduler::WorkerThread::ThreadProxy(void* context)
{
thread::SetName("Live coding worker");
ThreadContext* realContext = static_cast<ThreadContext*>(context);
const unsigned int exitCode = realContext->instance->ThreadFunction(realContext->queue);
delete realContext;
return exitCode;
}
unsigned int scheduler::WorkerThread::ThreadFunction(TaskQueue* queue)
{
for (;;)

View File

@@ -18,7 +18,6 @@ namespace scheduler
~WorkerThread(void);
private:
static unsigned int __stdcall ThreadProxy(void* context);
unsigned int ThreadFunction(TaskQueue* queue);
thread::Handle m_thread;

View File

@@ -29,31 +29,17 @@ public:
std::wstring GetProcessImagePath(void) const;
struct TaskContext
{
scheduler::TaskBase* taskRoot;
types::vector<scheduler::Task<LiveModule*>*> tasks;
};
private:
void LoadModule(const wchar_t* modulePath, const DuplexPipe* pipe, TaskContext* tasks, unsigned int processId);
void LoadAllModules(const wchar_t* modulePath, const DuplexPipe* pipe, TaskContext* tasks, unsigned int processId);
void UnloadModule(const wchar_t* modulePath, const DuplexPipe* pipe, unsigned int processId);
void UnloadAllModules(const wchar_t* modulePath, const DuplexPipe* pipe, unsigned int processId);
scheduler::Task<LiveModule*>* LoadModule(unsigned int processId, void* moduleBase, const wchar_t* modulePath, scheduler::TaskBase* taskRoot);
bool UnloadModule(unsigned int processId, const wchar_t* modulePath);
void PrewarmCompilerEnvironmentCache(void);
static unsigned int __stdcall ServerThreadProxy(void* context);
unsigned int ServerThread(void);
static unsigned int __stdcall CompileThreadProxy(void* context);
unsigned int CompileThread(void);
struct CommandThreadContext
{
ServerCommandThread* instance;
DuplexPipeServer pipe;
Event* readyEvent;
thread::Handle commandThread;
@@ -62,10 +48,7 @@ private:
thread::Handle exceptionCommandThread;
};
static unsigned int __stdcall CommandThreadProxy(void* context);
unsigned int CommandThread(DuplexPipeServer* pipe, Event* readyEvent);
static unsigned int __stdcall ExceptionCommandThreadProxy(void* context);
unsigned int ExceptionCommandThread(DuplexPipeServer* exceptionPipe);
void RemoveCommandThread(const DuplexPipe* pipe);
@@ -74,159 +57,53 @@ private:
void CompileChanges(bool didAllProcessesMakeProgress);
// actions
struct TriggerRecompileAction
struct actions
{
typedef commands::TriggerRecompile CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
#define DECLARE_ACTION(_name) \
struct _name \
{ \
typedef ::commands::_name CommandType; \
static bool Execute(const CommandType* command, const DuplexPipe* pipe, void* context, const void* payload, size_t payloadSize); \
}
struct BuildPatchAction
{
typedef commands::BuildPatch CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
DECLARE_ACTION(TriggerRecompile);
DECLARE_ACTION(BuildPatch);
DECLARE_ACTION(HandleException);
DECLARE_ACTION(ReadyForCompilation);
DECLARE_ACTION(DisconnectClient);
DECLARE_ACTION(RegisterProcess);
struct HandleExceptionAction
{
typedef commands::HandleException CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
DECLARE_ACTION(EnableModules);
DECLARE_ACTION(DisableModules);
struct ReadyForCompilationAction
{
typedef commands::ReadyForCompilation CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
DECLARE_ACTION(ApplySettingBool);
DECLARE_ACTION(ApplySettingInt);
DECLARE_ACTION(ApplySettingString);
struct DisconnectClientAction
{
typedef commands::DisconnectClient CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
// BEGIN EPIC MOD - Adding ShowConsole command
DECLARE_ACTION(ShowConsole);
// END EPIC MOD
// BEGIN EPIC MOD - Adding ShowConsole command
struct ShowConsoleAction
{
typedef commands::ShowConsole CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
// END EPIC MOD
// BEGIN EPIC MOD - Adding ShowConsole command
DECLARE_ACTION(SetVisible);
// END EPIC MOD
// BEGIN EPIC MOD - Adding ShowConsole command
struct SetVisibleAction
{
typedef commands::SetVisible CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
// END EPIC MOD
// BEGIN EPIC MOD - Adding SetActive command
DECLARE_ACTION(SetActive);
// END EPIC MOD
// BEGIN EPIC MOD - Adding SetActive command
struct SetActiveAction
{
typedef commands::SetActive CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
// END EPIC MOD
// BEGIN EPIC MOD - Adding SetBuildArguments command
DECLARE_ACTION(SetBuildArguments);
// END EPIC MOD
// BEGIN EPIC MOD - Adding SetBuildArguments command
struct SetBuildArgumentsAction
{
typedef commands::SetBuildArguments CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
// END EPIC MOD
// BEGIN EPIC MOD - Adding support for lazy-loading modules
DECLARE_ACTION(EnableLazyLoadedModule);
DECLARE_ACTION(FinishedLazyLoadingModules);
// END EPIC MOD
// BEGIN EPIC MOD - Adding support for lazy-loading modules
struct EnableLazyLoadedModuleAction
{
typedef commands::EnableLazyLoadedModule CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct FinishedLazyLoadingModulesAction
{
typedef commands::FinishedLazyLoadingModules CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
// END EPIC MOD
struct RegisterProcessAction
{
typedef commands::RegisterProcess CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct EnableModuleBatchBeginAction
{
typedef commands::EnableModuleBatchBegin CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct EnableModuleBatchEndAction
{
typedef commands::EnableModuleBatchEnd CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct DisableModuleBatchBeginAction
{
typedef commands::DisableModuleBatchBegin CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct DisableModuleBatchEndAction
{
typedef commands::DisableModuleBatchEnd CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct EnableModuleAction
{
typedef commands::EnableModule CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct EnableAllModulesAction
{
typedef commands::EnableAllModules CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct DisableModuleAction
{
typedef commands::DisableModule CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct DisableAllModulesAction
{
typedef commands::DisableAllModules CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct GetModuleInfoAction
{
typedef commands::GetModuleInfo CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct ApplySettingBoolAction
{
typedef commands::ApplySettingBool CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct ApplySettingIntAction
{
typedef commands::ApplySettingInt CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
};
struct ApplySettingStringAction
{
typedef commands::ApplySettingString CommandType;
static bool Execute(CommandType* command, const DuplexPipe* pipe, void* context);
#undef DECLARE_ACTION
};
@@ -253,9 +130,6 @@ private:
CriticalSection m_connectionCS;
types::vector<CommandThreadContext*> m_commandThreads;
telemetry::Scope m_moduleBatchScope;
size_t m_loadedCompilandCountInBatchScope;
// BEGIN EPIC MOD - Adding SetActive command
bool m_active = true;
// END EPIC MOD

View File

@@ -151,6 +151,15 @@ namespace symbolPatterns
#endif
};
extern const char* const EXCEPTION_UNWIND_PATTERNS[1] =
{
#if LC_64_BIT
"?dtor$",
#else
"__unwindfunclet$",
#endif
};
extern const char* const EXCEPTION_CLAUSE_PATTERNS[1] =
{
"__catch$"

View File

@@ -24,6 +24,7 @@ namespace symbolPatterns
#else
extern const char* const EXCEPTION_RELATED_PATTERNS[10];
#endif
extern const char* const EXCEPTION_UNWIND_PATTERNS[1];
extern const char* const EXCEPTION_CLAUSE_PATTERNS[1];

View File

@@ -301,7 +301,9 @@ namespace
return nullptr;
}
symbols::Provider* provider = new symbols::Provider { diaDataSource, diaSession, globalScope };
const file::Attributes& attributes = file::GetAttributes(filename);
const uint64_t lastModification = file::GetLastModificationTime(attributes);
symbols::Provider* provider = new symbols::Provider { diaDataSource, diaSession, globalScope, lastModification };
return provider;
}
@@ -613,7 +615,7 @@ namespace symbols
}
CompilandDB* GatherCompilands(Provider* provider, const DiaCompilandDB* diaCompilandDb, unsigned int splitAmalgamatedFilesThreshold, uint32_t compilandOptions)
CompilandDB* GatherCompilands(const Provider* provider, const DiaCompilandDB* diaCompilandDb, unsigned int splitAmalgamatedFilesThreshold, uint32_t compilandOptions)
{
telemetry::Scope telemetryScope("Gathering compilands");
@@ -840,6 +842,14 @@ namespace symbols
compilandPath = testPath;
}
// ignore compilands that are newer than the module itself.
// we cannot use those for reconstructing symbol information, because they weren't linked into the executable.
if (cacheData.lastModificationTime > provider->lastModificationTime)
{
LC_WARNING_USER("Ignoring compiland %S because it is newer than the module it belongs to.", compilandPath.c_str());
continue;
}
}
const std::wstring normalizedCompilandPath = file::NormalizePath(compilandPath.c_str());
@@ -2207,6 +2217,13 @@ namespace symbols
}
bool IsExceptionUnwindSymbolForDynamicInitializer(const ImmutableString& symbolName)
{
return (StartsWithPatterns(symbolName.c_str(), symbolPatterns::EXCEPTION_UNWIND_PATTERNS) &&
ContainsPatterns(symbolName.c_str(), symbolPatterns::DYNAMIC_INITIALIZER_PATTERNS));
}
bool IsRuntimeCheckRelatedSymbol(const ImmutableString& symbolName)
{
return ContainsPatterns(symbolName.c_str(), symbolPatterns::RTC_PATTERNS);

Some files were not shown because too many files have changed in this diff Show More