[Lldb-commits] [lldb] r169556 - in /lldb/trunk: include/lldb/Interpreter/Args.h source/Commands/CommandObjectBreakpoint.cpp source/Commands/CommandObjectDisassemble.cpp source/Commands/CommandObjectMemory.cpp source/Commands/CommandObjectTarget.cpp source/Interpreter/Args.cpp source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Greg Clayton gclayton at apple.com
Thu Dec 6 14:49:17 PST 2012


Author: gclayton
Date: Thu Dec  6 16:49:16 2012
New Revision: 169556

URL: http://llvm.org/viewvc/llvm-project?rev=169556&view=rev
Log:
<rdar://problem/12820334>

I modified the "Args::StringtoAddress(...)" function to be able to evaluate address expressions. This is now used for any command line arguments or options that takes addresses like:

memory read <addr> [<end-addr>]
memory write <addr>
breakpoint set --address <addr>
disassemble --start-address <addr> --end-address <addr>

It calls the expression parser to evaluate the address expression and will also work around the issue where the compiler doesn't like to add offsets to function pointers (which is what happens when you try to evaluate "main + 12"). So there is a temp fix in the Args::StringtoAddress() to work around this until we can get special compiler support for debug expressions with function pointers.



Modified:
    lldb/trunk/include/lldb/Interpreter/Args.h
    lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
    lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
    lldb/trunk/source/Commands/CommandObjectMemory.cpp
    lldb/trunk/source/Commands/CommandObjectTarget.cpp
    lldb/trunk/source/Interpreter/Args.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Modified: lldb/trunk/include/lldb/Interpreter/Args.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/Args.h?rev=169556&r1=169555&r2=169556&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Interpreter/Args.h (original)
+++ lldb/trunk/include/lldb/Interpreter/Args.h Thu Dec  6 16:49:16 2012
@@ -382,7 +382,10 @@
     }
 
     static lldb::addr_t
-    StringToAddress (const char *s, lldb::addr_t fail_value = LLDB_INVALID_ADDRESS, bool *success_ptr = NULL);
+    StringToAddress (const ExecutionContext *exe_ctx,
+                     const char *s,
+                     lldb::addr_t fail_value,
+                     Error *error);
 
     static bool
     StringToBoolean (const char *s, bool fail_value, bool *success_ptr);

Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=169556&r1=169555&r2=169556&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Thu Dec  6 16:49:16 2012
@@ -125,12 +125,10 @@
             switch (short_option)
             {
                 case 'a':
-                    m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
-                    if (m_load_addr == LLDB_INVALID_ADDRESS)
-                        m_load_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
-
-                    if (m_load_addr == LLDB_INVALID_ADDRESS)
-                        error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
+                    {
+                        ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+                        m_load_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
+                    }
                     break;
 
                 case 'b':

Modified: lldb/trunk/source/Commands/CommandObjectDisassemble.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectDisassemble.cpp?rev=169556&r1=169555&r2=169556&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectDisassemble.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectDisassemble.cpp Thu Dec  6 16:49:16 2012
@@ -88,23 +88,21 @@
         break;
 
     case 's':
-        start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
-        if (start_addr == LLDB_INVALID_ADDRESS)
-            start_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
-
-        if (start_addr == LLDB_INVALID_ADDRESS)
-            error.SetErrorStringWithFormat ("invalid start address string '%s'", option_arg);
-        some_location_specified = true;
+        {
+            ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+            start_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
+            if (start_addr != LLDB_INVALID_ADDRESS)
+                some_location_specified = true;
+        }
         break;
     case 'e':
-        end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 0);
-        if (end_addr == LLDB_INVALID_ADDRESS)
-            end_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS, 16);
-
-        if (end_addr == LLDB_INVALID_ADDRESS)
-            error.SetErrorStringWithFormat ("invalid end address string '%s'", option_arg);
+        {
+            ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
+            end_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error);
+            if (end_addr != LLDB_INVALID_ADDRESS)
+                some_location_specified = true;
+        }
         break;
-        some_location_specified = true;
     case 'n':
         func_name.assign (option_arg);
         some_location_specified = true;

Modified: lldb/trunk/source/Commands/CommandObjectMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMemory.cpp?rev=169556&r1=169555&r2=169556&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectMemory.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectMemory.cpp Thu Dec  6 16:49:16 2012
@@ -369,8 +369,7 @@
 
 protected:
     virtual bool
-    DoExecute (Args& command,
-             CommandReturnObject &result)
+    DoExecute (Args& command, CommandReturnObject &result)
     {
         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
         Target *target = exe_ctx.GetTargetPtr();
@@ -385,7 +384,8 @@
         
         if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2)
         {
-            result.AppendErrorWithFormat ("%s takes 1 or two args.\n", m_cmd_name.c_str());
+            result.AppendErrorWithFormat ("%s takes a start address expression with an optional end address expression.\n", m_cmd_name.c_str());
+            result.AppendRawWarning("Expressions should be quoted if they contain spaces or other special characters.");
             result.SetStatus(eReturnStatusFailed);
             return false;
         }
