[Lldb-commits] [PATCH] D23545: Minidump parsing

Zachary Turner via lldb-commits lldb-commits at lists.llvm.org
Tue Aug 16 10:10:15 PDT 2016


Btw the endian aware types are usable, just include
"llvm/Support/Endian.h". It's just the consumeObject functions that are not
On Tue, Aug 16, 2016 at 10:01 AM Zachary Turner <zturner at google.com> wrote:

> zturner added a comment.
>
> LLVM does have something similar to DataExtractor, but unfortunately it's
> not present in the correct library for you to easily be able to reuse it.
> I actually own the code in question, so I'm willing to fix that for you if
> you're interested, but at the same time the code is very simple.  LLVM has
> some endian-aware data types that are very convenient to work with and
> mostly eliminate the need to worry about endianness while parsing, which is
> what DataExtractor mostly does for you.  To use LLVM's types, for example,
> you would change this:
>
>   struct MinidumpHeader
>   {
>       uint32_t signature;
>       uint32_t version;
>       uint32_t streams_count;
>       RVA stream_directory_rva; // offset of the stream directory
>       uint32_t checksum;
>       uint32_t time_date_stamp; // time_t format
>       uint64_t flags;
>
>       static bool
>       SignatureMatchAndSetByteOrder(DataExtractor &data, lldb::offset_t
> *offset);
>
>       static llvm::Optional<MinidumpHeader>
>       Parse(const DataExtractor &data, lldb::offset_t *offset);
>   };
>
> to this:
>
>   struct MinidumpHeader
>   {
>       support::ulittle32_t signature;
>       support::ulittle32_t version;
>       support::ulittle32_t streams_count;
>       support::ulittle32_t stream_directory_rva; // offset of the stream
> directory
>       support::ulittle32_t checksum;
>       support::ulittle32_t time_date_stamp; // time_t format
>       support::ulittle64_t flags;
>   };
>
> All you have to do now is `reinterpret_cast` the buffer to a
> `MiniDumpHeader*` and you're good to go.  So pretty much the entirety of
> the `DataExtractor` class boils down to a single template function:
>
>   template<typename T>
>   Error consumeObject(ArrayRef<uint8_t> &Buffer, const T *&Object) {
>     if (Buffer.size() < sizeof(T))
>       return make_error<StringError>("Insufficient buffer!");
>     Object = reinterpret_cast<const T*>(Buffer.data());
>     Buffer = Buffer.drop_front(sizeof(T));
>     return Error::success();
>   }
>
> For starters, this is nice because it means you're not copying memory
> around unnecessarily.  You're just pointing to the memory that's already
> there.  With DataExtractor you are always copying bytes around.  Dump files
> can be large (even minidumps!) and copying all this memory around is
> inefficient.
>
> It also makes the syntax cleaner.  You have to call different functions on
> DataExtractor depending on what you want to extract.  `GetU8` or `GetU16`
> for example.  This one function works with almost everything.  A few simple
> template specializations and overloads can make it even more powerful.  For
> example:
>
>   Error consumeObject(ArrayRef<uint8_t> &Buffer, StringRef &ZeroString) {
>      ZeroString = StringRef(reinterpret_cast<const char
> *>(Buffer.front()));
>      Buffer = Buffer.drop_front(ZeroString.size() + 1);
>      return Error::success();
>   }
>
> I have some more comments on the CL, but I have to run to a meeting, so I
> will be back later.
>
>
> https://reviews.llvm.org/D23545
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20160816/c580b0bf/attachment-0001.html>


More information about the lldb-commits mailing list