search a string/number in memory using gdb? - gdb

Say I have following integer int i = 18723849;
So is there any parameter in GDB that can help search memory to find above integer and it's memory location?
E.g: (gdb) find 18723849

So is there any parameter in GDB that can help search memory to find above integer
Yes, there is.
It's also the first hit for https://www.google.com/search?q=gdb+search+memory

Related

GDB not able to access memory

I am trying an example in the documentation: "x/4wx 0x54320". I expect to see 16 hex characters. Instead I get an error: "Cannot access memory at address 0x54320".
According to documentation: "address is the address where you want GDB to begin displaying memory: it is always interpreted as an integer address of a byte of memory.".
Is GDB taking "0x54320" as the location to start looking, or the address (pointer) to the location to start looking?
Anyway, all I want is to see the bytes stored starting at "0x54320". How do I accomplish this, please?
x/4wx 0x54320 is incorrect. You probably mean x/4xw 0x54320: display 4 words as hex beginning at address 0x54320. If that address is a pointer, you'll see the value of the pointer, i.e., the address it holds.
0x54320 looks suspicious to me. It's a rare address that just happens to count down in hex. But, maybe you're just lucky.

Find out the source file (line number) where a global variable was initialized?

I have pretty large C++ code base of a shared library which is messed up with complicated conditional macro spaghetti so IDE has troubles with that. I examined it with GDB to find the initial value of a global variable as follows:
$ gdb libcomplex.so
(gdb) p some_global_var
$1 = 1024
So I figured out the value the variable was initialized with.
QUESTION: Is it possible to find out which source file (and maybe line number) it was initialized at with GDB?
I tried list some_global_var, but it simply prints nothing:
(gdb) list some_global_var
(gdb)
So on x86 you can put a limited number of hardware watchpoints on that variable being changed:
If you are lucky, on a global you can get away with
watch some_global_var
But the debugger may still decide that is not a fixed address, and do a software watchpoint.
So you need to get the address, and watch exactly that:
p &some_global_var
(int*)0x000123456789ABC
watch (int*)0x000123456789ABC
Now, when you restart, the debugger should pop out when the value is first initialised, perhaps to zero, and/or when it is initialised to the unexpected value. If you are lucky, listing the associated source code will tell you how it came to be initialised. As others have stated you may then need to deduce why that line of code generated that value, which can be a pain with complex macros.
If that doesn't help you, or it stops many times unexpectedly during startup, then you should initially disable the watchpoint, then starti to restart you program and stop as soon as possible. Then p your global, and if it does not yet have the magic value, enable the watchpoint and continue. Hopefully this will skip the irrelevant startup and zoom in on the problem value.
You could use rr (https://rr-project.org/) to record a trace of the program, then you could reverse-execute to find the location. E.g.:
rr replay
(gdb) continue
...
(gdb) watch -l some_global_var
(gdb) reverse-continue

How to tell the gdb the value of the 'optimized out value' or make it infer the value?

There is a C++ this pointer that is an <optimized out> value, but up the call stack its value can be found.
How to tell gdb that this has that specific value? Can gdb look at the stack and infer it?
There is no way to do this in gdb, at least not in the form of having print this know which frame to inspect to find the value.
One simple work around is to use a convenience variable. For example something like:
(gdb) up 5
(gdb) set $mythis = this
(gdb) down 5
(gdb) print *$mythis
Another approach would be to write a "convenience function" (that's the term used in the gdb manual) to automate this. Convenience functions are written in Python and can do many things, such as look for symbols in other stack frames. So, for example, you could write a $_this function and use it like:
(gdb) print *$_this()
... not quite the same but maybe it would fit your needs.

What does <exp+6> mean in gdb?

I was debugging a C++ code using gdb. The program stopped due to a segmentation fault.
Program received signal SIGSEGV, Segmentation fault.
So I was trying to print out the value of variables to identify where the error is coming from. I have an array called 'ring' of type 'Link **', where Link is a class I defined. Each element in the array points to a 'Link *' variable. Here is the output when I print the first three elements of the 'ring' array.
(gdb) print ring[0]
$13 = (Link *) 0x8125290
(gdb) print ring[1]
$14 = (Link *) 0xb7e80b86 <exp+6>
(gdb) print ring[2]
$15 = (Link *) 0x8132e20
Why am I getting '' after the memory address when printing 'ring[1]'? What does it mean?
EDIT: Im using gdb 7.8 on Arch Linux (3.16.4-1-ARCH)
It means the pointer value is equal to the address of the exp symbol plus 6. It's just the debugger trying to be helpful—whenever it decodes any pointer value, it tries to see if the pointer happens to lie near any known symbols in the object code, and it prints out that information if so.
You might expect to see such notation when examining the disassembly of a function's code, e.g. in branch targets, but as a data pointer, that's very unusual (function pointers would tend to point directly at function symbols, not offset into them).
You almost certainly have some kind of memory corruption bug that just happens to produce that value as a side effect.

Protect the whole address space using mprotect

For my university project I need to WRITE protect the whole address space of the process. I was reading the /proc/self/maps file and parsing the mapping.
So for each entry of the format 08048000-0804c000 r-xp 00000000 08:03 7971106 /bin/cat, I am reading the first two entry(here 08048000 & 0804c000), converting them to decimal. Lets assume the decimal equivalent is A & B respectively. Then I do mprotect((int*)A, B-A, PROT_READ). But this approach is giving me segmentation fault. I can't find out what I did wrong here. May be I've some knowledge gap here which is causing the problem. Someone can give me some suggestions?
Assuming that your implementation is correct, I'd still expect to see segmentation faults.
After all, you're telling the kernel that you don't want to be allowed to write to any part of your memory. Afterwards, you'll just continue to run your process and the next time you try to write anything at all you'll get a segmentation fault because that's no longer allowed.
That'll most likely be when you return from mprotect() after "protecting" the stack.
Thinking a bit more, it's even possible that you're getting segmentation faults while executing memory (i.e. a shared lib, or your executable code) after you've "protected" it.
In fact, all of the bits of memory where it's safe to apply read-only / do-not-execute flags already have those flags set.
I suspect that's the insight this univerity project was meant to give you.