@@ -565,7 +565,7 @@
         // Look for invalid combinations of settings
         if (error.Fail())
         {
-            result.AppendErrorWithFormat("%s", error.AsCString());
+            result.AppendError(error.AsCString());
             result.SetStatus(eReturnStatusFailed);
             return false;
         }
@@ -602,21 +602,23 @@
         }
 
         if (argc > 0)
-            addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0);
+            addr = Args::StringToAddress(&exe_ctx, command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, &error);
 
         if (addr == LLDB_INVALID_ADDRESS)
         {
-            result.AppendErrorWithFormat("invalid start address string '%s'.\n", command.GetArgumentAtIndex(0));
+            result.AppendError("invalid start address expression.");
+            result.AppendError(error.AsCString());
             result.SetStatus(eReturnStatusFailed);
             return false;
         }
 
         if (argc == 2)
         {
-            lldb::addr_t end_addr = Args::StringToUInt64(command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
+            lldb::addr_t end_addr = Args::StringToAddress(&exe_ctx, command.GetArgumentAtIndex(1), LLDB_INVALID_ADDRESS, 0);
             if (end_addr == LLDB_INVALID_ADDRESS)
             {
-                result.AppendErrorWithFormat("invalid end address string '%s'.\n", command.GetArgumentAtIndex(1));
+                result.AppendError("invalid end address expression.");
+                result.AppendError(error.AsCString());
                 result.SetStatus(eReturnStatusFailed);
                 return false;
             }
@@ -667,7 +669,7 @@
             }
             
             if (bytes_read < total_byte_size)
-                result.AppendWarningWithFormat("Not all bytes (%lu/%lu) were able to be read from 0x%" PRIx64 ".\n", bytes_read, total_byte_size, addr);
+                result.AppendWarningWithFormat("Not all bytes (%lu/%lu) were able to be read from 0x%" PRIx64 ".", bytes_read, total_byte_size, addr);
             else
             {
                 m_next_addr = addr + bytes_read;
@@ -987,7 +989,8 @@
     virtual bool
     DoExecute (Args& command, CommandReturnObject &result)
     {
-        Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
+        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
+        Process *process = exe_ctx.GetProcessPtr();
         if (process == NULL)
         {
             result.AppendError("need a process to read memory");
@@ -1020,11 +1023,16 @@
         OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
         size_t item_byte_size = byte_size_value.GetCurrentValue();
 
-        lldb::addr_t addr = Args::StringToUInt64(command.GetArgumentAtIndex(0), LLDB_INVALID_ADDRESS, 0);
+        Error error;
+        lldb::addr_t addr = Args::StringToAddress (&exe_ctx,
+                                                   command.GetArgumentAtIndex(0),
+                                                   LLDB_INVALID_ADDRESS,
+                                                   &error);
 
         if (addr == LLDB_INVALID_ADDRESS)
         {
-            result.AppendErrorWithFormat("Invalid address string '%s'.\n", command.GetArgumentAtIndex(0));
+            result.AppendError("invalid address expression\n");
+            result.AppendError(error.AsCString());
             result.SetStatus(eReturnStatusFailed);
             return false;
         }

Modified: lldb/trunk/source/Commands/CommandObjectTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectTarget.cpp?rev=169556&r1=169555&r2=169556&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectTarget.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectTarget.cpp Thu Dec  6 16:49:16 2012
@@ -3026,6 +3026,8 @@
         virtual Error
         SetOptionValue (uint32_t option_idx, const char *option_arg)
         {
+            Error error;
+
             const int short_option = m_getopt_table[option_idx].val;
             if (short_option == 'g')
             {
@@ -3033,13 +3035,7 @@
             }
             else if (short_option == 'a')
             {
-                bool success;
-                m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success);
-                if (!success)
-                {
-                    Error error;
-                    error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg);
-                }
+                m_module_addr = Args::StringToAddress(NULL, option_arg, LLDB_INVALID_ADDRESS, &error);
             }
             else
             {
@@ -3048,7 +3044,6 @@
                     width = strtoul (option_arg, NULL, 0);
                 m_format_array.push_back(std::make_pair(short_option, width));
             }
-            Error error;
             return error;
         }
         

Modified: lldb/trunk/source/Interpreter/Args.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/Args.cpp?rev=169556&r1=169555&r2=169556&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/Args.cpp (original)
+++ lldb/trunk/source/Interpreter/Args.cpp Thu Dec  6 16:49:16 2012
@@ -22,6 +22,11 @@
 #include "lldb/Core/StreamString.h"
 #include "lldb/Interpreter/Options.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/Process.h"
+//#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+//#include "lldb/Target/Thread.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -782,26 +787,119 @@
 }
 
 lldb::addr_t
-Args::StringToAddress (const char *s, lldb::addr_t fail_value, bool *success_ptr)
+Args::StringToAddress (const ExecutionContext *exe_ctx, const char *s, lldb::addr_t fail_value, Error *error_ptr)
 {
+    bool error_set = false;
     if (s && s[0])
     {
         char *end = NULL;
         lldb::addr_t addr = ::strtoull (s, &end, 0);
         if (*end == '\0')
         {
-            if (success_ptr) *success_ptr = true;
+            if (error_ptr)
+                error_ptr->Clear();
             return addr; // All characters were used, return the result
         }
         // Try base 16 with no prefix...
         addr = ::strtoull (s, &end, 16);
         if (*end == '\0')
         {
-            if (success_ptr) *success_ptr = true;
+            if (error_ptr)
+                error_ptr->Clear();
             return addr; // All characters were used, return the result
         }
+        
+        if (exe_ctx)
+        {
+            Target *target = exe_ctx->GetTargetPtr();
+            if (target)
+            {
+                lldb::ValueObjectSP valobj_sp;
+                EvaluateExpressionOptions options;
+                options.SetCoerceToId(false);
+                options.SetUnwindOnError(true);
+                options.SetKeepInMemory(false);
+                options.SetRunOthers(true);
+                
+                ExecutionResults expr_result = target->EvaluateExpression(s,
+                                                                          exe_ctx->GetFramePtr(),
+                                                                          valobj_sp,
+                                                                          options);
+
+                bool success = false;
+                if (expr_result == eExecutionCompleted)
+                {
+                    // Get the address to watch.
+                    addr = valobj_sp->GetValueAsUnsigned(fail_value, &success);
+                    if (success)
+                    {
+                        if (error_ptr)
+                            error_ptr->Clear();
+                        return addr;
+                    }
+                    else
+                    {
+                        if (error_ptr)
+                        {
+                            error_set = true;
+                            error_ptr->SetErrorStringWithFormat("address expression \"%s\" resulted in a value whose type can't be converted to an address: %s", s, valobj_sp->GetTypeName().GetCString());
+                        }
+                    }
+                    
+                }
+                else
+                {
+                    // Since the compiler can't handle things like "main + 12" we should
+                    // try to do this for now. The compliler doesn't like adding offsets
+                    // to function pointer types.
+                    RegularExpression symbol_plus_offset_regex("^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+                    if (symbol_plus_offset_regex.Execute(s, 3))
+                    {
+                        uint64_t offset = 0;
+                        bool add = true;
+                        std::string name;
+                        std::string str;
+                        if (symbol_plus_offset_regex.GetMatchAtIndex(s, 1, name))
+                        {
+                            if (symbol_plus_offset_regex.GetMatchAtIndex(s, 2, str))
+                            {
+                                add = str[0] == '+';
+                                
+                                if (symbol_plus_offset_regex.GetMatchAtIndex(s, 3, str))
+                                {
+                                    offset = Args::StringToUInt64(str.c_str(), 0, 0, &success);
+                                    
+                                    if (success)
+                                    {
+                                        Error error;
+                                        addr = StringToAddress (exe_ctx, name.c_str(), LLDB_INVALID_ADDRESS, &error);
+                                        if (addr != LLDB_INVALID_ADDRESS)
+                                        {
+                                            if (add)
+                                                return addr + offset;
+                                            else
+                                                return addr - offset;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    
+                    if (error_ptr)
+                    {
+                        error_set = true;
+                        error_ptr->SetErrorStringWithFormat("address expression \"%s\" evaluation failed", s);
+                    }
+                }
+            }
+        }
+    }
+    if (error_ptr)
+    {
+        if (!error_set)
+            error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", s);
     }
-    if (success_ptr) *success_ptr = false;
     return fail_value;
 }
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=169556&r1=169555&r2=169556&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Thu Dec  6 16:49:16 2012
@@ -2050,7 +2050,7 @@
             return response.GetHexBytes(buf, size, '\xdd');
         }
         else if (response.IsErrorResponse())
-            error.SetErrorString("memory read failed");
+            error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr);
         else if (response.IsUnsupportedResponse())
             error.SetErrorStringWithFormat("GDB server does not support reading memory");
         else
@@ -2086,7 +2086,7 @@
             return size;
         }
         else if (response.IsErrorResponse())
-            error.SetErrorString("memory write failed");
+            error.SetErrorStringWithFormat("memory write failed for 0x%" PRIx64, addr);
         else if (response.IsUnsupportedResponse())
             error.SetErrorStringWithFormat("GDB server does not support writing memory");
         else





More information about the lldb-commits mailing list