gdb use calculation of one command as an argument to another - memory

I'm trying to show a memory print out of the current stack frame, but right now what I have to do is laborious:
# Find out how big the current frame is:
(gdb) print/x $ebp - $esp
$1 = 0x4
# Use that in a display:
(gdb) x/4x $ebp
I'd love to use the define command to make it so this just happens after every step, so I have a constant awareness of the stack frame.
Doing things like these:
(gdb) x/$1x $ebp
(gdb) x/($1)x $ebp
hasn't worked.

In GDB, command x is used to examine the memory with the arguments as follows,
x
x address
x/nfu address
Where n is repeat count, f is display format & u is unit size;
(gdb) p/x $rsp
$4 = 0x7fffffffe248
(gdb) x/4x 0x7fffffffe248
0x7fffffffe248: 0xffffe4e5 0x00007fff 0x00000000 0x00000000
(gdb) x/$4
0x7fffffffe248: 0xffffe4e5
(gdb) x/$4x
Value can't be converted to integer.
(gdb) x/$4 $rsp
A syntax error in expression, near `$rsp'.
(gdb) x/$_
0x7fffffffe248: 0xffffe4e5
Observe the last command x/$_ in which after x, the last address examined is available for use in expressions using $_ variable.
EDIT: The memory content of address produced by variable $_ is given by variable $__.

Related

Memory allocation when a pointer is assigned

I am trying to avoid memory allocation and local copy in my code. Below is a small example :
module test
implicit none
public
integer, parameter :: nb = 1000
type :: info
integer n(nb)
double precision d(nb)
end type info
type(info), save :: abc
type(info), target, save :: def
contains
subroutine test_copy(inf)
implicit none
type(info), optional :: inf
type(info) :: local
if (present(inf)) then
local = inf
else
local = abc
endif
local%n = 1
local%d = 1.d0
end subroutine test_copy
subroutine test_assoc(inf)
implicit none
type(info), target, optional :: inf
type(info), pointer :: local
if (present(inf)) then
local => inf
else
local => def
endif
local%n = 1
local%d = 1.d0
end subroutine test_assoc
end module test
program run
use test
use caliper_mod
implicit none
type(ConfigManager), save :: mgr
abc%n = 0
abc%d = 0.d0
def%n = 0
def%d = 0.d0
! Init caliper profiling
mgr = ConfigManager_new()
call mgr%add("runtime-report(mem.highwatermark,output=stdout)")
call mgr%start
! Call subroutine with copy
call cali_begin_region("test_copy")
call test_copy()
call cali_end_region("test_copy")
! Call subroutine with pointer
call cali_begin_region("test_assoc")
call test_assoc()
call cali_end_region("test_assoc")
! End caliper profiling
call mgr%flush()
call mgr%stop()
call mgr%delete()
end program run
As far as i understand, the subroutine test_copy should produce a local copy while the subroutine test_assoc should only assign a pointer to some existing object. However, memory profiling with caliper leads to :
$ ./a.out
Path Min time/rank Max time/rank Avg time/rank Time % Allocated MB
test_assoc 0.000026 0.000026 0.000026 0.493827 0.000021
test_copy 0.000120 0.000120 0.000120 2.279202 0.000019
What looks odd is that Caliper shows the exact same amount of memory allocated whatever the value of the parameter nb. Am I using the right tool the right way to track memory allocation and local copy ?
Test performed with gfortran 11.2.0 and Caliper 2.8.0.
The local object is just a simple small scalar, albeit containing an array component, and will be very likely placed on the stack.
A stack is a pre-allocated part of memory of fixed size. Stack "allocation" is actually just a change of value of the stack pointer which is just one integer value. No actual memory allocation from the operating system takes place during stack allocation. There will be no change in the memory the process occupies.

How can I write bytes to memory using gdb?

Related to this question: In gdb, how can I write a string to memory?
However, my question is regarding how to write non-ASCII characters as well, which I'm having trouble with.
Not only does it seem like I have to specify the number of characters I want to write with
set {char[<number of characters>]}, but I don't seem able to escape characters in my string.
Consider:
set {char [5]} 0x618204 = "ABCD"
This should be equivalent:
set {char [5]} 0x618204 = "ABC\x44"
There is no error, but this treats the string as something else entirely, I'm not even sure what this does.
How can I write a string with escaped characters like this, I want some way to write arbitrary bytes to memory, preferably without needing to tell GDB beforehand how many bytes I intend to write.
I'd like something simple like:
set 0x618204 = \x41\x42\x43\x44\x45
This should write the bytes 0x41 0x42 0x43 0x44 0x45 to memory, starting at the address 0x618204.
Am I just missing the correct syntax for this, or doesn't it exist? Is there some extension to GDB that can do it? gef, peda?
There is no error, but this treats the string as something else entirely
No, it doesn't:
(gdb) start
Temporary breakpoint 1 at 0x1129: file t.c, line 3.
Starting program: /tmp/a.out
Temporary breakpoint 1, main () at t.c:3
3 char buf[] = "abcd";
(gdb) n
4 void *p = buf;
(gdb) n
5 return 0;
(gdb) p p
$1 = (void *) 0x7fffffffdb93
(gdb) p {char[4]}p
$2 = "abcd"
(gdb) set {char[4]}p = "ABC\x44"
Too many array elements
The error here is because char[4] doesn't account for terminating NUL.
(gdb) set {char[5]}p = "ABC\x44"
(gdb) p buf
$3 = "ABCD"
Voila!
You can write in memory with GDB using the set command:
Here is an example of how to change a single byte in memory with GDB:
pwndbg> x/bx 0x7fffffffdb7f
0x7fffffffdb7f: 0x30
pwndbg> set *0x7fffffffdb7f=0x00
pwndbg> x/bx 0x7fffffffdb7f
0x7fffffffdb7f: 0x00
You can also write multiple bytes, but you have to be aware of endianess.
pwndbg> set *0x7fffffffdb78=0x00414243
pwndbg> x/s 0x7fffffffdb78
0x7fffffffdb78: "CBA"
pwndbg> set *0x7fffffffdb78=0x0068732f6e69622f
pwndbg> x/s 0x7fffffffdb78
0x7fffffffdb78: "/bin/sh"

DTrace build in built-in variable stackdepth always return 0

I am recently using DTrace to analyze my iOS app。
Everything goes well except when I try to use the built-in variable stackDepth。
I read the document here where shows the introduction of built-in variable stackDepth.
So I write some D code
pid$target:::entry
{
self->entry_times[probefunc] = timestamp;
}
pid$target:::return
{
printf ("-----------------------------------\n");
this->delta_time = timestamp - self->entry_times[probefunc];
printf ("%s\n", probefunc);
printf ("stackDepth %d\n", stackdepth);
printf ("%d---%d\n", this->delta_time, epid);
ustack();
printf ("-----------------------------------\n");
}
And run it with sudo dtrace -s temp.d -c ./simple.out。 unstack() function goes very well, but stackDepth always appears to 0。
I tried both on my iOS app and a simple C program.
So anybody knows what's going on?
And how to get stack depth when the probe fires?
You want to use ustackdepth -- the user-land stack depth.
The stackdepth variable refers to the kernel thread stack depth; the ustackdepth variable refers to the user-land thread stack depth. When the traced program is executing in user-land, stackdepth will (should!) always be 0.
ustackdepth is calculated using the same logic as is used to walk the user-land stack as with ustack() (just as stackdepth and stack() use similar logic for the kernel stack).
This seems like a bug in the Mac / iOS implementation of DTrace to me.
However, since you're already probing every function entry and return, you could just keep a new variable self->depth and do ++ in the :::entry probe and -- in the :::return probe. This doesn't work quite right if you run it against optimized code, because any tail-call-optimized functions may look like they enter but never return. To solve that, you can turn off optimizations.
Also, because what you're doing looks a lot like this, I thought maybe you would be interested in the -F option:
Coalesce trace output by identifying function entry and return.
Function entry probe reports are indented and their output is prefixed
with ->. Function return probe reports are unindented and their output
is prefixed with <-.
The normal script to use with -F is something like:
pid$target::some_function:entry { self->trace = 1 }
pid$target:::entry /self->trace/ {}
pid$target:::return /self->trace/ {}
pid$target::some_function:return { self->trace = 0 }
Where some_function is the function whose execution you want to be printed. The output shows a textual call graph for that execution:
-> some_function
-> another_function
-> malloc
<- malloc
<- another_function
-> yet_another_function
-> strcmp
<- strcmp
-> malloc
<- malloc
<- yet_another_function
<- some_function

LLDB evaluations run out of memory on iOS. How can I free some memory?

In LLDB console on iOS, I repeated
(lldb) p/x $r1
(unsigned int) $1 = 0x07000006
(lldb) p/x $r1
(unsigned int) $2 = 0x07000006
(lldb) p/x $r1
(unsigned int) $3 = 0x07000006
...etc
about 1500 times, and finally got the following error message
error: Couldn't allocate space for the stack frame: Couldn't malloc: address space is full
Errored out in Execute, couldn't PrepareToExecuteJITExpression
As far as I understand it, each time I run p/x $r1, the debugger evaluates $r1 as an expression and allocates a buffer in a memory for a temporary variable $N (where N = 1, 2, 3, ...). After about 1500 evaluations, the debugger run out of memory and can't allocate buffers anymore.
My question is how can I free some memory? E.g. if I do not need the temporary variable $1 anymore, can I do something like free($1)? Are there any "secret" lldb commands for that?
Thanks in advance for your answers.
Are you doing p/x $r1 because you need to preserve value of $r1 in a temporary, or do you just want to see its value? If the latter, you can use:
(lldb) register read/x r1
which can be shortened to:
(lldb) re r/x r1
That directly prints the register without constructing a temporary. Similarly, if you just want to see the value of a local variable:
(lldb) frame variable foo
will print the value of foo without going through the full expression parser.
Note, there is also a bug in the current lldb that causes expressions to allocate way more memory than they need to - 1500 expressions is too few for you to really be running out of memory, even on a 32 bit system... That's been fixed in the lldb.llvm.org sources, but I don't know when the fix will make its way into a release.
There isn't currently a way to tell lldb either not to make, or to discard, these convenience variables. There's no reason this couldn't be done, there just hasn't been a need for it.

What does the gdb 'x' command do?

In my quest to learn more about the computer in general, I stumbled upon a book which has some chapters about disassembling, the x86 assembly language, and the relationship between C and x86 assembly. Now I have been reading this GDB command but I am unable to fully understand it.
The command, along with its results, follows:
(gdb) x/32xw $esp
0xbffff7e0: 0xb8000ce0 0x08048510 0xbffff848 0xb7eafebc
0xbffff7f0: 0x00000002 0xbffff874 0xbffff880 0xb8001898
0xbffff800: 0x00000000 0x00000001 0x00000001 0x00000000
0xbffff810: 0xb7fd6ff4 0xb8000ce0 0x00000000 0xbffff848
0xbffff820: 0x40f5f7f0 0x48e0fe81 0x00000000 0x00000000
0xbffff830: 0x00000000 0xb7ff9300 0xb7eafded 0xb8000ff4
0xbffff840: 0x00000002 0x08048350 0x00000000 0x08048371
0xbffff850: 0x08048474 0x00000002 0xbffff874 0x08048510
Now, from what I understand, the command that I issue tells the debugger to:
x (first one): examine the memory
32: get 32 of what follows
x: enable hexadecimal representation
w: show me Word size data.
**Note:** I know that I ask about the esp register, but I don't quite fully understand what $ is doing in front of it. When I try not to use it, I get a missing symbol error, so I get it has something to do with reference/de-reference?
What has been bugging me is how did I find all those bytes? Since I am examining a register, who's size is 32 bit, shouldn't I get only 32 bits, or 4 bytes (only 1 row of the above)? If I am correct with my assumption, then were did we find the rest of the data? Does it have to do something with the stack, and a particular stack frame, which I currently am unaware of?
I would appreciate your input so that I can clarify things in my mind.
(gdb) help x
Examine memory: x/FMT ADDRESS.
Giving $esp as the address will make gdb fetch whatever is in that register and use that as the memory address for the x command - and will show you the following 32 words in memory starting at that address.
variables within gdb itself are names prefixed with a $ , gdb sets up predefined variables for all the cpu registers.
If you want to inspect the esp register, use the command info registers esp, as you'll see with your example (x/32xw $esp), the esp register contains the first address shown, 0xbffff7e0
It's giving you 32 words of memory where the esp register is pointing (apparently that register contains the address 0xbffff7e0).
(gdb) x/32xw $esp
it means show me the 32 words field where esp points.
pieces:32,
format:hex ,
size:word (1 word= 32 bit on gdb)
show me the 32 words field where esp points
(hex)0xbffff7e0 - (hex)0xbffff7f0 = (dec)3221223392 - (dec)3221223408 = 16bytes=4words

Resources