You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
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:
@@ -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");
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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...);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
@@ -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:
|
||||
|
||||
@@ -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 (;;)
|
||||
|
||||
@@ -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;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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$"
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user