Re: [DynInst_API:] Struct size computation


Date: Thu, 4 Sep 2014 13:13:25 -0700 (PDT)
From: Matthew LeGendre <legendre1@xxxxxxxx>
Subject: Re: [DynInst_API:] Struct size computation

I'd guess that this is a bug in DyninstAPI's DWARF parsing. In symtabAPI/src/dwarfWalker.C, function DwarfWalker::parseStructUnionClass(), the code calculates a structure's size, but then doesn't do anything with the result (I'd guess this bug appeared with the DWARF rewrite from a couple years ago). I think the calculated size should be set in the new typeStruct/typeUnion objects via setSize().

The Type.C code below is trying to estimate the size if one isn't set elsewhere. That may work, and it may be worth improving, but it'd still be better to get the correct size straight from DWARF.

(Disclaimer that I haven't tested this proposed fix).

-Matt

On Thu, 4 Sep 2014, Fabian Mager wrote:
Hello all,

my goal is to extract parameter values of function calls and therefore I use getLocalVariableValue(...). This works quite well so far but not in case the parameter is a struct. getLocalVariableValue() uses Type::getSize() which calls typeStruct::updateSize() in case of a struct. This method just calculates the sum of the sizes of all struct elements. The problem I have is when padding comes into play, e.g.:

struct st {
   int i;    // 4 Bytes
   char c;   // 1 Byte + 3 Bytes padding
   float f;  // 4 Bytes
}

The size of struct st is 12 Bytes on my machine but getSize() returns 9. getLocalVariableValue() uses this wrong size to fill the result buffer with 9 Bytes of information. This buffer then contains the 3 Bytes of padding but not the last 3 Bytes of the float. Nevertheless, getLocalVariableValue() returns 0 to indicate everything went well, even if thats obviously not the case. In order to solve that I made a little patch that considers padding within the struct but not at the end (which is fine for me so far). I'm really not an expert in DynInst so I don't know if this breaks something or not. Perhaps I miss something that already solves my problem?

--- a/symtabAPI/src/Type.C
+++ b/symtabAPI/src/Type.C

@@ -197,7 +197,9 @@ unsigned int Type::getSize()
{
-       if (!size_)
+   // If default constructed, update
+   if (!size_ || (size_ == sizeof(int)))
       const_cast<Type *>(this)->updateSize();
   return size_;
}

@@ -896,15 +898,25 @@ void typeStruct::updateSize()
   // Calculate the size of the entire structure
   size_ = 0;
-   for(unsigned int i = 0; i < fieldList.size(); ++i) {
-       size_ += fieldList[i]->getSize();

-       // Is the type of this field still a placeholder?
-       if(fieldList[i]->getType()->getDataClass() == dataUnknownType) {
-           size_ = 0;
-           break;
-       }
-   }
+
+   // considers padding
+   Field* lastElement = fieldList.back();
+   size_ = (lastElement->getOffset() / 8) + lastElement->getSize();

Best regards,
Fabian
_______________________________________________
Dyninst-api mailing list
Dyninst-api@xxxxxxxxxxx
https://lists.cs.wisc.edu/mailman/listinfo/dyninst-api

[← Prev in Thread] Current Thread [Next in Thread→]