How to inspect std::string in GDB with no source code? - c++

I'm trying to debug a program that has no source code available, and I need to look at what it has stored in a std::string. I've been Googling and looking on here, and I've found some information about outputting STL containers, but all of it refers to variables, with no source or debug information all I have is a memory offset of the class data. Is there any way to do this?

Every std::string implementation has a pointer to the raw characters in it somewhere. For g++ 4.x, that pointer is at offset 0 into the string.
If you know that the string resides at e.g. 0x7fffffffda88, then
print *(char**)0x7fffffffda88
is what you need.

Perhaps the easiest option is to use the c_str method, as in:
print myStr.c_str()

Related

configuring gdb to change the display of objects

In GDB, objects typically display with lots of tripe due to included template objects.
There's a lot of useless std::char_traits ...
Is there a way to filter this stuff out? Basically, I'd like to know if I can configure .gdbinit to display the text only for a std::string, and perhaps the first few elements for a vector.
Alternatively, is there some sort of macro I can write to let me print out just a particular field of an object instead of writing by hand
For a string, I can write:
p s.c_str()
but I'll get a seg fault if it's NULL.
I'd like enough logic to ignore that but don't know that gdb has any facility for it?
Yes, there are such things about! It's a bit limited but you can do it.
Look here and also here.

Why do the characters ÌÌÌÌ get stuck onto the begining of my strings?

I have been developing some computer vision tools with openCV, but every time that I pass a string into an openCV function, the characters ÌÌÌÌ get tagged onto the beginning. At first this was just annoying, but now I am trying to use openCV's fileStorage tools and the ÌÌÌÌ characters are making my file names unreadable.
Note: the characters only get added when I pass strings into the new c++ style openCV functions. If I use the old C style functions the strings come out fine.
example:
I enter this:
namedWindow("CBImage", 1);
.
.
.
imshow("CBImage", Frame);
But the window title reads ÌÌÌÌCBImage
I don't think that the problem is necessarily specific to openCV; I think it has to do with string use in general. check this link out the coder seems to be experiencing a similar problem.
http://www.sfml-dev.org/forum/viewtopic.php?t=1257&sid=5cfa50b780e47685d1c03296adffa8ed
any thoughts?
thanks
Thank you all for your help. KennyTM's origional suggestion did fix the problem. I had to replace my cv cvaux cvcore and highgui libraries with the debug versions (they may have to be built depending on which version of openCV you are running check your lib folder in your openCV directory).
Given that ÌÌÌÌ = 0xCCCCCCCC, it seems the library does not expect a 4-byte member before the string member, e.g.
// Provided.
struct something {
...
void* some_pointer; // uninitialized variables are filled with 0xCC in debug mode.
char the_actual_content[1234];
...
}
// But the library wants
struct something {
...
char the_actual_content[1234]; // now the 0xCCCCCCC is shifted into this string.
...
}
Have you tried the advice in the link?
Don't mix debug and release configurations If you're in debug mode, link to the libraries with the "-d" suffix.
Something is reading memory that hasn't been initialized. See the following answer for details of what debug builds of MSVC might set uninitialized or unusable memory to:
When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete?
You may be passing the address of a std::string to a function that expects a reference (not pointer) to a std::string and also has a version that accepts void*.

Issue with using std::copy

