diff options
author | Greg Clayton <gclayton@apple.com> | 2014-03-24 23:10:19 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2014-03-24 23:10:19 +0000 |
commit | 23f8c95a4439767cf9c7dc9d7a35eb55dc78b9d0 (patch) | |
tree | 3e56f285be57acf15b3fb73195567727a329aca9 /lldb/source/Expression/ClangUserExpression.cpp | |
parent | 2256d0dcedf887593ebfb35db860827e8682807e (diff) | |
download | bcm5719-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/ClangUserExpression.cpp')
-rw-r--r-- | lldb/source/Expression/ClangUserExpression.cpp | 71 |
1 files changed, 61 insertions, 10 deletions
diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index 2b9bd2cef50..4eefddda41a 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -20,6 +20,7 @@ #include "lldb/Core/ConstString.h" #include "lldb/Core/Log.h" +#include "lldb/Core/Module.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StreamString.h" #include "lldb/Core/ValueObjectConstResult.h" @@ -36,6 +37,8 @@ #include "lldb/Symbol/Block.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Function.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/VariableList.h" @@ -63,6 +66,11 @@ ClangUserExpression::ClangUserExpression (const char *expr, m_language (language), m_transformed_text (), m_desired_type (desired_type), + m_expr_decl_map(), + m_execution_unit_sp(), + m_materializer_ap(), + m_result_synthesizer(), + m_jit_module_wp(), m_enforce_valid_object (true), m_cplusplus (false), m_objectivec (false), @@ -91,6 +99,12 @@ ClangUserExpression::ClangUserExpression (const char *expr, ClangUserExpression::~ClangUserExpression () { + if (m_target) + { + lldb::ModuleSP jit_module_sp (m_jit_module_wp.lock()); + if (jit_module_sp) + m_target->GetImages().Remove(jit_module_sp); + } } clang::ASTConsumer * @@ -415,7 +429,8 @@ bool ClangUserExpression::Parse (Stream &error_stream, ExecutionContext &exe_ctx, lldb_private::ExecutionPolicy execution_policy, - bool keep_result_in_memory) + bool keep_result_in_memory, + bool generate_debug_info) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)); @@ -514,7 +529,7 @@ ClangUserExpression::Parse (Stream &error_stream, if (!exe_scope) exe_scope = exe_ctx.GetTargetPtr(); - ClangExpressionParser parser(exe_scope, *this); + ClangExpressionParser parser(exe_scope, *this, generate_debug_info); unsigned num_errors = parser.Parse (error_stream); @@ -533,11 +548,42 @@ ClangUserExpression::Parse (Stream &error_stream, Error jit_error = parser.PrepareForExecution (m_jit_start_addr, m_jit_end_addr, - m_execution_unit_ap, + m_execution_unit_sp, exe_ctx, m_can_interpret, execution_policy); + if (generate_debug_info) + { + lldb::ModuleSP jit_module_sp ( m_execution_unit_sp->GetJITModule()); + + if (jit_module_sp) + { + ConstString const_func_name(FunctionName()); + FileSpec jit_file; + jit_file.GetFilename() = const_func_name; + jit_module_sp->SetFileSpecAndObjectName (jit_file, ConstString()); + m_jit_module_wp = jit_module_sp; + target->GetImages().Append(jit_module_sp); + } +// lldb_private::ObjectFile *jit_obj_file = jit_module_sp->GetObjectFile(); +// StreamFile strm (stdout, false); +// if (jit_obj_file) +// { +// jit_obj_file->GetSectionList(); +// jit_obj_file->GetSymtab(); +// jit_obj_file->Dump(&strm); +// } +// lldb_private::SymbolVendor *jit_sym_vendor = jit_module_sp->GetSymbolVendor(); +// if (jit_sym_vendor) +// { +// lldb_private::SymbolContextList sc_list; +// jit_sym_vendor->FindFunctions(const_func_name, NULL, lldb::eFunctionNameTypeFull, true, false, sc_list); +// sc_list.Dump(&strm, target); +// jit_sym_vendor->Dump(&strm); +// } + } + m_expr_decl_map.reset(); // Make this go away since we don't need any of its state after parsing. This also gets rid of any ClangASTImporter::Minions. if (jit_error.Success()) @@ -667,7 +713,7 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, IRMemoryMap::AllocationPolicy policy = m_can_interpret ? IRMemoryMap::eAllocationPolicyHostOnly : IRMemoryMap::eAllocationPolicyMirror; - m_materialized_address = m_execution_unit_ap->Malloc(m_materializer_ap->GetStructByteSize(), + m_materialized_address = m_execution_unit_sp->Malloc(m_materializer_ap->GetStructByteSize(), m_materializer_ap->GetStructAlignment(), lldb::ePermissionsReadable | lldb::ePermissionsWritable, policy, @@ -688,7 +734,7 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, const size_t stack_frame_size = 512 * 1024; - m_stack_frame_bottom = m_execution_unit_ap->Malloc(stack_frame_size, + m_stack_frame_bottom = m_execution_unit_sp->Malloc(stack_frame_size, 8, lldb::ePermissionsReadable | lldb::ePermissionsWritable, IRMemoryMap::eAllocationPolicyHostOnly, @@ -705,7 +751,7 @@ ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream, Error materialize_error; - m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_ap, struct_address, materialize_error); + m_dematerializer_sp = m_materializer_ap->Materialize(frame, *m_execution_unit_sp, struct_address, materialize_error); if (!materialize_error.Success()) { @@ -781,8 +827,8 @@ ClangUserExpression::Execute (Stream &error_stream, if (m_can_interpret) { - llvm::Module *module = m_execution_unit_ap->GetModule(); - llvm::Function *function = m_execution_unit_ap->GetFunction(); + llvm::Module *module = m_execution_unit_sp->GetModule(); + llvm::Function *function = m_execution_unit_sp->GetFunction(); if (!module || !function) { @@ -810,7 +856,7 @@ ClangUserExpression::Execute (Stream &error_stream, IRInterpreter::Interpret (*module, *function, args, - *m_execution_unit_ap.get(), + *m_execution_unit_sp.get(), interpreter_error, function_stack_bottom, function_stack_top); @@ -965,8 +1011,13 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx, log->Printf("== [ClangUserExpression::Evaluate] Parsing expression %s ==", expr_cstr); const bool keep_expression_in_memory = true; + const bool generate_debug_info = options.GetGenerateDebugInfo(); - if (!user_expression_sp->Parse (error_stream, exe_ctx, execution_policy, keep_expression_in_memory)) + if (!user_expression_sp->Parse (error_stream, + exe_ctx, + execution_policy, + keep_expression_in_memory, + generate_debug_info)) { if (error_stream.GetString().empty()) error.SetErrorString ("expression failed to parse, unknown error"); |