Ok, so I'm trying to learn gdb. I know most of the basics but I have not been able to figure out how to examine a pointer to a pointer in a oneliner. It might be possible by defining a macro/command but I haven't been able to do so.
This question began when learning the cdecl calling convention where $esp contained a pointer to a string, passed as an argument to a function. In order to get this out I had to do the following:
gdb$ x $esp+0x08
0xbffff6a4: 0x980eb192
gdb$ x/s 0x980eb192
0x980eb192: "Hello world"
So, the question is. Can this be done in an easier way? Cutting and pasting just feels too slow.
Appreciate any hints/ideas!
(gdb) x/s *(char**)($esp+8) might do the trick.
You can reuse results of print in subsequent expressions:
(gdb) p *(void **)($esp + 4)
$4 = (void *) 0x80aec48
(gdb) x/s $4
0x80aec48: "alabala"
Related
I have a pointer to a string
void *s = "now is the time for all"
and I wish to print it as an integer of 32-bit size:
gdb) p /x *((int *)s)
What is the equivalence in lldb parlance?
Exactly that, except you can't put a space between the p and the /x.
lldb's command syntax is not the same as lldb's (for more details see:
http://lldb.llvm.org/tutorial.html
) but p (among others) was added (as an alias to the lldb expr command) for people more familiar with gdb's commands. However, to get the /x part working through lldb's command parser it has to be directly postpended to the actual command name so it isn't confused with arguments and options. So:
(lldb) p/x *((int *) text_to_use)
(int) $1 = 0x8f06c8c0
There's also a cheat sheet for lldb <-> gdb commands here:
http://lldb.llvm.org/lldb-gdb.html
which you might find handy.
I was using GDB on a 64-bit machine:
(gdb) show arch
The target architecture is set automatically (currently i386:x86-64)
(gdb) p sizeof(void*)
$1 = 8
I had a pointer stored on 0x600fe8:
(gdb) x /xg 0x600fe8
0x600fe8: 0x00007ffff7bd5680
I tried to examine what the pointer stored here was pointing to, so I used:
(gdb) x *0x600fe8
0xfffffffff7bd5680: Cannot access memory at address 0xfffffffff7bd5680
(gdb) x /g *0x600fe8
0xfffffffff7bd5680: Cannot access memory at address 0xfffffffff7bd5680
It seems that gdb took only 4 bytes as a pointer from 0x600fe8 and sign extended it.
How could I fix this? Thanks.
Research I've done:
Didn't find my scenario on:
GDB doc
Google
Try:
x *(void**)0x600fe8
As #zwol mentioned in the comment, gdb needs type information about the operand to decide its size. This type casting tells gdb that 0x600fe8 is a pointer to a pointer.
When I executed the following code:
AVFrame tmp = frames_video1[k]; //AVFrame frames_video1[]
AVFrame *avf1 = &tmp;
AVFrameSideData* avfsd1=NULL;
if(avf1->side_data != NULL)
printf("avf1->side_data is not NULL!!...........\n");
avfsd1 = av_frame_get_side_data(avf1, AV_FRAME_DATA_MOTION_VECTORS);
I came across segmentation fault happened at av_frame_get_side_data(avf1, AV_FRAME_DATA_MOTION_VECTORS):
avf1->side_data is not NULL!!...........
Segmentation fault (core dumped)
why?
here is the output of gdb:
(gdb) print avf1->side_data->type
Cannot access memory at address 0x0
(gdb) print frames_video1[1]->side_data->type
Cannot access memory at address 0x0
surprisingly, avf1 points to a corrupted frame whose side_data->type is null, which is abnormal. The cause of the issue resides somewhere else.
AVFrame tmp = frames_video1[k]; //AVFrame frames_video1[]
AVFrame *avf1 = &tmp;
You can't do this. I don't know where you learned this, but this is not allowed and fundamentally cannot work. You don't know the size of AVFrame in the application (it is not part of FFmpeg's ABI), so you cannot place a copy on the stack. Instead, do this:
AVFrame *avf1 = frames_video1[k];
Do not ever copy an FFmpeg object on the stack, it will not work. This also means frames_video1[] needs to be an array of AVFrame *, i.e. AVFrame pointers, not an array of AVFrame. If you don't understand why, read about pointers and memory in C and remember again that AVFrame's size is not part of the FFmpeg ABI.
Now, let's debug your object. First, basics of C stack: how many frames are in frames_video1[], and what is k? What is frames_video1[k]->data[0] or frames_video[k]->linesize[0]? Are they legal? Are you sure frames_video1[k] is a legal object? The fact that some copy of non-existing memory is non-NULL means nothing.
Secondly, if the object is legal, what is AVFrame->nb_side_data? You cannot access AVFrame->side_data[] beyond that index.
(gdb) print avf1->side_data->type
You can't do that either. side_data[] is an array of pointers, so instead do this:
(gdb) print avf1->side_data[0]->type
All that said, I again highly recommend you to read up on C pointers and memory allocation, I don't think you entirely understand it. FFmpeg is a very low-level C library and not understanding C will cause lots of grief.
I have run gdb, as my code show segfault. I understand that the code that give the error is
210 if (colour_s->colorlist.colorlist_id == 1)
(gdb) print colour_s
$1 = (car_colour_list_t_slot *) 0x21
(gdb) print colorlist
$2 = (car_colour_list_t *) 0x12d1a80
(gdb) print colour_s->colorlist
Cannot access memory at address 0x21
typedef struct {
int colorlist_id;
} car_colour_list_t;
typedef struct _car_colour_list_t_slot {
car_colour_list_t colorlist;
struct _car_colour_list_t_slot *next, *prev;
} car_colour_list_t_slot;
car_colour_list_t_slot *colour_s;
colour_s = (car_colour_list_t_slot *)malloc(sizeof(car_colour_list_t_slot));
car_colour_list_t *colorlist;
colorlist = (car_colour_list_t *)malloc(sizeof(car_colour_list_t));
I have already assigned those pointers memory, but when I tried to print colour_s->colorlist it fails (can not access memory at address 0x21)
Can anyone understand why this happens, although I have already assign memory to each poitner?
Thank you
The colour_s pointer is definitely invalid. There is no doubt about it. GDB is simply informing you of this fact. (Any pointer near 0x0 is invalid, and any pointer with a residue modulo 4 is invalid for your structure.) The malloc function will never return 0x21.
There are lots of ways your program can do this. They boil down to two basic types of errors in your program:
colour_s was not initialized.
colour_s was initialized, but it was accidentally overwritten by an error in a different part of your code.
there is an error in GDB or your compiler (not worth considering)
Run your program with Valgrind or set a watchpoint on colour_s. These will help you discover where the error is in your code.
As an alternative exercise, see if you can find the error just by reading your code, without running it. Read carefully. This kind of exercise will make you a better programmer.
I am trying to debug a segfault, and I have this output from gdb:
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x08048af9 in parse_option_list (ptr=0x6f72505f <Address 0x6f72505f out of bounds>, box_name=0x696d6978 <Address 0x696d6978 out of bounds>, option_list=0x313a7974,
num_elements=0x33313532) at submit.c:125
125 memcpy(&(option_list[(*num_elements)].value), value, 24);
(gdb) p num_elements
$15 = (int *) 0x33313532
(gdb) p *num_elements
Cannot access memory at address 0x33313532
(gdb)
It looks to me like something in memcpy() is going haywire. But I can't figure out what exactly the problem is, since that line references so many variables.
Can somebody help figure out what the 0x8048af9 in parse_option_list... line is telling me?
My function signature is:
int parse_option_list(char *ptr, char *box_name,
struct option_list_values *option_list, int *num_elements)
And this might be useful:
struct option_list_values {
char value[24];
char name[24];
};
Also, the variables value and name are not segfaulting (but if you think they are, i can post the code which sets those values.) But right now, if I can understand this gdb output, I will be happy as a clam! Thank you!
You have all the signs of a classic buffer overflow. The values of all the stack parameters have been overwritten by ASCII text - here is the translation of those values (assuming you have a little-endian architecture, which looks right):
ptr = 0x6f72505f = "_Pro"
box_name = 0x696d6978 = "ximi"
option_list = 0x313a7974 = "ty:1"
num_elements = 0x33313532 = "2513"
Concatenating them together gives "_Proximity:12513" - if this substring looks familiar to you, you should be able to track down where that data is being copied around - somewhere you are copying it into an array stored on the stack, without proper bounds checking.
0x8048af9 is the instruction pointer - the address of the executable code in memory that your code was at when the SEGFAULT occurred.
Are you sure that option_list[(*num_elements)].value is a valid address? You might have a buffer overflow, and be overwriting something you shouldn't be.
If num_elements is the length of option_list, then option_list[(*num_elements)] refers to just after the end of the list.
ptr=0x6f72505f - Address 0x6f72505f out of bounds
This is the useful part in this case
The first input to parse_option_list is invalid. Possibly an uninitialized pointer.