Change "target.save-jit-objects" to "target.save-jit-objects-dir".

The old command wrote to CWD, which doesn't always work, and if it
didn't, there was no workaround (and it crashed on failure).  This
patch changed the setting to provide a directory to save the objects
to.

Differential Revision: https://reviews.llvm.org/D121036
This commit is contained in:
Jim Ingham 2022-03-07 16:38:52 -08:00
parent a7adf7b9e9
commit 94ec0b6c5a
6 changed files with 70 additions and 22 deletions

View File

@ -311,7 +311,6 @@ public:
lldb::OptionValueSP GetParent() const { return m_parent_wp.lock(); }
void SetValueChangedCallback(std::function<void()> callback) {
assert(!m_callback);
m_callback = std::move(callback);
}

View File

@ -158,8 +158,8 @@ public:
bool GetEnableNotifyAboutFixIts() const;
bool GetEnableSaveObjects() const;
FileSpec GetSaveJITObjectsDir() const;
bool GetEnableSyntheticValue() const;
uint32_t GetMaxZeroPaddingInFloatFormat() const;
@ -248,6 +248,9 @@ private:
void DisableASLRValueChangedCallback();
void InheritTCCValueChangedCallback();
void DisableSTDIOValueChangedCallback();
// Settings checker for target.jit-save-objects-dir:
void CheckJITObjectsDir();
Environment ComputeEnvironment() const;

View File

@ -21,6 +21,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
@ -306,27 +307,37 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr,
class ObjectDumper : public llvm::ObjectCache {
public:
ObjectDumper(FileSpec output_dir) : m_out_dir(output_dir) {}
void notifyObjectCompiled(const llvm::Module *module,
llvm::MemoryBufferRef object) override {
int fd = 0;
llvm::SmallVector<char, 256> result_path;
std::string object_name_model =
"jit-object-" + module->getModuleIdentifier() + "-%%%.o";
(void)llvm::sys::fs::createUniqueFile(object_name_model, fd, result_path);
llvm::raw_fd_ostream fds(fd, true);
fds.write(object.getBufferStart(), object.getBufferSize());
}
FileSpec model_spec
= m_out_dir.CopyByAppendingPathComponent(object_name_model);
std::string model_path = model_spec.GetPath();
std::error_code result
= llvm::sys::fs::createUniqueFile(model_path, fd, result_path);
if (!result) {
llvm::raw_fd_ostream fds(fd, true);
fds.write(object.getBufferStart(), object.getBufferSize());
}
}
std::unique_ptr<llvm::MemoryBuffer>
getObject(const llvm::Module *module) override {
getObject(const llvm::Module *module) override {
// Return nothing - we're just abusing the object-cache mechanism to dump
// objects.
return nullptr;
}
}
private:
FileSpec m_out_dir;
};
if (process_sp->GetTarget().GetEnableSaveObjects()) {
m_object_cache_up = std::make_unique<ObjectDumper>();
FileSpec save_objects_dir = process_sp->GetTarget().GetSaveJITObjectsDir();
if (save_objects_dir) {
m_object_cache_up = std::make_unique<ObjectDumper>(save_objects_dir);
m_execution_engine_up->setObjectCache(m_object_cache_up.get());
}

View File

@ -3814,6 +3814,8 @@ TargetProperties::TargetProperties(Target *target)
m_collection_sp->SetValueChangedCallback(
ePropertyDisableSTDIO, [this] { DisableSTDIOValueChangedCallback(); });
m_collection_sp->SetValueChangedCallback(
ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); });
m_experimental_properties_up =
std::make_unique<TargetExperimentalProperties>();
m_collection_sp->AppendProperty(
@ -3835,6 +3837,8 @@ TargetProperties::TargetProperties(Target *target)
m_collection_sp->AppendProperty(
ConstString("process"), ConstString("Settings specific to processes."),
true, Process::GetGlobalProperties().GetValueProperties());
m_collection_sp->SetValueChangedCallback(
ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); });
}
}
@ -4164,10 +4168,41 @@ bool TargetProperties::GetEnableNotifyAboutFixIts() const {
nullptr, idx, g_target_properties[idx].default_uint_value != 0);
}
bool TargetProperties::GetEnableSaveObjects() const {
const uint32_t idx = ePropertySaveObjects;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
nullptr, idx, g_target_properties[idx].default_uint_value != 0);
FileSpec TargetProperties::GetSaveJITObjectsDir() const {
const uint32_t idx = ePropertySaveObjectsDir;
return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx);
}
void TargetProperties::CheckJITObjectsDir() {
const uint32_t idx = ePropertySaveObjectsDir;
FileSpec new_dir = GetSaveJITObjectsDir();
const FileSystem &instance = FileSystem::Instance();
bool exists = instance.Exists(new_dir);
bool is_directory = instance.IsDirectory(new_dir);
std::string path = new_dir.GetPath(true);
bool writable = llvm::sys::fs::can_write(path);
if (exists && is_directory && writable)
return;
m_collection_sp->GetPropertyAtIndex(nullptr, true, idx)->GetValue()
->Clear();
StreamSP error_strm_sp;
if (m_target) {
// FIXME: How can I warn the user when setting this on the Debugger?
error_strm_sp = m_target->GetDebugger().GetAsyncErrorStream();
} else if (Debugger::GetNumDebuggers() == 1) {
error_strm_sp = Debugger::GetDebuggerAtIndex(0)->GetAsyncErrorStream();
}
if (error_strm_sp) {
error_strm_sp->Format("JIT object dir '{0}' ", path);
if (!exists)
error_strm_sp->PutCString("does not exist.");
else if (!is_directory)
error_strm_sp->PutCString("is not a directory.");
else if (!writable)
error_strm_sp->PutCString("is not writable.");
error_strm_sp->EOL();
error_strm_sp->Flush();
}
}
bool TargetProperties::GetEnableSyntheticValue() const {

View File

@ -63,9 +63,9 @@ let Definition = "target" in {
def NotifyAboutFixIts: Property<"notify-about-fixits", "Boolean">,
DefaultTrue,
Desc<"Print the fixed expression text.">;
def SaveObjects: Property<"save-jit-objects", "Boolean">,
DefaultFalse,
Desc<"Save intermediate object files generated by the LLVM JIT">;
def SaveObjectsDir: Property<"save-jit-objects-dir", "FileSpec">,
DefaultStringValue<"">,
Desc<"If specified, the directory to save intermediate object files generated by the LLVM JIT">;
def MaxZeroPaddingInFloatFormat: Property<"max-zero-padding-in-float-format", "UInt64">,
DefaultUnsignedValue<6>,
Desc<"The maximum number of zeroes to insert when displaying a very small float before falling back to scientific notation.">;

View File

@ -38,14 +38,14 @@ class SaveJITObjectsTestCase(TestBase):
self.cleanJITFiles()
frame.EvaluateExpression("(void*)malloc(0x1)")
self.assertEquals(self.countJITFiles(), 0,
"No files emitted with save-jit-objects=false")
self.runCmd("settings set target.save-jit-objects true")
"No files emitted with save-jit-objects-dir empty")
self.runCmd("settings set target.save-jit-objects-dir {0}".format(self.getBuildDir()))
frame.EvaluateExpression("(void*)malloc(0x1)")
jit_files_count = self.countJITFiles()
self.cleanJITFiles()
self.assertNotEqual(jit_files_count, 0,
"At least one file emitted with save-jit-objects=true")
"At least one file emitted with save-jit-objects-dir set to the build dir")
process.Kill()
os.chdir(self.getSourceDir())