Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a pointer value change just by passing it to another function?

Tags:

c

pointers

gdb

I am debugging my function A with GDB, and just before calling function B, I print the following value:

p *(key->s->fds[3].handler)

and I get as a result: (these are all function pointers)

$3 = {handle_read = 0x55555555ba49 <socks5_read>, handle_write = 0x55555555baa2 <socks5_write>, handle_block = 0x55555555bb0a <socks5_block>, handle_close = 0x55555555bb15 <socks5_close>}

Then, I type s to enter function B with GDB. Immediately after, I print p *(key->s->fds[3].handler) again, but its value is:

$4 = {handle_read = 0x7fffffffdb90, handle_write = 0x5555baa2, handle_block = 0x55555555bb0a <socks5_block>, handle_close = 0x55555555bb15 <socks5_close>}

I know that this question is really open, because I should show some of my code. But my question is general: Is it possible that the contents of my struct change just by passing a pointer to a function?

If it helps, this is the complete trace of what I've done in GDB:

(gdb) s
31              stm->current->on_arrival(stm->current->state, key);
(gdb) p *(key->s->fds[3].handler)
$3 = {handle_read = 0x55555555ba49 <socks5_read>, handle_write = 0x55555555baa2 <socks5_write>, handle_block = 0x55555555bb0a <socks5_block>, 
  handle_close = 0x55555555bb15 <socks5_close>}
(gdb) s
hello_read_init (state=0, key=0x7fffffffdb90) at src/stm/stm_hello.c:20
20      hello_stm *hello_stm = &ATTACHMENT(key)->hello_state;
(gdb) p *(key->s->fds[3].handler)
$4 = {handle_read = 0x7fffffffdb90, handle_write = 0x5555baa2, handle_block = 0x55555555bb0a <socks5_block>, 
  handle_close = 0x55555555bb15 <socks5_close>}

1 Answers

Is it possible that the contents of my struct change just by passing a pointer to a function?

There are 3 possible reasons I can think of (most to least likely):

  1. Your program has undefined behavior of the stack use after scope variety.
    That is, if key->s->fds[3].handler points to stack of a frame which has already returned, that stack will be overwritten by subsequent call instructions.
  2. You didn't step far enough.
    If the called function is optimized, it is possible for GDB to stop in hello_read_init prolog (area where registers aren't yet set up).
  3. You have a multithreaded program and a data race (another thread overwrites key->s->fds[3].handler->handle_read while the first thread uses it).

Using Address Sanitizer should show whether this is an instance of UB (the first possibility above) right away.

like image 139
Employed Russian Avatar answered Jun 07 '26 23:06

Employed Russian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!