summaryrefslogtreecommitdiffstats
path: root/lldb/source/Expression/ClangExpressionParser.cpp
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2014-03-24 23:10:19 +0000
committerGreg Clayton <gclayton@apple.com>2014-03-24 23:10:19 +0000
commit23f8c95a4439767cf9c7dc9d7a35eb55dc78b9d0 (patch)
tree3e56f285be57acf15b3fb73195567727a329aca9 /lldb/source/Expression/ClangExpressionParser.cpp
parent2256d0dcedf887593ebfb35db860827e8682807e (diff)
downloadbcm5719-llvm-23f8c95a4439767cf9c7dc9d7a35eb55dc78b9d0.tar.gz
bcm5719-llvm-23f8c95a4439767cf9c7dc9d7a35eb55dc78b9d0.zip
JITed functions can now have debug info and be debugged with debug and source info:
(lldb) b puts (lldb) expr -g -i0 -- (int)puts("hello") First we will stop at the entry point of the expression before it runs, then we can step over a few times and hit the breakpoint in "puts", then we can continue and finishing stepping and fininsh the expression. Main features: - New ObjectFileJIT class that can be easily created for JIT functions - debug info can now be enabled when parsing expressions - source for any function that is run throught the JIT is now saved in LLDB process specific temp directory and cleaned up on exit - "expr -g --" allows you to single step through your expression function with source code <rdar://problem/16382881> llvm-svn: 204682
Diffstat (limited to 'lldb/source/Expression/ClangExpressionParser.cpp')
-rw-r--r--lldb/source/Expression/ClangExpressionParser.cpp98
1 files changed, 75 insertions, 23 deletions
diff --git a/lldb/source/Expression/ClangExpressionParser.cpp b/lldb/source/Expression/ClangExpressionParser.cpp
index ea3ff95f578..44f1e535ec7 100644
--- a/lldb/source/Expression/ClangExpressionParser.cpp
+++ b/lldb/source/Expression/ClangExpressionParser.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
@@ -24,6 +25,8 @@
#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRDynamicChecks.h"
#include "lldb/Expression/IRInterpreter.h"
+#include "lldb/Host/File.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
@@ -93,7 +96,8 @@ std::string GetBuiltinIncludePath(const char *Argv0) {
//===----------------------------------------------------------------------===//
ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
- ClangExpression &expr) :
+ ClangExpression &expr,
+ bool generate_debug_info) :
m_expr (expr),
m_compiler (),
m_code_generator ()
@@ -228,6 +232,10 @@ ClangExpressionParser::ClangExpressionParser (ExecutionContextScope *exe_scope,
m_compiler->getCodeGenOpts().InstrumentFunctions = false;
m_compiler->getCodeGenOpts().DisableFPElim = true;
m_compiler->getCodeGenOpts().OmitLeafFramePointer = false;
+ if (generate_debug_info)
+ m_compiler->getCodeGenOpts().setDebugInfo(CodeGenOptions::FullDebugInfo);
+ else
+ m_compiler->getCodeGenOpts().setDebugInfo(CodeGenOptions::NoDebugInfo);
// Disable some warnings.
m_compiler->getDiagnostics().setDiagnosticGroupMapping("unused-value", clang::diag::MAP_IGNORE, SourceLocation());
@@ -299,8 +307,48 @@ ClangExpressionParser::Parse (Stream &stream)
diag_buf->FlushDiagnostics (m_compiler->getDiagnostics());
- MemoryBuffer *memory_buffer = MemoryBuffer::getMemBufferCopy(m_expr.Text(), __FUNCTION__);
- m_compiler->getSourceManager().createMainFileIDForMemBuffer (memory_buffer);
+ const char *expr_text = m_expr.Text();
+
+ bool created_main_file = false;
+ if (m_compiler->getCodeGenOpts().getDebugInfo() == CodeGenOptions::FullDebugInfo)
+ {
+ std::string temp_source_path;
+
+ FileSpec tmpdir_file_spec;
+ if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
+ {
+ tmpdir_file_spec.GetFilename().SetCString("expr.XXXXXX");
+ temp_source_path = std::move(tmpdir_file_spec.GetPath());
+ }
+ else
+ {
+ temp_source_path = "/tmp/expr.XXXXXX";
+ }
+
+ if (mktemp(&temp_source_path[0]))
+ {
+ lldb_private::File file (temp_source_path.c_str(),
+ File::eOpenOptionWrite | File::eOpenOptionCanCreateNewOnly,
+ lldb::eFilePermissionsFileDefault);
+ const size_t expr_text_len = strlen(expr_text);
+ size_t bytes_written = expr_text_len;
+ if (file.Write(expr_text, bytes_written).Success())
+ {
+ if (bytes_written == expr_text_len)
+ {
+ file.Close();
+ m_compiler->getSourceManager().createMainFileID(m_file_manager->getFile(temp_source_path));
+ created_main_file = true;
+ }
+ }
+ }
+ }
+
+ if (!created_main_file)
+ {
+ MemoryBuffer *memory_buffer = MemoryBuffer::getMemBufferCopy(expr_text, __FUNCTION__);
+ m_compiler->getSourceManager().createMainFileIDForMemBuffer (memory_buffer);
+ }
diag_buf->BeginSourceFile(m_compiler->getLangOpts(), &m_compiler->getPreprocessor());
@@ -370,7 +418,7 @@ static bool FindFunctionInModule (ConstString &mangled_name,
Error
ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
lldb::addr_t &func_end,
- std::unique_ptr<IRExecutionUnit> &execution_unit_ap,
+ std::shared_ptr<IRExecutionUnit> &execution_unit_sp,
ExecutionContext &exe_ctx,
bool &can_interpret,
ExecutionPolicy execution_policy)
@@ -379,13 +427,11 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
func_end = LLDB_INVALID_ADDRESS;
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- std::unique_ptr<llvm::ExecutionEngine> execution_engine_ap;
-
Error err;
- std::unique_ptr<llvm::Module> module_ap (m_code_generator->ReleaseModule());
+ std::unique_ptr<llvm::Module> llvm_module_ap (m_code_generator->ReleaseModule());
- if (!module_ap.get())
+ if (!llvm_module_ap.get())
{
err.SetErrorToGenericError();
err.SetErrorString("IR doesn't contain a module");
@@ -396,7 +442,7 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
ConstString function_name;
- if (!FindFunctionInModule(function_name, module_ap.get(), m_expr.FunctionName()))
+ if (!FindFunctionInModule(function_name, llvm_module_ap.get(), m_expr.FunctionName()))
{
err.SetErrorToGenericError();
err.SetErrorStringWithFormat("Couldn't find %s() in the module", m_expr.FunctionName());
@@ -408,12 +454,12 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
log->Printf("Found function %s for %s", function_name.AsCString(), m_expr.FunctionName());
}
- m_execution_unit.reset(new IRExecutionUnit(m_llvm_context, // handed off here
- module_ap, // handed off here
- function_name,
- exe_ctx.GetTargetSP(),
- m_compiler->getTargetOpts().Features));
-
+ execution_unit_sp.reset(new IRExecutionUnit (m_llvm_context, // handed off here
+ llvm_module_ap, // handed off here
+ function_name,
+ exe_ctx.GetTargetSP(),
+ m_compiler->getTargetOpts().Features));
+
ClangExpressionDeclMap *decl_map = m_expr.DeclMap(); // result can be NULL
if (decl_map)
@@ -425,15 +471,15 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
IRForTarget ir_for_target(decl_map,
m_expr.NeedsVariableResolution(),
- *m_execution_unit,
+ *execution_unit_sp,
error_stream,
function_name.AsCString());
- bool ir_can_run = ir_for_target.runOnModule(*m_execution_unit->GetModule());
+ bool ir_can_run = ir_for_target.runOnModule(*execution_unit_sp->GetModule());
Error interpret_error;
- can_interpret = IRInterpreter::CanInterpret(*m_execution_unit->GetModule(), *m_execution_unit->GetFunction(), interpret_error);
+ can_interpret = IRInterpreter::CanInterpret(*execution_unit_sp->GetModule(), *execution_unit_sp->GetFunction(), interpret_error);
Process *process = exe_ctx.GetProcessPtr();
@@ -483,7 +529,7 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
IRDynamicChecks ir_dynamic_checks(*process->GetDynamicCheckers(), function_name.AsCString());
- if (!ir_dynamic_checks.runOnModule(*m_execution_unit->GetModule()))
+ if (!ir_dynamic_checks.runOnModule(*execution_unit_sp->GetModule()))
{
err.SetErrorToGenericError();
err.SetErrorString("Couldn't add dynamic checks to the expression");
@@ -491,15 +537,21 @@ ClangExpressionParser::PrepareForExecution (lldb::addr_t &func_addr,
}
}
- m_execution_unit->GetRunnableInfo(err, func_addr, func_end);
+ execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
}
}
else
{
- m_execution_unit->GetRunnableInfo(err, func_addr, func_end);
+ execution_unit_sp->GetRunnableInfo(err, func_addr, func_end);
}
- execution_unit_ap.reset (m_execution_unit.release());
-
return err;
}
+
+bool
+ClangExpressionParser::GetGenerateDebugInfo () const
+{
+ if (m_compiler)
+ return m_compiler->getCodeGenOpts().getDebugInfo() == CodeGenOptions::FullDebugInfo;
+ return false;
+}
OpenPOWER on IntegriCloud