<rdar://problem/12437929>
Providing a special mode of operator for "memory read -f c-str" which actually works in most common cases
Where the old behavior would provide:
(lldb) mem read --format s `foo`
0x100000f5d: NULL
Now we do:
(lldb) mem read --format s `foo`
0x100000f5d: "hello world"
You can also specify a count and that many strings will be showed starting at the initial address:
(lldb) mem read -c 2 -f c-str `foo`
0x100000f1d: "hello world"
0x100000f29: "short"
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@173076 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index 947fc27..cbff45c 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -586,7 +586,7 @@
}
size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
- const size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
+ size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
if (total_byte_size == 0)
@@ -641,6 +641,8 @@
return false;
}
+
+
DataBufferSP data_sp;
size_t bytes_read = 0;
if (clang_ast_type.GetOpaqueQualType())
@@ -651,7 +653,7 @@
bytes_read = clang_ast_type.GetTypeByteSize() * m_format_options.GetCountValue().GetCurrentValue();
}
- else
+ else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
{
data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
Address address(addr, NULL);
@@ -674,6 +676,46 @@
if (bytes_read < total_byte_size)
result.AppendWarningWithFormat("Not all bytes (%lu/%lu) were able to be read from 0x%" PRIx64 ".", bytes_read, total_byte_size, addr);
}
+ else
+ {
+ // we treat c-strings as a special case because they do not have a fixed size
+ if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat())
+ item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
+ else
+ item_byte_size = target->GetMaximumSizeOfStringSummary();
+ if (!m_format_options.GetCountValue().OptionWasSet())
+ item_count = 1;
+ data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary
+ uint8_t *data_ptr = data_sp->GetBytes();
+ auto data_addr = addr;
+ auto count = item_count;
+ item_count = 0;
+ while (item_count < count)
+ {
+ std::string buffer;
+ buffer.resize(item_byte_size+1,0);
+ Error error;
+ size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error);
+ if (error.Fail())
+ {
+ result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
+ if (item_byte_size == read)
+ {
+ result.AppendWarningWithFormat("unable to find a NULL terminated string at 0x%" PRIx64 ".Consider increasing the maximum read length.\n", data_addr);
+ break;
+ }
+ read+=1; // account for final NULL byte
+ memcpy(data_ptr, &buffer[0], read);
+ data_ptr += read;
+ data_addr += read;
+ bytes_read += read;
+ item_count++; // if we break early we know we only read item_count strings
+ }
+ data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1));
+ }
m_next_addr = addr + bytes_read;
m_prev_byte_size = bytes_read;