How to view va_list variables via gdb

By | March 7, 2016

Viewing variable values via gdb of a va_list is not as straight forward as gdb> p myvar. It requires a few extra steps not only in execution but in understanding. Read on if you want to know how va_* works and how to view the underlying variables.

Step 1:

The first step is to understand the underlying structure of variable arguments and in particular va_list. This blog https://bobobobo.wordpress.com/2008/01/28/how-to-use-variable-argument-lists-va_list/ does a really good job.

The summary from this site:

  • va_list, va_start, va_end, va_arg are the macros needed.
  • The very first step is to create a pointer to point to the first element of the variable argument list. (va_list myListPointer;)
  • use va_start(myListPointer, numargs) to actually make myListPointer point to the first variable. (You need to at least step past this line in order to start inspecting memory).
  • The rest involves looping through and printing/calculating the values.

Step 2:

Copy the sample code from https://en.wikipedia.org/wiki/Variadic_function and compile it. Change the input to average as required.

Step 3:

Read through these 2 further posts that shows you the gdb command to run in order to view the value of your variable.

The summary is that you need to type this in gdb:

  • p *(int *)(((char *)args[0].reg_save_area)+args[0].gp_offset)

Note to change args to the name of your variable .

Here is another angle. The key is “gp_offset is how many bytes after reg_save_area the first argument is”. So you could find the pointer of first argument via:

>>  ap[0].reg_save_area+ap[0].gp_offset

Then you can view it via:

>> x/c 0x7fff5fbffa18

Screen Shot 2016-03-07 at 12.05.53 PM

My variable here was ‘8’. To get the content of the next variable, you have to increment the reg_save_area by the number of bytes you know the argument to take. ie run through the loop again calling va_arg(). This will then increment gp_offset.

“…gp_offset will be only incremented after calling va_arg() macro, if you want to see more arguments you must increment reg_save_area by the number of bytes you know arguments take…”

Step 4:

Check out the definition of reg_save_area, overflow_arg_area, gp_offset and fp_offset at: http://stackoverflow.com/questions/4958384/what-is-the-format-of-the-x86-64-va-list-structure

Reason being is if you tried gdb> p args, you would come across these variables. Note my variable is called “ap”

Screen Shot 2016-03-07 at 11.44.17 AM

Step 5:

This post does a great job explaining step 4.

https://blog.nelhage.com/2010/10/amd64-and-va_arg/

Conclusion

This is not for the faint hearted, but if you want to truely understand how it actually works, put in the time and figure it out.

Leave a Reply

Your email address will not be published. Required fields are marked *