Any C compiler with the option to space out variables?

M

mathog

I have run into one of those horrible bugs where the placement of
print statements affects a calculation. These always come down to
memory access issues or uninitialized variables, and this one is giving
me conniptions. The code does not generate any compiler warnings with
-Wall, nor any errors that gdb or Valgrind will flag, and adding range
check code before every array access did not show any out of range
memory accesses. The next step is to pull the code out of the larger
program and test it separately, where perhaps changing optimization
switches will let valgrind see something.

This did bring up an interesting point though. Valgrind will say when a
program accesses uninitialized memory or unallocated memory.
Neither are happening here, so the memory error is probably of
the type where a memory access goes to the wrong place, but there is a
valid variable there. In order to find this one would need a way to
move the memory which is used around, and especially to space it out,
such that something like:

int a,b,c; /* 4 byte integers */
double d; /* 8 byte doubles */

which is normally stored like:

a 0-3
b 4-7
c 8-11
d 12-19

is instead stored spaced out like:

- 0-16
a 16-19
- 20-31
b 32-35
- 36-47
c 48-51
- 52-55
d 60-67
- 68-71
- 72-87

A 32 or 64 byte space might be even better. If laid out in that manner,
with uninitialized, unused memory between the variables, valgrind might
find the problem.

Are there any compilers that have a switch that will induce this sort of
intentionally unpacked memory organization?

(Manually inserting dummy variables in all those positions might work,
although it would be a painful editing exercise, but more likely the
compiler would warn about them and then optimize those variables
out of existence.)

Thanks,

David Mathog
 
M

mathog

mathog said:
The next step is to pull the code out of the larger
program and test it separately, where perhaps changing optimization
switches will let valgrind see something.

Where it works perfectly with all levels of optimization tested, with or
without the extra printf() statements. So no way to duplicate the
problem with the simpler test case.

This is going to be a long day.

David Mathog
 
E

Eric Sosman

I have run into one of those horrible bugs where the placement of
print statements affects a calculation. These always come down to
memory access issues or uninitialized variables, and this one is giving
me conniptions. The code does not generate any compiler warnings with
-Wall, nor any errors that gdb or Valgrind will flag, and adding range
check code before every array access did not show any out of range
memory accesses. The next step is to pull the code out of the larger
program and test it separately, where perhaps changing optimization
switches will let valgrind see something.

This did bring up an interesting point though. Valgrind will say when a
program accesses uninitialized memory or unallocated memory.
Neither are happening here, so the memory error is probably of
the type where a memory access goes to the wrong place, but there is a
valid variable there. In order to find this one would need a way to
move the memory which is used around, and especially to space it out,
such that something like:

int a,b,c; /* 4 byte integers */
double d; /* 8 byte doubles */

which is normally stored like:

a 0-3
b 4-7
c 8-11
d 12-19

is instead stored spaced out like:

- 0-16
a 16-19
- 20-31
b 32-35
- 36-47
c 48-51
- 52-55
d 60-67
- 68-71
- 72-87

A 32 or 64 byte space might be even better. If laid out in that manner,
with uninitialized, unused memory between the variables, valgrind might
find the problem.

Are there any compilers that have a switch that will induce this sort of
intentionally unpacked memory organization?

(Manually inserting dummy variables in all those positions might work,
although it would be a painful editing exercise, but more likely the
compiler would warn about them and then optimize those variables
out of existence.)

Compilers with such options may exist, although I don't
recall encountering one. If you resort to manual insertion,
there's a more reliable technique than just tossing variables
in and hoping the compiler (1) puts them where you want and
(2) doesn't optimize them away:

typedef char Spacer[16];
struct {
Spacer x1;
int a;
Spaces x2;
int b;
Spacer x3;
int c;
Spacer x4;
double d;
Spacer x5;
} vars;
#define a vars.a
#define b vars.b
#define c vars.c
#define d vars.d

Alternatively,

struct {
Spacer x1;
int value;
Spacer x2;
} x_a;
#define a x_a.value
// ... and so on

An editor with mild programmability and macro prowess might be
able to handle the latter form fairly painlessly.
 
R

Rox

maybe you should double check your print first.
without strong type check, printf maybe work unusual in some circumstanes
 
W

Walter Banks

Eric said:
I have run into one of those horrible bugs where the placement of
print statements affects a calculation. These always come down to
memory access issues or uninitialized variables, and this one is giving
me conniptions. The code does not generate any compiler warnings with
-Wall, nor any errors that gdb or Valgrind will flag, and adding range
check code before every array access did not show any out of range
memory accesses. The next step is to pull the code out of the larger
program and test it separately, where perhaps changing optimization
switches will let valgrind see something.

This did bring up an interesting point though. Valgrind will say when a
program accesses uninitialized memory or unallocated memory.
Neither are happening here, so the memory error is probably of
the type where a memory access goes to the wrong place, but there is a
valid variable there. In order to find this one would need a way to
move the memory which is used around, and especially to space it out,
such that something like:

int a,b,c; /* 4 byte integers */
double d; /* 8 byte doubles */

which is normally stored like:

a 0-3
b 4-7
c 8-11
d 12-19

is instead stored spaced out like:

- 0-16
a 16-19
- 20-31
b 32-35
- 36-47
c 48-51
- 52-55
d 60-67
- 68-71
- 72-87

A 32 or 64 byte space might be even better. If laid out in that manner,
with uninitialized, unused memory between the variables, valgrind might
find the problem.

Are there any compilers that have a switch that will induce this sort of
intentionally unpacked memory organization?

(Manually inserting dummy variables in all those positions might work,
although it would be a painful editing exercise, but more likely the
compiler would warn about them and then optimize those variables
out of existence.)

Compilers with such options may exist, although I don't
recall encountering one. If you resort to manual insertion,
there's a more reliable technique than just tossing variables
in and hoping the compiler (1) puts them where you want and
(2) doesn't optimize them away:

typedef char Spacer[16];
struct {
Spacer x1;
int a;
Spaces x2;
int b;
Spacer x3;
int c;
Spacer x4;
double d;
Spacer x5;
} vars;
#define a vars.a
#define b vars.b
#define c vars.c
#define d vars.d

Alternatively,

struct {
Spacer x1;
int value;
Spacer x2;
} x_a;
#define a x_a.value
// ... and so on

An editor with mild programmability and macro prowess might be
able to handle the latter form fairly painlessly.

Quite a few C compilers including ours has the ability to place
variables at specific locations.

Eric's suggestion to create a struct is a good one to force
any C compiler to put gaps between variables.

Walter Banks
Byte Craft Limited
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,480
Members
44,900
Latest member
Nell636132

Latest Threads

Top