I am getting warning when using the std copy function.
I have a byte array that I declare.
byte *tstArray = new byte[length];
Then I have a couple other byte arrays that are declared and initialized with some hex values that i would like to use depending on some initial user input.
I have a series of if statements that I use to basically parse out the original input, and based on some string, I choose which byte array to use and in doing so copy the results to the original tstArray.
For example:
if(substr1 == "15")
{
std::cout<<"Using byte array rated 15"<<std::endl;
std::copy(ratedArray15,ratedArray15+length,tstArray);
}
The warning i get is
warning C4996: 'std::copy': Function call with parameters
that may be unsafe
- this call relies on the caller to check that the passed
values are correct.
A possible solution is to to disable this warning is by useing -D_SCL_SECURE_NO_WARNINGS, I think. Well, that is what I am researching.
But, I am not sure if this means that my code is really unsafe and I actually needed to do some checking?
C4996 means you're using a function that was marked as __declspec(deprecated). Probably using D_SCL_SECURE_NO_WARNINGS will just #ifdef out the deprecation. You could go read the header file to know for sure.
But the question is why is it deprecated? MSDN doesn't seem to say anything about it on the std::copy() page, but I may be looking at the wrong one. Typically this was done for all "unsafe string manipulation functions" during the great security push of XPSP2. Since you aren't passing the length of your destination buffer to std::copy, if you try to write too much data to it it will happily write past the end of the buffer.
To say whether or not your usage is unsafe would require us to review your entire code. Usually there is a safer version they recommend when they deprecate a function in this manner. You could just copy the strings in some other way. This article seems to go in depth. They seem to imply you should be using a std::checked_array_iterator instead of a regular OutputIterator.
Something like:
stdext::checked_array_iterator<char *> chkd_test_array(tstArray, length);
std::copy(ratedArray15, ratedArray15+length, chkd_test_array);
(If I understand your code right.)
Basically, what this warning tells you is that you have to be absolutely sure that tstArray points to an array that is large enough to hold "length" elements, as std::copy does not check that.
Well, I assume Microsoft's unilateral deprecation of the stdlib also includes passing char* to std::copy. (They've messed with a whole range of functions actually.)
I suppose parts of it has some merit (fopen() touches global ERRNO, so it's not thread-safe) but other decisions do not seem very rational. (I'd say they took a too big swathe at the whole thing. There should be levels, such as non-threadsafe, non-checkable, etc)
I'd recommend reading the MS-doc on each function if you want to know the issues about each case though, it's pretty well documented why each function has that warning, and the cause is usually different in each case.
At least it seems that VC++ 2010 RC does not emit that warning at the default warning level.

Detour to get a Global Pointer?

I need to get the protocol version of an application, and I don't know too much about the inner workings of detouring. I usually use a detour class written by a friend of mine (Not windows detour, as this works on win/linux) but im wondering if anyone can give me some insight on how to retrieve the value of a global pointer? I found a function which uses it, but the class I use only allows for you to rewrite functions, not access individual lines. Here is what the assembly looks like from IDA...
I need to get the value of "gpszVersionString_ptr"
http://www.ampaste.net/m57f13aba
Edit
Sorry, it lost formatting so i had to ampaste it.
if it's already a compiled binary. How about extracting the string using string pattern match?
For example you can read in the file char by char and search for the pattern:
Protocol version %i\nExe version %s
(%s)

Does an arbitrary instruction pointer reside in a specific function?

I have a very difficult problem I'm trying to solve: Let's say I have an arbitrary instruction pointer. I need to find out if that instruction pointer resides in a specific function (let's call it "Foo").
One approach to this would be to try to find the start and ending bounds of the function and see if the IP resides in it. The starting bound is easy to find:
void *start = &Foo;
The problem is, I don't know how to get the ending address of the function (or how "long" the function is, in bytes of assembly).
Does anyone have any ideas how you would get the "length" of a function, or a completely different way of doing this?
Let's assume that there is no SEH or C++ exception handling in the function. Also note that I am on a win32 platform, and have full access to the win32 api.
This won't work. You're presuming functions are contigous in memory and that one address will map to one function. The optimizer has a lot of leeway here and can move code from functions around the image.
If you have PDB files, you can use something like the dbghelp or DIA API's to figure this out. For instance, SymFromAddr. There may be some ambiguity here as a single address can map to multiple functions.
I've seen code that tries to do this before with something like:
#pragma optimize("", off)
void Foo()
{
}
void FooEnd()
{
}
#pragma optimize("", on)
And then FooEnd-Foo was used to compute the length of function Foo. This approach is incredibly error prone and still makes a lot of assumptions about exactly how the code is generated.
Look at the *.map file which can optionally be generated by the linker when it links the program, or at the program's debug (*.pdb) file.
OK, I haven't done assembly in about 15 years. Back then, I didn't do very much. Also, it was 680x0 asm. BUT...
Don't you just need to put a label before and after the function, take their addresses, subtract them for the function length, and then just compare the IP? I've seen the former done. The latter seems obvious.
If you're doing this in C, look first for debugging support --- ChrisW is spot on with map files, but also see if your C compiler's standard library provides anything for this low-level stuff -- most compilers provide tools for analysing the stack etc., for instance, even though it's not standard. Otherwise, try just using inline assembly, or wrapping the C function with an assembly file and a empty wrapper function with those labels.
The most simple solution is maintaining a state variable:
volatile int FOO_is_running = 0;
int Foo( int par ){
FOO_is_running = 1;
/* do the work */
FOO_is_running = 0;
return 0;
}
Here's how I do it, but it's using gcc/gdb.
$ gdb ImageWithSymbols
gdb> info line * 0xYourEIPhere
Edit: Formatting is giving me fits. Time for another beer.