Author: spyffe Date: Mon Sep 26 15:18:51 2016 New Revision: 282434 URL: http://llvm.org/viewvc/llvm-project?rev=282434&view=rev Log: Added a setting that enables saving all .o files from a given JIT expression.
This allows debugging of the JIT and other analyses of the internals of the expression parser. I've also added a testcase that verifies that the setting works correctly when off and on. Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/ lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/Makefile lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/TestSaveJITObjects.py lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/main.c Modified: lldb/trunk/include/lldb/Expression/IRExecutionUnit.h lldb/trunk/include/lldb/Target/Target.h lldb/trunk/source/Expression/IRExecutionUnit.cpp lldb/trunk/source/Target/Target.cpp Modified: lldb/trunk/include/lldb/Expression/IRExecutionUnit.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRExecutionUnit.h?rev=282434&r1=282433&r2=282434&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRExecutionUnit.h (original) +++ lldb/trunk/include/lldb/Expression/IRExecutionUnit.h Mon Sep 26 15:18:51 2016 @@ -33,6 +33,7 @@ namespace llvm { class Module; class ExecutionEngine; +class ObjectCache; } // namespace llvm @@ -398,6 +399,7 @@ private: std::unique_ptr<llvm::LLVMContext> m_context_ap; std::unique_ptr<llvm::ExecutionEngine> m_execution_engine_ap; + std::unique_ptr<llvm::ObjectCache> m_object_cache_ap; std::unique_ptr<llvm::Module> m_module_ap; ///< Holder for the module until it's been handed off llvm::Module *m_module; ///< Owned by the execution engine Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=282434&r1=282433&r2=282434&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Mon Sep 26 15:18:51 2016 @@ -128,6 +128,8 @@ public: bool GetEnableNotifyAboutFixIts() const; + bool GetEnableSaveObjects() const; + bool GetEnableSyntheticValue() const; uint32_t GetMaximumNumberOfChildrenToDisplay() const; Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/Makefile?rev=282434&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/Makefile (added) +++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/Makefile Mon Sep 26 15:18:51 2016 @@ -0,0 +1,5 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/TestSaveJITObjects.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/TestSaveJITObjects.py?rev=282434&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/TestSaveJITObjects.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/TestSaveJITObjects.py Mon Sep 26 15:18:51 2016 @@ -0,0 +1,57 @@ +""" +Test that LLDB can emit JIT objects when the appropriate setting is enabled +""" + +from __future__ import print_function + +import os +import time +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +def enumerateJITFiles(): + return [f for f in os.listdir(os.getcwd()) if f.startswith("jit")] + +def countJITFiles(): + return len(enumerateJITFiles()) + +def cleanJITFiles(): + for j in enumerateJITFiles(): + os.remove(j) + return + +class SaveJITObjectsTestCase(TestBase): + mydir = TestBase.compute_mydir(__file__) + + def test_save_jit_objects(self): + self.build() + src_file = "main.c" + src_file_spec = lldb.SBFileSpec(src_file) + + exe_path = os.path.join(os.getcwd(), "a.out") + target = self.dbg.CreateTarget(exe_path) + + breakpoint = target.BreakpointCreateBySourceRegex( + "break", src_file_spec) + + process = target.LaunchSimple(None, None, + self.get_process_working_directory()) + + thread = process.GetSelectedThread() + frame = thread.GetSelectedFrame() + + cleanJITFiles() + frame.EvaluateExpression("(void*)malloc(0x1)") + self.assertTrue(countJITFiles() == 0, + "No files emitted with save-jit-objects=false") + + self.runCmd("settings set target.save-jit-objects true") + frame.EvaluateExpression("(void*)malloc(0x1)") + jit_files_count = countJITFiles() + cleanJITFiles() + self.assertTrue(jit_files_count != 0, + "At least one file emitted with save-jit-objects=true") + + process.Kill() Added: lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/main.c?rev=282434&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/main.c (added) +++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/save_jit_objects/main.c Mon Sep 26 15:18:51 2016 @@ -0,0 +1,14 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +int main (int argc, char const *argv[]) +{ + const char* foo = "Hello world"; // break here + return 0; +} Modified: lldb/trunk/source/Expression/IRExecutionUnit.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRExecutionUnit.cpp?rev=282434&r1=282433&r2=282434&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRExecutionUnit.cpp (original) +++ lldb/trunk/source/Expression/IRExecutionUnit.cpp Mon Sep 26 15:18:51 2016 @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" @@ -306,6 +307,32 @@ void IRExecutionUnit::GetRunnableInfo(Er return; } + class ObjectDumper : public llvm::ObjectCache { + public: + 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()); + } + + std::unique_ptr<llvm::MemoryBuffer> + getObject(const llvm::Module *module) override { + // Return nothing - we're just abusing the object-cache mechanism to dump + // objects. + return nullptr; + } + }; + + if (process_sp->GetTarget().GetEnableSaveObjects()) { + m_object_cache_ap = llvm::make_unique<ObjectDumper>(); + m_execution_engine_ap->setObjectCache(m_object_cache_ap.get()); + } + // Make sure we see all sections, including ones that don't have // relocations... m_execution_engine_ap->setProcessAllSections(true); Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=282434&r1=282433&r2=282434&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Mon Sep 26 15:18:51 2016 @@ -3246,6 +3246,8 @@ static PropertyDefinition g_properties[] nullptr, "Automatically apply fix-it hints to expressions."}, {"notify-about-fixits", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, "Print the fixed expression text."}, + {"save-jit-objects", OptionValue::eTypeBoolean, false, false, nullptr, + nullptr, "Save intermediate object files generated by the LLVM JIT"}, {"max-children-count", OptionValue::eTypeSInt64, false, 256, nullptr, nullptr, "Maximum number of children to expand in any level of depth."}, {"max-string-summary-length", OptionValue::eTypeSInt64, false, 1024, @@ -3370,6 +3372,7 @@ enum { ePropertyAutoImportClangModules, ePropertyAutoApplyFixIts, ePropertyNotifyAboutFixIts, + ePropertySaveObjects, ePropertyMaxChildrenCount, ePropertyMaxSummaryLength, ePropertyMaxMemReadSize, @@ -3787,6 +3790,12 @@ bool TargetProperties::GetEnableNotifyAb return m_collection_sp->GetPropertyAtIndexAsBoolean( nullptr, idx, g_properties[idx].default_uint_value != 0); } + +bool TargetProperties::GetEnableSaveObjects() const { + const uint32_t idx = ePropertySaveObjects; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} bool TargetProperties::GetEnableSyntheticValue() const { const uint32_t idx = ePropertyEnableSynthetic; _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits