SlideShare uma empresa Scribd logo
1 de 4
Baixar para ler offline
Undefined behavior is closer than you
think
Author: Andrey Karpov
Date: 05.02.2016
Some people think that undefined behavior is caused only by gross errors (accessing outside the bounds
of the array, for instance) or inadequate constructions (i = i++ + ++i, for example). That's why it is quite
surprising when a programmer sees undefined behavior in the code that used to work correctly, without
arousing any suspicion. One should never let his guard down, programming in C/C++. Because hell is
closer than you may think.
Error description
It's been a while since I've written anything on the topic of 64-bit errors. It's time to relive a bit of the
past. In this case undefined will appear in a 64-bit program.
Consider incorrect synthetic code fragment.
size_t Count = 1024*1024*1024; // 1 Gb
if (is64bit)
Count *= 5; // 5 Gb
char *array = (char *)malloc(Count);
memset(array, 0, Count);
int index = 0;
for (size_t i = 0; i != Count; i++)
array[index++] = char(i) | 1;
if (array[Count - 1] == 0)
printf("The last array element contains 0.n");
free(array);
This code works correctly if the programmer compiles a 32-bit version of the program. But if you
compile the 64-bit program, everything is way more interesting.
64-bit program allocates a 5 gigabyte array/buffer and initially fills it with zeros. The loop then modifies
it, filling it with non-zero values we use "| 1" to ensure this.
And now try to guess how the code will run if it is compiled in x64 mode using Visual Studio 2015? Have
you got the answer? If yes, then let's continue.
If you run a debug version of this program, it'll crash because it'll index out of bounds At some point the
index variable will overflow and its value will become −2147483648 (INT_MIN).
Sounds logical, right? Nothing of the kind! This is an undefined behavior and really anything can happen.
Additional links:
 Integer overflow
 Understanding Integer Overflow in C/C++
 Is signed integer overflow still undefined behavior in C++?
When I or somebody else says that this is an example of undefined behavior, people start grumbling. I
don't know why, but it feels like they assume that they know absolutely everything about C++ and how
compilers work.
Usually we get comments like:
"This is some theoretical nonsense. Well, yes, formally the 'int' overflow leads to an undefined behavior.
But it's nothing more but some jabbering. In practice, we can always tell what we will get. If you add 1 to
INT_MAX then we'll have INT_MIN. Maybe somewhere in the universe there are some exotic
architectures, but my Visual C++ / GCC compiler gives a correct result."
And now without any magic, I will give a demonstration of UB using a simple example and not on some
fairy architecture either, but a Win64-program.
It would be enough to build the example given above in the Release x64 mode and run it. The program
will cease crashing and the warning "the last array element contains 0" won't be issued.
The undefined behavior reveals itself in the following way. The array will be completely filled, in spite of
the fact that index variable isn't wide enough to index all the array elements. Those who still don't
believe me should have a look at the assembly code:
int index = 0;
for (size_t i = 0; i != Count; i++)
000000013F6D102D xor ecx,ecx
000000013F6D102F nop
array[index++] = char(i) | 1;
000000013F6D1030 movzx edx,cl
000000013F6D1033 or dl,1
000000013F6D1036 mov byte ptr [rcx+rbx],dl
000000013F6D1039 inc rcx
000000013F6D103C cmp rcx,rdi
000000013F6D103F jne main+30h (013F6D1030h)
Here is the UB! And no exotic compilers were used, it's just VS2015.
If you replace 'int' with 'unsigned' the undefined behavior will disappear. The array will be only partially
filled and at the end we will have a message - "the last array element contains 0".
Assembly code with the 'unsigned':
unsigned index = 0;
000000013F07102D xor r9d,r9d
for (size_t i = 0; i != Count; i++)
000000013F071030 mov ecx,r9d
000000013F071033 nop dword ptr [rax]
000000013F071037 nop word ptr [rax+rax]
array[index++] = char(i) | 1;
000000013F071040 movzx r8d,cl
000000013F071044 mov edx,r9d
000000013F071047 or r8b,1
000000013F07104B inc r9d
000000013F07104E inc rcx
000000013F071051 mov byte ptr [rdx+rbx],r8b
000000013F071055 cmp rcx,rdi
000000013F071058 jne main+40h (013F071040h)
Notes about PVS-Studio
PVS-Studio analyzer doesn't detect character variable overflow straight away. This is not a very
rewarding job. It's almost impossible to predict what value one or another variable will have or if the
overflow will or will not occur. However, the analyzer can track down some erroneous patterns that it
refers to as "64-bit errors".
To tell the truth, there are no 64-bit errors. There are just those that are connected with undefined
behavior, that have been hibernating in 32-bit code, and these then show up when we recompile in x64
mode. But if we speak about UB, it wouldn't sound very interesting and people won't buy it (PVS-Studio
that is). On top of it all, they won't believe that there are any issues with it. But if the analyzer says that
this variable can overflow in the loop, and it is a "64-bit error", then it's a different story. Profit.
The code we gave above is considered incorrect by the analyzer, and it issues a warning related to 64-bit
portability issues. The idea is the following: In Win32 mode size_t is 32-bits and we cannot allocate a 5
gigabyte array, so everything works fine. In Win64, where size_t is 64-bits, we work with a bigger array,
which requires more memory. So the 64-bit code won't work. 32-bit code works, but the 64-bit code
fails. PVS-Studio calls it a 64-bit error.
Here are diagnostic messages that PVS-Studio will issue for the code given in th ebeginning:
 V127 An overflow of the 32-bit 'index' variable is possible inside a long cycle which utilizes a
memsize-type loop counter. consoleapplication1.cpp 16
 V108 Incorrect index type: array[not a memsize-type]. Use memsize type instead.
consoleapplication1.cpp 16
More details about 64-bit traps:
 Development of 64-bit C/C++ applications
 A 64-bit horse that can count
 A Collection of Examples of 64-bit Errors in Real Programs
 C++11 and 64-bit Issues
Correct code
You must use proper data types for your programs to run properly. If you are going to work with large-
size arrays, forget about int and unsigned. The proper types are ptrdiff_t, intptr_t, size_t, DWORD_PTR,
std::vector::size_type and so on. In this case it is size_t:
size_t index = 0;
for (size_t i = 0; i != Count; i++)
array[index++] = char(i) | 1;
Conclusion
If the C++ language rules result in undefined behavior, don't argue with them or try to predict the way
they'll behave in the future. Just don't write such dangerous code.
There are a whole lot of stubborn programmers who don't want to see anything suspicious in shifting
negative numbers, comparing 'this' with null or signed types overflowing.
Don't be like that. The fact that the program is working now doesn't mean that everything is fine. The
way UB will reveal itself is impossible to predict. Expected program behavior is one of the variants of UB.

Mais conteúdo relacionado

Mais procurados

Hennchthree 160912095304
Hennchthree 160912095304Hennchthree 160912095304
Hennchthree 160912095304
marangburu42
 
10 ipt python exam breakdown
10 ipt python exam breakdown10 ipt python exam breakdown
10 ipt python exam breakdown
hccit
 
Java Questioner for
Java Questioner for Java Questioner for
Java Questioner for
Abhay Korat
 
Ques c++ minhnd
Ques c++   minhndQues c++   minhnd
Ques c++ minhnd
Congdat Le
 
C# programming datatypes
C# programming  datatypesC# programming  datatypes
C# programming datatypes
성진 원
 

Mais procurados (20)

Lesson 9. Pattern 1. Magic numbers
Lesson 9. Pattern 1. Magic numbersLesson 9. Pattern 1. Magic numbers
Lesson 9. Pattern 1. Magic numbers
 
Static code analysis and the new language standard C++0x
Static code analysis and the new language standard C++0xStatic code analysis and the new language standard C++0x
Static code analysis and the new language standard C++0x
 
Static code analysis and the new language standard C++0x
Static code analysis and the new language standard C++0xStatic code analysis and the new language standard C++0x
Static code analysis and the new language standard C++0x
 
A collection of examples of 64 bit errors in real programs
A collection of examples of 64 bit errors in real programsA collection of examples of 64 bit errors in real programs
A collection of examples of 64 bit errors in real programs
 
Comparison of analyzers' diagnostic possibilities at checking 64-bit code
Comparison of analyzers' diagnostic possibilities at checking 64-bit codeComparison of analyzers' diagnostic possibilities at checking 64-bit code
Comparison of analyzers' diagnostic possibilities at checking 64-bit code
 
Lesson 11. Pattern 3. Shift operations
Lesson 11. Pattern 3. Shift operationsLesson 11. Pattern 3. Shift operations
Lesson 11. Pattern 3. Shift operations
 
Type Conversion in C++ and C# Arithmetic Expressions
Type Conversion in C++ and C# Arithmetic ExpressionsType Conversion in C++ and C# Arithmetic Expressions
Type Conversion in C++ and C# Arithmetic Expressions
 
Hennchthree
HennchthreeHennchthree
Hennchthree
 
Hennchthree 160912095304
Hennchthree 160912095304Hennchthree 160912095304
Hennchthree 160912095304
 
10 ipt python exam breakdown
10 ipt python exam breakdown10 ipt python exam breakdown
10 ipt python exam breakdown
 
The static code analysis rules for diagnosing potentially unsafe construction...
The static code analysis rules for diagnosing potentially unsafe construction...The static code analysis rules for diagnosing potentially unsafe construction...
The static code analysis rules for diagnosing potentially unsafe construction...
 
C programming part4
C programming part4C programming part4
C programming part4
 
Program errors occurring while porting C++ code from 32-bit platforms on 64-b...
Program errors occurring while porting C++ code from 32-bit platforms on 64-b...Program errors occurring while porting C++ code from 32-bit platforms on 64-b...
Program errors occurring while porting C++ code from 32-bit platforms on 64-b...
 
20 issues of porting C++ code on the 64-bit platform
20 issues of porting C++ code on the 64-bit platform20 issues of porting C++ code on the 64-bit platform
20 issues of porting C++ code on the 64-bit platform
 
Java Questioner for
Java Questioner for Java Questioner for
Java Questioner for
 
Quiz test JDBC
Quiz test JDBCQuiz test JDBC
Quiz test JDBC
 
Ques c++ minhnd
Ques c++   minhndQues c++   minhnd
Ques c++ minhnd
 
Lesson 14. Pattern 6. Changing an array's type
Lesson 14. Pattern 6. Changing an array's typeLesson 14. Pattern 6. Changing an array's type
Lesson 14. Pattern 6. Changing an array's type
 
C# programming datatypes
C# programming  datatypesC# programming  datatypes
C# programming datatypes
 
Manoch1raw 160512091436
Manoch1raw 160512091436Manoch1raw 160512091436
Manoch1raw 160512091436
 

Destaque

A Guide to SlideShare Analytics - Excerpts from Hubspot's Step by Step Guide ...
A Guide to SlideShare Analytics - Excerpts from Hubspot's Step by Step Guide ...A Guide to SlideShare Analytics - Excerpts from Hubspot's Step by Step Guide ...
A Guide to SlideShare Analytics - Excerpts from Hubspot's Step by Step Guide ...
SlideShare
 

Destaque (19)

200 Open Source Projects Later: Source Code Static Analysis Experience
200 Open Source Projects Later: Source Code Static Analysis Experience200 Open Source Projects Later: Source Code Static Analysis Experience
200 Open Source Projects Later: Source Code Static Analysis Experience
 
The Ultimate Question of Programming, Refactoring, and Everything
The Ultimate Question of Programming, Refactoring, and EverythingThe Ultimate Question of Programming, Refactoring, and Everything
The Ultimate Question of Programming, Refactoring, and Everything
 
200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода200 open source проектов спустя: опыт статического анализа исходного кода
200 open source проектов спустя: опыт статического анализа исходного кода
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
PVS-Studio for Linux (CoreHard presentation)
PVS-Studio for Linux (CoreHard presentation)PVS-Studio for Linux (CoreHard presentation)
PVS-Studio for Linux (CoreHard presentation)
 
PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...PVS-Studio team experience: checking various open source projects, or mistake...
PVS-Studio team experience: checking various open source projects, or mistake...
 
The operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzerThe operation principles of PVS-Studio static code analyzer
The operation principles of PVS-Studio static code analyzer
 
PVS-Studio vs Clang
PVS-Studio vs ClangPVS-Studio vs Clang
PVS-Studio vs Clang
 
How to capture a variable in C# and not to shoot yourself in the foot
How to capture a variable in C# and not to shoot yourself in the footHow to capture a variable in C# and not to shoot yourself in the foot
How to capture a variable in C# and not to shoot yourself in the foot
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
 
PVS-Studio. Static code analyzer. Windows/Linux, C/C++/C#. 2017
PVS-Studio. Static code analyzer. Windows/Linux, C/C++/C#. 2017PVS-Studio. Static code analyzer. Windows/Linux, C/C++/C#. 2017
PVS-Studio. Static code analyzer. Windows/Linux, C/C++/C#. 2017
 
Masters of SlideShare
Masters of SlideShareMasters of SlideShare
Masters of SlideShare
 
What Makes Great Infographics
What Makes Great InfographicsWhat Makes Great Infographics
What Makes Great Infographics
 
STOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
STOP! VIEW THIS! 10-Step Checklist When Uploading to SlideshareSTOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
STOP! VIEW THIS! 10-Step Checklist When Uploading to Slideshare
 
10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization
 
How To Get More From SlideShare - Super-Simple Tips For Content Marketing
How To Get More From SlideShare - Super-Simple Tips For Content MarketingHow To Get More From SlideShare - Super-Simple Tips For Content Marketing
How To Get More From SlideShare - Super-Simple Tips For Content Marketing
 
You Suck At PowerPoint!
You Suck At PowerPoint!You Suck At PowerPoint!
You Suck At PowerPoint!
 
A Guide to SlideShare Analytics - Excerpts from Hubspot's Step by Step Guide ...
A Guide to SlideShare Analytics - Excerpts from Hubspot's Step by Step Guide ...A Guide to SlideShare Analytics - Excerpts from Hubspot's Step by Step Guide ...
A Guide to SlideShare Analytics - Excerpts from Hubspot's Step by Step Guide ...
 
How to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & TricksHow to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & Tricks
 

Semelhante a Undefined behavior is closer than you think

Semelhante a Undefined behavior is closer than you think (20)

Monitoring a program that monitors computer networks
Monitoring a program that monitors computer networksMonitoring a program that monitors computer networks
Monitoring a program that monitors computer networks
 
Monitoring a program that monitors computer networks
Monitoring a program that monitors computer networksMonitoring a program that monitors computer networks
Monitoring a program that monitors computer networks
 
Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errors
 
Optimization in the world of 64-bit errors
Optimization  in the world of 64-bit errorsOptimization  in the world of 64-bit errors
Optimization in the world of 64-bit errors
 
I just had to check ICQ project
I just had to check ICQ projectI just had to check ICQ project
I just had to check ICQ project
 
Lesson 6. Errors in 64-bit code
Lesson 6. Errors in 64-bit codeLesson 6. Errors in 64-bit code
Lesson 6. Errors in 64-bit code
 
The forgotten problems of 64-bit programs development
The forgotten problems of 64-bit programs developmentThe forgotten problems of 64-bit programs development
The forgotten problems of 64-bit programs development
 
Static code analysis for verification of the 64-bit applications
Static code analysis for verification of the 64-bit applicationsStatic code analysis for verification of the 64-bit applications
Static code analysis for verification of the 64-bit applications
 
Safety of 64-bit code
Safety of 64-bit codeSafety of 64-bit code
Safety of 64-bit code
 
64-Bit Code in 2015: New in the Diagnostics of Possible Issues
64-Bit Code in 2015: New in the Diagnostics of Possible Issues64-Bit Code in 2015: New in the Diagnostics of Possible Issues
64-Bit Code in 2015: New in the Diagnostics of Possible Issues
 
Are 64-bit errors real?
Are  64-bit errors real?Are  64-bit errors real?
Are 64-bit errors real?
 
Accord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
Accord.Net: Looking for a Bug that Could Help Machines Conquer HumankindAccord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
Accord.Net: Looking for a Bug that Could Help Machines Conquer Humankind
 
20 issues of porting C++ code on the 64-bit platform
20 issues of porting C++ code on the 64-bit platform20 issues of porting C++ code on the 64-bit platform
20 issues of porting C++ code on the 64-bit platform
 
A nice 64-bit error in C
A  nice 64-bit error in CA  nice 64-bit error in C
A nice 64-bit error in C
 
LibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-StudioLibRaw, Coverity SCAN, PVS-Studio
LibRaw, Coverity SCAN, PVS-Studio
 
Grounded Pointers
Grounded PointersGrounded Pointers
Grounded Pointers
 
Tesseract. Recognizing Errors in Recognition Software
Tesseract. Recognizing Errors in Recognition SoftwareTesseract. Recognizing Errors in Recognition Software
Tesseract. Recognizing Errors in Recognition Software
 
Analysis of Godot Engine's Source Code
Analysis of Godot Engine's Source CodeAnalysis of Godot Engine's Source Code
Analysis of Godot Engine's Source Code
 
64-bit
64-bit64-bit
64-bit
 
Lesson 22. Pattern 14. Overloaded functions
Lesson 22. Pattern 14. Overloaded functionsLesson 22. Pattern 14. Overloaded functions
Lesson 22. Pattern 14. Overloaded functions
 

Mais de Andrey Karpov

Mais de Andrey Karpov (20)

60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста60 антипаттернов для С++ программиста
60 антипаттернов для С++ программиста
 
60 terrible tips for a C++ developer
60 terrible tips for a C++ developer60 terrible tips for a C++ developer
60 terrible tips for a C++ developer
 
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...Ошибки, которые сложно заметить на code review, но которые находятся статичес...
Ошибки, которые сложно заметить на code review, но которые находятся статичес...
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
PVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature OverviewPVS-Studio in 2021 - Feature Overview
PVS-Studio in 2021 - Feature Overview
 
PVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибокPVS-Studio в 2021 - Примеры ошибок
PVS-Studio в 2021 - Примеры ошибок
 
