Skip to content

Instantly share code, notes, and snippets.

@uucidl
Last active August 20, 2017 17:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uucidl/7a9dddd89a29354875d97575a90e8936 to your computer and use it in GitHub Desktop.
Save uucidl/7a9dddd89a29354875d97575a90e8936 to your computer and use it in GitHub Desktop.
Reproduction of an optimizer bug with Visual Studio 2017
/* Repro optimizer issue with Visual Studio 2017 */
/* @language: c99 */
/*
# Visual Studio 2015 (working)
--
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\cl.exe
cl.exe -Fe:repro.exe repro.c -nologo -FC -EHsc -Z7 -Oi -GR- -Gm- -O2 -Z7 -W4 -WX -DEBUG
TEST repro.exe
Event layout:
int_count: [0x08,0x09)
int_values: [0x0c,0x18)
int_values[0]: [0x0c,0x10)
int_values[1]: [0x10,0x14)
---
Event:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0x0000 20 00 00 00 00 00 00 00 01 CD CD CD 2A 00 00 00
0x0010 CD CD CD CD CD CD CD CD
---
exited with code 0
0xCD is memory that wasn't touched.
int_count is 0x01 (1 argument)
int_values[0]: is 0x2A, which is our sentinel value
# Visual Studio 2017 (broken)
D:\Visual Studio 2017\VC\Tools\MSVC\14.10.25017\bin\HostX64\x64\cl.exe
cl.exe -Fe:repro.exe -nologo -FC -EHsc -Z7 -Oi -GR- -Gm- -O2 -Z7 -W4 -WX -DEBUG repro.c
TEST repro.exe
Event layout:
int_count: [0x08,0x09)
int_values: [0x0c,0x18)
int_values[0]: [0x0c,0x10)
int_values[1]: [0x10,0x14)
---
Event:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0x0000 20 00 00 00 00 00 00 00 01 CD CD CD CD CD CD CD
0x0010 2A 00 00 00 CD CD CD CD
---
Assertion failed: event->int_values[0] == 42, file repro.c, line 111
ERROR: Test failed
exited with code -1073740791
0xCD is memory that wasn't touched.
int_count is 0x01 (1 argument, correct)
int_values[0]: is 0xCD. Our sentinel value has been put instead at int_values[1]!
*/
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
struct SPDR_Event {
unsigned long long ts_ticks;
char int_count;
int int_values[3];
};
static int equal_zstring(char const* a, char const *b) { return strcmp(a, b) == 0; }
static void print_hexdump(unsigned char* bytes, size_t bytes_n, unsigned int offset_base);
int main(int argc, char** argv)
{
(void) argc;
(void) argv;
/* print record layout */ {
printf("Event layout:\n");
#define OP(m) printf("%20s: [0x%02x,0x%02x)\n", #m, \
(unsigned int) offsetof(struct SPDR_Event, m), \
(unsigned int) (offsetof(struct SPDR_Event, m) + \
sizeof ((struct SPDR_Event*)0)->m))
OP(int_count);
OP(int_values);
OP(int_values[0]);
OP(int_values[1]);
#undef OP
printf("---\n");
fflush(stdout);
}
int clock_tick = 32;
struct SPDR_Event event_on_stack;
/* create event */ {
memset(&event_on_stack, 0xCD, sizeof event_on_stack);
{
event_on_stack.ts_ticks = clock_tick++;
event_on_stack.int_count = 0;
}
{
int i = event_on_stack.int_count++;
event_on_stack.int_values[i] = 42;
}
}
/* inspect event afterwards */ {
struct SPDR_Event* event = &event_on_stack;
printf("Event:\n");
print_hexdump((unsigned char*)event, sizeof *event, 0);
printf("---\n");
fflush(stdout);
assert(event->int_count == 1);
assert(event->int_values[0] == 42);
}
return 0;
}
static void print_hexdump(unsigned char* bytes, size_t bytes_n, unsigned int offset_base)
{
unsigned char* bytes_l = bytes + bytes_n;
unsigned int row_offset = offset_base;
printf(" ");
{
unsigned int n = 0;
while(n < 8) {
printf(" %02x", n);
++n;
}
printf(" ");
while(n < 16) {
printf(" %02x", n);
++n;
}
printf("\n");
}
while (bytes != bytes_l) {
int n = 8;
printf("0x%04x", row_offset);
while (n-- && bytes != bytes_l) {
printf(" %02X", *bytes); ++bytes;
}
printf(" ");
n = 8;
while (n-- && bytes != bytes_l) {
printf(" %02X", *bytes); ++bytes;
}
printf ("\n");
row_offset += 16;
}
}
@McMartin
Copy link

McMartin commented Aug 20, 2017

@uucidl: this has been fixed in the latest release, i.e. Visual Studio 2017 version 15.3.1 (released on August 18, 2017). I tried specifically with that compiler:

D:\dev>where cl
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\bin\HostX64\x64\cl.exe

D:\dev>cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25506 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

usage: cl [ option... ] filename... [ /link linkoption... ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment