SlideShare une entreprise Scribd logo
1  sur  52
Patterns of 64-bit errors in
games
Andrey Karpov
karpov@viva64.com
Speaker
• Karpov Andrey Nikolaevich
• Habr profile: habr.com/users/Andrey2008/
• Microsoft MVP, Intel Black Belt Software Developer
• One of the founders of the PVS-Studio project, which
started right from the search of 64-bit errors
• https://www.viva64.com
Technically speaking, there are no
«64-bit errors»
In practice
• 64-bit errors are the ones which reveal themselves after building a
64-bit application
• By the way, many of them do it only when the 4 Gigabyte limit is
exceeded
Explanation on the example of malloc
• Who will notice an error?
void Foo()
{
const size_t Gigabyte = 1073741824;
void *A[10];
for (size_t i = 0; i < 10; ++i)
{
A[i] = malloc(Gigabyte);
printf("%pn", A[i]);
}
for (size_t i = 0; i < 10; ++i)
free(A[i]);
}
In C-code developers forget to include
headers
• Your program might not contain calls of malloc, but they might be in
third-party libraries
• It is revealed only when consuming large amount of memory
#include <stdio.h>
#include <string.h>
//#include <stdlib.h>
The case isn’t only about malloc
• Fennec Media
• memset
• memcpy
• Ffdshow (media decoder)
• memset
• memcpy
• libZPlay
• strlen
Let’s get back to implicit
truncation of 64-bit values
long type in Win64
const std::vector<Vec2> &vertexList =
body->getCalculatedVertexList();
unsigned long length = vertexList.size();
PVS-Studio: V103 Implicit type conversion from memsize to 32-bit type.
CCArmature.cpp 614
Cocos2d-x
int type is a bad idea in any case
PVS-Studio: V104 Implicit conversion of 'i' to memsize type in an arithmetic
expression: i < points_.size() sweep_context.cc 76
std::vector<Point*> points_;
void SweepContext::InitTriangulation()
{
// Calculate bounds.
for (unsigned int i = 0; i < points_.size(); i++) {
Point& p = *points_[i];
....
Cocos2d-x
By the way, such errors are more insidious
than it looks
• When overflowing int, undefined behavior occurs
• UB might be the case when everything works correctly :)
• More details: "Undefined behavior is closer than you think"
https://www.viva64.com/ru/b/0374/
size_t N = foo();
for (int i = 0; i < N; ++i)
Usage of correct memsize-types
"memsize" types
• ptrdiff_t - signed type (distance between pointers)
• size_t – maximum size of theoretically possible object of any type,
including arrays
• rsize_t – size of a single object
• intptr_t - signed type, can store a pointer
• uintptr_t – unsigned type, can store a pointer
Usage of memsize-types
• Number of elements in an array
• Buffer size
• Counters
• Pointer storing (although, it’s better not to do it)
• Pointer arithmetic
• And so on
Using of memsize-types: bad thing
PVS-Studio: V109 Implicit type conversion of return value 'a * b * c' to memsize
type. test.cpp 22
Potential overflow
size_t Foo(int a, int b, int c)
{
return a * b * c;
}
Using of memsize-types: OK
size_t Foo(int a, int b, int c)
{
return static_cast<size_t>(a)
* static_cast<size_t>(b)
* static_cast<size_t>(c);
}
size_t Foo(int a, int b, int c)
{
return static_cast<size_t>(a) * b * c;
}
JUST DON’T DO IT!
std::vector<unsigned char> buf(
static_cast<size_t>(exr_image->width * h * pixel_data_size));
PVS-Studio: V1028 CWE-190 Possible overflow. Consider casting operands, not the
result. tinyexr.h 11682
Possible
overflow again
TinyEXR
This way errors only hide more
if (components == 1) {
images[0].resize(static_cast<size_t>(width * height));
memcpy(images[0].data(), data, sizeof(float) * size_t(width * height));
} else {
images[0].resize(static_cast<size_t>(width * height));
images[1].resize(static_cast<size_t>(width * height));
images[2].resize(static_cast<size_t>(width * height));
images[3].resize(static_cast<size_t>(width * height));
for (size_t i = 0; i < static_cast<size_t>(width * height); i++) {
TinyEXR
More about pointer arithmetic
int A = -2;
unsigned B = 1;
int array[5] = { 1, 2, 3, 4, 5 };
int *ptr = array + 3;
ptr = ptr + (A + B);
printf("%in", *ptr); //Access violation
//on 64-bit platform
Developers forget to expand 32-bit
types
int64_t X = 1 << N
• This code doesn’t work in 32-bit programs as well
• Setting most significant bits is usually not needed there
class FMallocBinned : public FMalloc
{
uint64 PoolMask;
....
FMallocBinned(uint32 InPageSize, uint64 AddressLimit)
{
....
PoolMask = (( 1 << ( HashKeyShift - PoolBitShift ) ) - 1);
....
}
};
Unreal Engine 4
PVS-Studio: V629 Consider inspecting the '1 << (HashKeyShift - PoolBitShift)'
expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-
bit type. mallocbinned.h 800
class FMallocBinned : public FMalloc
{
uint64 PoolMask;
....
FMallocBinned(uint32 InPageSize, uint64 AddressLimit)
{
....
PoolMask = (( 1ULL << ( HashKeyShift - PoolBitShift ) ) - 1);
....
}
};
Unreal Engine 4
Godot Engine
void vp9_adjust_mask(....) {
....
const uint64_t columns = cm->mi_cols - mi_col;
const uint64_t mask_y =
(((1 << columns) - 1)) * 0x0101010101010101ULL;
....
}
PVS-Studio: V629 CWE-190 Consider inspecting the '1 << columns'
expression. Bit shifting of the 32-bit value with a subsequent expansion to
the 64-bit type. vp9_loopfilter.c 851
size_t N = ~0U;
• In 32-bit code everything is OK
• 64-bit code, expectation: 0xFFFFFFFFFFFFFFFF
• 64-bit code, reality: 0x00000000FFFFFFFF
size_t nRenderMeshSize = ~0U;
PVS-Studio: V101 Implicit assignment type conversion to memsize type.
StatObjLoad.cpp 1369
CryEngine
size_t N = ~(1024u - 1);
• In 32-bit code everything is OK
• 64-bit code, expectation: 0xFFFFFFFFFFFFFC00
• 64-bit code, reality: 0x00000000FFFFFC00
static const UINT_PTR SmallBlockAlignMask = ~(SmallBlockLength - 1);
FreeBlockHeader* InsertFreeBlock(FreeBlockHeader* after,
UINT_PTR start, UINT_PTR end)
{
bool isFreeBlockDone = (start & SmallBlockAlignMask) ==
(end & SmallBlockAlignMask) ||
(start > end - (SmallBlockLength / 2));
....
}
CryEngine
Increased consumption of the
stack and dynamic memory
Stack
• I suggest taking it easy and just increase it by 2 times :)
Dynamic memory
• Is it worth doing some fighting?
• Are 64-bit integer types needed everywhere?
• Are the pointers needed everywhere?
• Structures’ size
Redundant growth of structures’ size
struct Candidate {
uint32_t face;
ChartBuildData *chart;
float metric;
};
PVS-Studio: V802 On 64-bit platform, structure size can be reduced from 24 to 16
bytes by rearranging the fields according to their sizes in decreasing order. xatlas.cpp
5237
24 bytes
Redundant growth of structures’ size
struct Candidate {
ChartBuildData *chart;
uint32_t face;
float metric;
};
16 bytes
Other error patterns
Magic constants
• 1024 x 768
• 1600 x 1200
Magic constants
• 1024 x 768
• 1600 x 1200
• 4
• 32
• 0x7FFFFFFF
• 0x80000000
• 0xFFFFFFFF
Dangerous tricks with type casting
ResourceBase::Header *header = (*iter).value;
char fourCC[ 5 ];
*( ( U32* ) fourCC ) = header->getSignature();
fourCC[ 4 ] = 0;
Everything will be fine thanks to header, but still very unstable.
PVS-Studio: V1032 The pointer 'fourCC' is cast to a more strictly aligned pointer
type. resourceManager.cpp 127
Torque 3D
Data serialization
• No specific errors and tips
• Review the code
Arrays of various types
Virtual functions
Virtual functions
How to write a 64-bit program of
high-quality?
Specify the code standard
• Use correct types:
ptrdiff_t, size_t, intptr_t, uintptr_t, INT_PTR, DWORD_PTR и т.д.
• Say «NO!» to magic numbers. Use this:
UINT_MAX, ULONG_MAX, std::numeric_limits<size_t>::max() и т.д.
• Explain how to correctly use the explicit type casting in the
expressions and what’s the difference between 1 and
static_cast<size_t>(1)
• unsigned long != size_t
Tooling: unit-tests
Tooling: dynamic analyzers
Tooling: static analyzers
Conclusion
• Even if you already have released a 64-bit application, this doesn’t
mean that it works correctly
• A 64-bit error can lie low for ages
• How to solve the situation:
• learning
• Code standard
• Static code analysis
Useful links
• Lessons on development of 64-bit C/C++ applications (single file)
https://www.viva64.com/ru/l/full/
• A Collection of Examples of 64-bit Errors in Real Programs
https://www.viva64.com/ru/a/0065/
• Undefined behavior is closer than you think
https://www.viva64.com/ru/b/0374/
Time for your questions!
Andrey Karpov
karpov@viva64.com
www.viva64.com

Contenu connexe

Tendances

IonMonkey Mozilla All-Hands 2011
IonMonkey Mozilla All-Hands 2011IonMonkey Mozilla All-Hands 2011
IonMonkey Mozilla All-Hands 2011
iamdvander
 

Tendances (20)

WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装
 
Vectorization with LMS: SIMD Intrinsics
Vectorization with LMS: SIMD IntrinsicsVectorization with LMS: SIMD Intrinsics
Vectorization with LMS: SIMD Intrinsics
 
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
Abstracting Vector Architectures in Library Generators: Case Study Convolutio...
 
Happy To Use SIMD
Happy To Use SIMDHappy To Use SIMD
Happy To Use SIMD
 
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
 
AA-sort with SSE4.1
AA-sort with SSE4.1AA-sort with SSE4.1
AA-sort with SSE4.1
 
A (brief) overview of Span<T>
A (brief) overview of Span<T>A (brief) overview of Span<T>
A (brief) overview of Span<T>
 
IonMonkey Mozilla All-Hands 2011
IonMonkey Mozilla All-Hands 2011IonMonkey Mozilla All-Hands 2011
IonMonkey Mozilla All-Hands 2011
 
Egor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizationsEgor Bogatov - .NET Core intrinsics and other micro-optimizations
Egor Bogatov - .NET Core intrinsics and other micro-optimizations
 
Practical Two-level Homomorphic Encryption in Prime-order Bilinear Groups
Practical Two-level Homomorphic Encryption in Prime-order Bilinear GroupsPractical Two-level Homomorphic Encryption in Prime-order Bilinear Groups
Practical Two-level Homomorphic Encryption in Prime-order Bilinear Groups
 
Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”Bartosz Milewski, “Re-discovering Monads in C++”
Bartosz Milewski, “Re-discovering Monads in C++”
 
To Swift 2...and Beyond!
To Swift 2...and Beyond!To Swift 2...and Beyond!
To Swift 2...and Beyond!
 
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
 
Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and...
Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and...Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and...
Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and...
 
PVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around DisneyPVS-Studio for Linux Went on a Tour Around Disney
PVS-Studio for Linux Went on a Tour Around Disney
 
25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах
 
Implementation of Bitcoin Miner on SW and HW
Implementation of Bitcoin Miner on SW and HWImplementation of Bitcoin Miner on SW and HW
Implementation of Bitcoin Miner on SW and HW
 
Exploiting vectorization with ISPC
Exploiting vectorization with ISPCExploiting vectorization with ISPC
Exploiting vectorization with ISPC
 
暗認本読書会4
暗認本読書会4暗認本読書会4
暗認本読書会4
 
Pwning in c++ (basic)
Pwning in c++ (basic)Pwning in c++ (basic)
Pwning in c++ (basic)
 

Similaire à Patterns of 64-bit errors in games

Things to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit SoftwareThings to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit Software
Andrey Karpov
 
Jurczyk windows kernel reference count vulnerabilities. case study
Jurczyk   windows kernel reference count vulnerabilities. case studyJurczyk   windows kernel reference count vulnerabilities. case study
Jurczyk windows kernel reference count vulnerabilities. case study
DefconRussia
 

Similaire à Patterns of 64-bit errors in games (20)

Things to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit SoftwareThings to Remember When Developing 64-bit Software
Things to Remember When Developing 64-bit Software
 
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
 
An Open Discussion of RISC-V BitManip, trends, and comparisons _ Claire
 An Open Discussion of RISC-V BitManip, trends, and comparisons _ Claire An Open Discussion of RISC-V BitManip, trends, and comparisons _ Claire
An Open Discussion of RISC-V BitManip, trends, and comparisons _ Claire
 
Some examples of the 64-bit code errors
Some examples of the 64-bit code errorsSome examples of the 64-bit code errors
Some examples of the 64-bit code errors
 
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
 
100 bugs in Open Source C/C++ projects
100 bugs in Open Source C/C++ projects 100 bugs in Open Source C/C++ projects
100 bugs in Open Source C/C++ projects
 
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
 
embedded C.pptx
embedded C.pptxembedded C.pptx
embedded C.pptx
 
PVS-Studio, a solution for developers of modern resource-intensive applications
PVS-Studio, a solution for developers of modern resource-intensive applicationsPVS-Studio, a solution for developers of modern resource-intensive applications
PVS-Studio, a solution for developers of modern resource-intensive applications
 
Interview with Anatoliy Kuznetsov, the author of BitMagic C++ library
Interview with Anatoliy Kuznetsov, the author of BitMagic C++ libraryInterview with Anatoliy Kuznetsov, the author of BitMagic C++ library
Interview with Anatoliy Kuznetsov, the author of BitMagic C++ library
 
The reasons why 64-bit programs require more stack memory
The reasons why 64-bit programs require more stack memoryThe reasons why 64-bit programs require more stack memory
The reasons why 64-bit programs require more stack memory
 
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
 
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
 
Critical errors in CryEngine V code
Critical errors in CryEngine V codeCritical errors in CryEngine V code
Critical errors in CryEngine V 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
 
C++ in Action Webinar: Move your C++ projects to C++Builder 10 Seattle
C++ in Action Webinar: Move your C++ projects to C++Builder 10 SeattleC++ in Action Webinar: Move your C++ projects to C++Builder 10 Seattle
C++ in Action Webinar: Move your C++ projects to C++Builder 10 Seattle
 
Jurczyk windows kernel reference count vulnerabilities. case study
Jurczyk   windows kernel reference count vulnerabilities. case studyJurczyk   windows kernel reference count vulnerabilities. case study
Jurczyk windows kernel reference count vulnerabilities. case study
 
Deep hooks
Deep hooksDeep hooks
Deep hooks
 
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
 

Plus de Andrey Karpov

Plus 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?
 
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
 
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOpsPVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
PVS-Studio Is Now in Chocolatey: Checking Chocolatey under Azure DevOps
 

Dernier

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 

Dernier (20)

%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
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
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
%in Lydenburg+277-882-255-28 abortion pills for sale in Lydenburg
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
%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
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 

Patterns of 64-bit errors in games

  • 1. Patterns of 64-bit errors in games Andrey Karpov karpov@viva64.com
  • 2.
  • 3. Speaker • Karpov Andrey Nikolaevich • Habr profile: habr.com/users/Andrey2008/ • Microsoft MVP, Intel Black Belt Software Developer • One of the founders of the PVS-Studio project, which started right from the search of 64-bit errors • https://www.viva64.com
  • 4. Technically speaking, there are no «64-bit errors»
  • 5. In practice • 64-bit errors are the ones which reveal themselves after building a 64-bit application • By the way, many of them do it only when the 4 Gigabyte limit is exceeded
  • 6. Explanation on the example of malloc • Who will notice an error?
  • 7. void Foo() { const size_t Gigabyte = 1073741824; void *A[10]; for (size_t i = 0; i < 10; ++i) { A[i] = malloc(Gigabyte); printf("%pn", A[i]); } for (size_t i = 0; i < 10; ++i) free(A[i]); }
  • 8.
  • 9. In C-code developers forget to include headers • Your program might not contain calls of malloc, but they might be in third-party libraries • It is revealed only when consuming large amount of memory #include <stdio.h> #include <string.h> //#include <stdlib.h>
  • 10. The case isn’t only about malloc • Fennec Media • memset • memcpy • Ffdshow (media decoder) • memset • memcpy • libZPlay • strlen
  • 11. Let’s get back to implicit truncation of 64-bit values
  • 12. long type in Win64 const std::vector<Vec2> &vertexList = body->getCalculatedVertexList(); unsigned long length = vertexList.size(); PVS-Studio: V103 Implicit type conversion from memsize to 32-bit type. CCArmature.cpp 614 Cocos2d-x
  • 13. int type is a bad idea in any case PVS-Studio: V104 Implicit conversion of 'i' to memsize type in an arithmetic expression: i < points_.size() sweep_context.cc 76 std::vector<Point*> points_; void SweepContext::InitTriangulation() { // Calculate bounds. for (unsigned int i = 0; i < points_.size(); i++) { Point& p = *points_[i]; .... Cocos2d-x
  • 14. By the way, such errors are more insidious than it looks • When overflowing int, undefined behavior occurs • UB might be the case when everything works correctly :) • More details: "Undefined behavior is closer than you think" https://www.viva64.com/ru/b/0374/ size_t N = foo(); for (int i = 0; i < N; ++i)
  • 15. Usage of correct memsize-types
  • 16. "memsize" types • ptrdiff_t - signed type (distance between pointers) • size_t – maximum size of theoretically possible object of any type, including arrays • rsize_t – size of a single object • intptr_t - signed type, can store a pointer • uintptr_t – unsigned type, can store a pointer
  • 17. Usage of memsize-types • Number of elements in an array • Buffer size • Counters • Pointer storing (although, it’s better not to do it) • Pointer arithmetic • And so on
  • 18. Using of memsize-types: bad thing PVS-Studio: V109 Implicit type conversion of return value 'a * b * c' to memsize type. test.cpp 22 Potential overflow size_t Foo(int a, int b, int c) { return a * b * c; }
  • 19. Using of memsize-types: OK size_t Foo(int a, int b, int c) { return static_cast<size_t>(a) * static_cast<size_t>(b) * static_cast<size_t>(c); } size_t Foo(int a, int b, int c) { return static_cast<size_t>(a) * b * c; }
  • 20. JUST DON’T DO IT! std::vector<unsigned char> buf( static_cast<size_t>(exr_image->width * h * pixel_data_size)); PVS-Studio: V1028 CWE-190 Possible overflow. Consider casting operands, not the result. tinyexr.h 11682 Possible overflow again TinyEXR
  • 21. This way errors only hide more if (components == 1) { images[0].resize(static_cast<size_t>(width * height)); memcpy(images[0].data(), data, sizeof(float) * size_t(width * height)); } else { images[0].resize(static_cast<size_t>(width * height)); images[1].resize(static_cast<size_t>(width * height)); images[2].resize(static_cast<size_t>(width * height)); images[3].resize(static_cast<size_t>(width * height)); for (size_t i = 0; i < static_cast<size_t>(width * height); i++) { TinyEXR
  • 22. More about pointer arithmetic int A = -2; unsigned B = 1; int array[5] = { 1, 2, 3, 4, 5 }; int *ptr = array + 3; ptr = ptr + (A + B); printf("%in", *ptr); //Access violation //on 64-bit platform
  • 23. Developers forget to expand 32-bit types
  • 24. int64_t X = 1 << N • This code doesn’t work in 32-bit programs as well • Setting most significant bits is usually not needed there
  • 25. class FMallocBinned : public FMalloc { uint64 PoolMask; .... FMallocBinned(uint32 InPageSize, uint64 AddressLimit) { .... PoolMask = (( 1 << ( HashKeyShift - PoolBitShift ) ) - 1); .... } }; Unreal Engine 4 PVS-Studio: V629 Consider inspecting the '1 << (HashKeyShift - PoolBitShift)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64- bit type. mallocbinned.h 800
  • 26. class FMallocBinned : public FMalloc { uint64 PoolMask; .... FMallocBinned(uint32 InPageSize, uint64 AddressLimit) { .... PoolMask = (( 1ULL << ( HashKeyShift - PoolBitShift ) ) - 1); .... } }; Unreal Engine 4
  • 27. Godot Engine void vp9_adjust_mask(....) { .... const uint64_t columns = cm->mi_cols - mi_col; const uint64_t mask_y = (((1 << columns) - 1)) * 0x0101010101010101ULL; .... } PVS-Studio: V629 CWE-190 Consider inspecting the '1 << columns' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. vp9_loopfilter.c 851
  • 28. size_t N = ~0U; • In 32-bit code everything is OK • 64-bit code, expectation: 0xFFFFFFFFFFFFFFFF • 64-bit code, reality: 0x00000000FFFFFFFF
  • 29. size_t nRenderMeshSize = ~0U; PVS-Studio: V101 Implicit assignment type conversion to memsize type. StatObjLoad.cpp 1369 CryEngine
  • 30. size_t N = ~(1024u - 1); • In 32-bit code everything is OK • 64-bit code, expectation: 0xFFFFFFFFFFFFFC00 • 64-bit code, reality: 0x00000000FFFFFC00
  • 31. static const UINT_PTR SmallBlockAlignMask = ~(SmallBlockLength - 1); FreeBlockHeader* InsertFreeBlock(FreeBlockHeader* after, UINT_PTR start, UINT_PTR end) { bool isFreeBlockDone = (start & SmallBlockAlignMask) == (end & SmallBlockAlignMask) || (start > end - (SmallBlockLength / 2)); .... } CryEngine
  • 32. Increased consumption of the stack and dynamic memory
  • 33. Stack • I suggest taking it easy and just increase it by 2 times :)
  • 34. Dynamic memory • Is it worth doing some fighting? • Are 64-bit integer types needed everywhere? • Are the pointers needed everywhere? • Structures’ size
  • 35. Redundant growth of structures’ size struct Candidate { uint32_t face; ChartBuildData *chart; float metric; }; PVS-Studio: V802 On 64-bit platform, structure size can be reduced from 24 to 16 bytes by rearranging the fields according to their sizes in decreasing order. xatlas.cpp 5237 24 bytes
  • 36. Redundant growth of structures’ size struct Candidate { ChartBuildData *chart; uint32_t face; float metric; }; 16 bytes
  • 38. Magic constants • 1024 x 768 • 1600 x 1200
  • 39. Magic constants • 1024 x 768 • 1600 x 1200 • 4 • 32 • 0x7FFFFFFF • 0x80000000 • 0xFFFFFFFF
  • 40. Dangerous tricks with type casting ResourceBase::Header *header = (*iter).value; char fourCC[ 5 ]; *( ( U32* ) fourCC ) = header->getSignature(); fourCC[ 4 ] = 0; Everything will be fine thanks to header, but still very unstable. PVS-Studio: V1032 The pointer 'fourCC' is cast to a more strictly aligned pointer type. resourceManager.cpp 127 Torque 3D
  • 41. Data serialization • No specific errors and tips • Review the code
  • 45. How to write a 64-bit program of high-quality?
  • 46. Specify the code standard • Use correct types: ptrdiff_t, size_t, intptr_t, uintptr_t, INT_PTR, DWORD_PTR и т.д. • Say «NO!» to magic numbers. Use this: UINT_MAX, ULONG_MAX, std::numeric_limits<size_t>::max() и т.д. • Explain how to correctly use the explicit type casting in the expressions and what’s the difference between 1 and static_cast<size_t>(1) • unsigned long != size_t
  • 50. Conclusion • Even if you already have released a 64-bit application, this doesn’t mean that it works correctly • A 64-bit error can lie low for ages • How to solve the situation: • learning • Code standard • Static code analysis
  • 51. Useful links • Lessons on development of 64-bit C/C++ applications (single file) https://www.viva64.com/ru/l/full/ • A Collection of Examples of 64-bit Errors in Real Programs https://www.viva64.com/ru/a/0065/ • Undefined behavior is closer than you think https://www.viva64.com/ru/b/0374/
  • 52. Time for your questions! Andrey Karpov karpov@viva64.com www.viva64.com