0

This is a debugging problem I've been trying to solve. I know the bit mask I need to apply to make b equal a. I inspected with gdb to find the difference between a and b. The variables b and a are char[] types and set prior to reaching the 'bug'.

#include <string.h>

int main() {
  char a[1] = "a";
  char b[1] = "b";
  int *x;
  x = (int *) b;
  // bug in next line
  *x = *x & 0xffffffff;
  return memcmp(a, b, 1);
}

Until a equals b, I can't solve the problem. The only constraint given is that the bug is in the line noted, no other code is to be changed. There is no rule saying I can't add lines after the bug, though and before the memcmp().The issue I find is that nothing I do to the bit mask changes the value of b, ever. I've set breakpoints and inspected the value of x and *x before and after the bug, but x seems to not change.

Breakpoint 1, main () at test.c:9
9     *x = *x & 0xffffffff;
(gdb) print (int) a
$1 = -6922
(gdb) print (int) b
$2 = -6921
(gdb) print (int) x
$3 = -6921
(gdb) step

Breakpoint 2, main () at test.c:10
10    return memcmp(a, b, 1);
(gdb) print (int) a
$4 = -6922
(gdb) print (int) b
$5 = -6921
(gdb) print (int) x
$6 = -6921

I don't see how this can be solved the way requested, by modifying the constant in the line where the bug is. Any help to understand how to use x to update b using a bitwise mask would be appreciated.

mike_b
  • 2,127
  • 5
  • 20
  • 25
  • As you did tag C++: don't use C-style casts. In this case, you would have to use `reinterpret_cast` to make it compile. Whenever you use that keyword and do not positively know why it is safe, the code should be assumed wrong! – Neil Kirk Sep 05 '15 at 03:42
  • I don't believe your edit. The output from the debugger isn't consistent with the code. – Mark Ransom Sep 05 '15 at 03:46
  • correct, it was an example, I converted into a minimal, complete example. so the integer values shown are not representative of the actual values of "a" and "b", etc. – mike_b Sep 05 '15 at 04:10
  • 2
    This program is so messed up it's not even wrong. Just delete it and start over. There are so many levels of UB, it's not rescuable. You are dereferencing `*x` even though it does not point to an `int`. Even if you ignore the strict aliasing rules, it's still UB, because it's pointing to a buffer that is smaller than `sizeof(int)`. And even if you ignore that issue, it's still UB because `char` has different alignment from `int`. And even if you ignore that issue, it's dependent upon processor endianness. This program has no reason to exist. Put it out of its misery. – Raymond Chen Sep 05 '15 at 04:56
  • 1
    You're printing three addresses; `&a[0]`, `&b[0]`, and `x`. It should come as no surprise that those are unaffected by anything you do to `*x`. (And for a 32-bit `i`, `i & 0xffffffff` is equivalent to `i`.) – molbdnilo Sep 05 '15 at 06:36
  • "*I know the bit mask I need to apply to make `b` equal `a`*" which mask and which operation do you plan to use? – alk Sep 05 '15 at 07:06
  • @RaymondChen The program is meant to be a minimal representation of the issue. It wasn't meant to have a purpose other than to illustrate that it is not updating the value of b. They are dereferenced as ints to more easily show their binary representation, the readable type value doesn't matter. I'm not sure what you mean by "UB", I assume undefined behavior. Again, read the post that this was a debugging problem, it is not meant to have a purpose beyond that. And, its not my problem, I've just been told the constant can be changed to make a equal b. – mike_b Sep 05 '15 at 19:37
  • If this is a debugging problem, then the question would be "Why is b changing to a?" or "How can I fix the program so I don't corrupt a?" Not "How can I alter this program's behavior to be even more undefined?" – Raymond Chen Sep 06 '15 at 04:27

2 Answers2

1

You are trying to change the address of b but in

*x = *x & 0xffffffff;

You are changing the value because you are dereferencing x. Yyou need to apply the manipulation to x itself like

x = x & 0xffffffff;

And then you need to reassign x into b.

This will run afoul of the strict aliasing rules.

Community
  • 1
  • 1
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
  • What do you mean by "out of scope"? It's your program..Change anything you want. (If this is homework, then check your school's academic honesty policy. You will probably need to cite this Web site when you submit your homework. And I doubt "posting the question on the Internet and copying the answer" will be looked upon very favorably.) – Raymond Chen Sep 05 '15 at 14:16
  • What do you think I mean by "out of scope"? What do you think I mean by stating it is "debugging problem" or by pointing out which line the "bug" is in? This is a problem (not homework but school related) given to me to solve under the instructions that I only need to change the bitmask to solve it. Hence me stating "I know the bit mask I need to apply to make b equal a." My question on SO is laying doubt that there is actually a solution here because `*x` has nothing to do with `b` when modified. But it is better to ask before claiming to a PhD that their pointer logic is wrong. – mike_b Sep 05 '15 at 19:30
1

x is a pointer; casting it to an int simply gives you the address as a decimal number.

a and b are both arrays, which will decay to a pointer when you do operations that require a pointer. By casting them to int you're again getting the address of the variable. The address doesn't change with the operation you're performing, even when the contents at that address changes.

Since a and b are both smaller than an int, your code is likely to mess up in ways that are extremely painful. Even if they were the right size, this isn't guaranteed to do the right thing.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622