PVS-Studio в 2021
PVS-Studio в 2021PVS-Studio в 2021
PVS-Studio в 2021
 
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
Make Your and Other Programmer’s Life Easier with Static Analysis (Unreal Eng...
 
Best Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' MistakesBest Bugs from Games: Fellow Programmers' Mistakes
Best Bugs from Games: Fellow Programmers' Mistakes
 
Does static analysis need machine learning?
Does static analysis need machine learning?Does static analysis need machine learning?
Does static analysis need machine learning?
 
Typical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and JavaTypical errors in code on the example of C++, C#, and Java
Typical errors in code on the example of C++, C#, and Java
 
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
How to Fix Hundreds of Bugs in Legacy Code and Not Die (Unreal Engine 4)
 
Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?Game Engine Code Quality: Is Everything Really That Bad?
Game Engine Code Quality: Is Everything Really That Bad?
 
C++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical ReviewerC++ Code as Seen by a Hypercritical Reviewer
C++ Code as Seen by a Hypercritical Reviewer
 
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source SoftwareThe Use of Static Code Analysis When Teaching or Developing Open-Source Software
The Use of Static Code Analysis When Teaching or Developing Open-Source Software
 
Static Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal EngineStatic Code Analysis for Projects, Built on Unreal Engine
Static Code Analysis for Projects, Built on Unreal Engine
 
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded SystemsSafety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
Safety on the Max: How to Write Reliable C/C++ Code for Embedded Systems
 
The Great and Mighty C++
The Great and Mighty C++The Great and Mighty C++
The Great and Mighty C++
 
Static code analysis: what? how? why?
Static code analysis: what? how? why?Static code analysis: what? how? why?
Static code analysis: what? how? why?
 
Zero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for youZero, one, two, Freddy's coming for you
Zero, one, two, Freddy's coming for you
 

Último

%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
masabamasaba
 

Último (20)

%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto%in Soweto+277-882-255-28 abortion pills for sale in soweto
%in Soweto+277-882-255-28 abortion pills for sale in soweto
 
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
%+27788225528 love spells in new york Psychic Readings, Attraction spells,Bri...
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
%in Rustenburg+277-882-255-28 abortion pills for sale in Rustenburg
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 

Undefined behavior is closer than you think

  • 1. Undefined behavior is closer than you think Author: Andrey Karpov Date: 05.02.2016 Some people think that undefined behavior is caused only by gross errors (accessing outside the bounds of the array, for instance) or inadequate constructions (i = i++ + ++i, for example). That's why it is quite surprising when a programmer sees undefined behavior in the code that used to work correctly, without arousing any suspicion. One should never let his guard down, programming in C/C++. Because hell is closer than you may think. Error description It's been a while since I've written anything on the topic of 64-bit errors. It's time to relive a bit of the past. In this case undefined will appear in a 64-bit program. Consider incorrect synthetic code fragment. size_t Count = 1024*1024*1024; // 1 Gb if (is64bit) Count *= 5; // 5 Gb char *array = (char *)malloc(Count); memset(array, 0, Count); int index = 0; for (size_t i = 0; i != Count; i++) array[index++] = char(i) | 1; if (array[Count - 1] == 0) printf("The last array element contains 0.n");
  • 2. free(array); This code works correctly if the programmer compiles a 32-bit version of the program. But if you compile the 64-bit program, everything is way more interesting. 64-bit program allocates a 5 gigabyte array/buffer and initially fills it with zeros. The loop then modifies it, filling it with non-zero values we use "| 1" to ensure this. And now try to guess how the code will run if it is compiled in x64 mode using Visual Studio 2015? Have you got the answer? If yes, then let's continue. If you run a debug version of this program, it'll crash because it'll index out of bounds At some point the index variable will overflow and its value will become −2147483648 (INT_MIN). Sounds logical, right? Nothing of the kind! This is an undefined behavior and really anything can happen. Additional links:  Integer overflow  Understanding Integer Overflow in C/C++  Is signed integer overflow still undefined behavior in C++? When I or somebody else says that this is an example of undefined behavior, people start grumbling. I don't know why, but it feels like they assume that they know absolutely everything about C++ and how compilers work. Usually we get comments like: "This is some theoretical nonsense. Well, yes, formally the 'int' overflow leads to an undefined behavior. But it's nothing more but some jabbering. In practice, we can always tell what we will get. If you add 1 to INT_MAX then we'll have INT_MIN. Maybe somewhere in the universe there are some exotic architectures, but my Visual C++ / GCC compiler gives a correct result." And now without any magic, I will give a demonstration of UB using a simple example and not on some fairy architecture either, but a Win64-program. It would be enough to build the example given above in the Release x64 mode and run it. The program will cease crashing and the warning "the last array element contains 0" won't be issued. The undefined behavior reveals itself in the following way. The array will be completely filled, in spite of the fact that index variable isn't wide enough to index all the array elements. Those who still don't believe me should have a look at the assembly code: int index = 0; for (size_t i = 0; i != Count; i++) 000000013F6D102D xor ecx,ecx 000000013F6D102F nop array[index++] = char(i) | 1; 000000013F6D1030 movzx edx,cl 000000013F6D1033 or dl,1 000000013F6D1036 mov byte ptr [rcx+rbx],dl 000000013F6D1039 inc rcx
  • 3. 000000013F6D103C cmp rcx,rdi 000000013F6D103F jne main+30h (013F6D1030h) Here is the UB! And no exotic compilers were used, it's just VS2015. If you replace 'int' with 'unsigned' the undefined behavior will disappear. The array will be only partially filled and at the end we will have a message - "the last array element contains 0". Assembly code with the 'unsigned': unsigned index = 0; 000000013F07102D xor r9d,r9d for (size_t i = 0; i != Count; i++) 000000013F071030 mov ecx,r9d 000000013F071033 nop dword ptr [rax] 000000013F071037 nop word ptr [rax+rax] array[index++] = char(i) | 1; 000000013F071040 movzx r8d,cl 000000013F071044 mov edx,r9d 000000013F071047 or r8b,1 000000013F07104B inc r9d 000000013F07104E inc rcx 000000013F071051 mov byte ptr [rdx+rbx],r8b 000000013F071055 cmp rcx,rdi 000000013F071058 jne main+40h (013F071040h) Notes about PVS-Studio PVS-Studio analyzer doesn't detect character variable overflow straight away. This is not a very rewarding job. It's almost impossible to predict what value one or another variable will have or if the overflow will or will not occur. However, the analyzer can track down some erroneous patterns that it refers to as "64-bit errors". To tell the truth, there are no 64-bit errors. There are just those that are connected with undefined behavior, that have been hibernating in 32-bit code, and these then show up when we recompile in x64 mode. But if we speak about UB, it wouldn't sound very interesting and people won't buy it (PVS-Studio that is). On top of it all, they won't believe that there are any issues with it. But if the analyzer says that this variable can overflow in the loop, and it is a "64-bit error", then it's a different story. Profit. The code we gave above is considered incorrect by the analyzer, and it issues a warning related to 64-bit portability issues. The idea is the following: In Win32 mode size_t is 32-bits and we cannot allocate a 5 gigabyte array, so everything works fine. In Win64, where size_t is 64-bits, we work with a bigger array, which requires more memory. So the 64-bit code won't work. 32-bit code works, but the 64-bit code fails. PVS-Studio calls it a 64-bit error. Here are diagnostic messages that PVS-Studio will issue for the code given in th ebeginning:
  • 4.  V127 An overflow of the 32-bit 'index' variable is possible inside a long cycle which utilizes a memsize-type loop counter. consoleapplication1.cpp 16  V108 Incorrect index type: array[not a memsize-type]. Use memsize type instead. consoleapplication1.cpp 16 More details about 64-bit traps:  Development of 64-bit C/C++ applications  A 64-bit horse that can count  A Collection of Examples of 64-bit Errors in Real Programs  C++11 and 64-bit Issues Correct code You must use proper data types for your programs to run properly. If you are going to work with large- size arrays, forget about int and unsigned. The proper types are ptrdiff_t, intptr_t, size_t, DWORD_PTR, std::vector::size_type and so on. In this case it is size_t: size_t index = 0; for (size_t i = 0; i != Count; i++) array[index++] = char(i) | 1; Conclusion If the C++ language rules result in undefined behavior, don't argue with them or try to predict the way they'll behave in the future. Just don't write such dangerous code. There are a whole lot of stubborn programmers who don't want to see anything suspicious in shifting negative numbers, comparing 'this' with null or signed types overflowing. Don't be like that. The fact that the program is working now doesn't mean that everything is fine. The way UB will reveal itself is impossible to predict. Expected program behavior is one of the variants of UB.