SlideShare une entreprise Scribd logo
1  sur  77
Самые вкусные баги из игрового кода:
как ошибаются
наши коллеги-программисты
Докладчик:
Георгий Грибков
Докладчик
Георгий Грибков
Программист C++, разработчик
статического анализатора кода
PVS-Studio
Автор статей и докладов о поиске
ошибок в играх (Вангеры, VVVVVV)
и других проектах
с открытым исходным кодом
gribkov@viva64.com
2
1. Как мы ищем ошибки в коде
2. Примеры и разбор найденных ошибок
3. Мысли напоследок
Содержание
3
Как мы ищем ошибки в коде
4
Как мы ищем ошибки в коде
5
Обновляемый список статей
о проверке проектов:
Примеры и разбор найденных ошибок
6
System Shock (Си)
7
fix Terrain( fix X, fix Y, int deriv ) {
if( deriv == 0 )
return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) );
if( deriv == 1 )
return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) );
if( deriv == 2 )
return 0;
return 0;
}
Пример №1
8
fix Terrain( fix X, fix Y, int deriv ) {
if( deriv == 0 )
return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) );
if( deriv == 1 )
return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) );
if( deriv == 2 )
return 0;
return 0;
}
Пример №1
9
V751 Parameter 'Y' is not used
inside function body. BTEST.C 67
fix Terrain( fix X, fix Y, int deriv ) {
if( deriv == 0 )
return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) );
if( deriv == 1 )
return fix_mul( fix_make(0,0x2000), (Y - fix_make(20,0) ) );
if( deriv == 2 )
return 0;
return 0;
}
Пример №1
10
V751 Parameter 'Y' is not used
inside function body. BTEST.C 67
// And here, ladies and gentlemen,
// is a celebration of C and C++ and their untamed
passion...
// ==================
TerrainData terrain_info;
// Now the actual stuff...
// =======================
Забавные комментарии
11
// it's a wonderful world, with a lot of strange men
// who are standing around, and they all wearing towels
// Returns whether or not in the humble opinion of the
// sound system, the sample should be politely
// obliterated out of existence
Забавные комментарии
12
Space
Engineers (C#)
13
if (....)
MySandboxGame.Log.WriteLine(string.Format(
"Could not find any sound for '{0}'", cueName));
else
{
if (....)
string.Format(
"Could not find arcade sound for '{0}'", cueName);
if (....)
string.Format(
"Could not find realistic sound for '{0}'", cueName);
}
Пример №1
14
if (....)
MySandboxGame.Log.WriteLine(string.Format(
"Could not find any sound for '{0}'", cueName));
else
{
if (....)
string.Format(
"Could not find arcade sound for '{0}'", cueName);
if (....)
string.Format(
"Could not find realistic sound for '{0}'", cueName);
}
Пример №1
15
V3010 The return value of function 'Format' is required to
be utilized. Sandbox.Game MyEntity3DSoundEmitter.cs
if (....)
MySandboxGame.Log.WriteLine(string.Format(
"Could not find any sound for '{0}'", cueName));
else
{
if (....)
MySandboxGame.Log.WriteLine(string.Format(
"Could not find arcade sound for '{0}'", cueName));
if (....)
MySandboxGame.Log.WriteLine(string.Format(
"Could not find realistic sound for '{0}'", cueName));
}
Пример №1
16
V3010 The return value of function 'Format' is required to
be utilized. Sandbox.Game MyEntity3DSoundEmitter.cs
var actionsItem = item as MyToolbarItemActions;
if (item != null)
{
if (idx < 0 || idx >= actionsItem
.PossibleActions(....)
.Count)
RemoveToolbarItem(slot);
....
}
Пример №2
17
var actionsItem = item as MyToolbarItemActions;
if (item != null)
{
if (idx < 0 || idx >= actionsItem
.PossibleActions(....)
.Count)
RemoveToolbarItem(slot);
....
}
Пример №2
18
V3019 Possibly an incorrect variable is compared to null after type
conversion using 'as' keyword. Check variables 'item', 'actionsItem'.
Sandbox.Game MyGuiControlToolbar.cs 511
var actionsItem = item as MyToolbarItemActions;
if (item != null)
{
if (idx < 0 || idx >= actionsItem
.PossibleActions(....)
.Count)
RemoveToolbarItem(slot);
....
}
Пример №2
19
V3019 Possibly an incorrect variable is compared to null after type
conversion using 'as' keyword. Check variables 'item', 'actionsItem'.
Sandbox.Game MyGuiControlToolbar.cs 511
var actionsItem = item as MyToolbarItemActions;
if (actionsItem != null)
{
if (idx < 0 || idx >= actionsItem
.PossibleActions(....)
.Count)
RemoveToolbarItem(slot);
....
}
Пример №2
20
V3019 Possibly an incorrect variable is compared to null after type
conversion using 'as' keyword. Check variables 'item', 'actionsItem'.
Sandbox.Game MyGuiControlToolbar.cs 511
C&C: Tiberian Dawn и C&C: Red Alert (C++)
21
// Maximum number of multi players possible.
#define MAX_PLAYERS 8 // max # of players we can have
for (int i = 0; i < MAX_PLAYERS && i < 4; i++) {
if (GlyphxPlayerIDs[i] == player_id) {
MultiplayerStartPositions[i] = XY_Cell(x, y);
}
}
Пример №1
22
// Maximum number of multi players possible.
#define MAX_PLAYERS 8 // max # of players we can have
for (int i = 0; i < MAX_PLAYERS && i < 4; i++) {
if (GlyphxPlayerIDs[i] == player_id) {
MultiplayerStartPositions[i] = XY_Cell(x, y);
}
}
Пример №1
23
V590 Consider inspecting the 'i < 8 && i < 4' expression.
The expression is excessive or contains a misprint.
DLLInterface.cpp 2238
// Maximum number of multi players possible.
#define MAX_PLAYERS 8 // max # of players we can have
for (int i = 0; i < MAX_PLAYERS || i < 4; i++) {
if (GlyphxPlayerIDs[i] == player_id) {
MultiplayerStartPositions[i] = XY_Cell(x, y);
}
}
Пример №1
24
V590 Consider inspecting the 'i < 8 && i < 4' expression.
The expression is excessive or contains a misprint.
DLLInterface.cpp 2238
void * ptr = new char [sizeof(100)];
if (ptr) {
sprintf((char *)ptr,
"%cTrack %dt%d:%02dt%s",
....);
listbox.Add_Item((char const *)ptr);
}
Пример №2
25
void * ptr = new char [sizeof(100)];
if (ptr) {
sprintf((char *)ptr,
"%cTrack %dt%d:%02dt%s",
....);
listbox.Add_Item((char const *)ptr);
}
Пример №2
26
V512 A call of the 'sprintf' function will lead to overflow of
the buffer '(char *) ptr'. SOUNDDLG.CPP 250
void * ptr = new char [100];
if (ptr) {
sprintf((char *)ptr,
"%cTrack %dt%d:%02dt%s",
....);
listbox.Add_Item((char const *)ptr);
}
Пример №2
27
V512 A call of the 'sprintf' function will lead to overflow of
the buffer '(char *) ptr'. SOUNDDLG.CPP 250
28
Doom 3 (C++)
29
for ( j = 0; j < w.GetNumPoints(); j++ ) {
for ( k = 0; k < verts.Num(); j++ ) {
if ( verts[k].xyz.Compare(w[j].ToVec3(),
POLYTOPE_VERTEX_EPSILON))
{
break;
}
}
...
}
Пример №1
30
for ( j = 0; j < w.GetNumPoints(); j++ ) {
for ( k = 0; k < verts.Num(); j++ ) {
if ( verts[k].xyz.Compare(w[j].ToVec3(),
POLYTOPE_VERTEX_EPSILON))
{
break;
}
}
...
}
Пример №1
31
V533 It is likely that a wrong variable is being
incremented inside the 'for' operator. Consider
reviewing 'j'. idLib surface_polytope.cpp 65
for ( j = 0; j < w.GetNumPoints(); j++ ) {
for ( k = 0; k < verts.Num(); k++ ) {
if ( verts[k].xyz.Compare(w[j].ToVec3(),
POLYTOPE_VERTEX_EPSILON))
{
break;
}
}
...
}
Пример №1
32
V533 It is likely that a wrong variable is being
incremented inside the 'for' operator. Consider
reviewing 'j'. idLib surface_polytope.cpp 65
void idBrushBSP::FloodThroughPortals_r
(idBrushBSPNode *node, ...)
{
...
if ( node->occupied ) {
common->Error( "Node already occupiedn" );
}
if ( !node ) {
common->Error( "NULL noden" );
}
...
}
Пример №2
33
void idBrushBSP::FloodThroughPortals_r
(idBrushBSPNode *node, ...)
{
...
if ( node->occupied ) {
common->Error( "Node already occupiedn" );
}
if ( !node ) {
common->Error( "NULL noden" );
}
...
}
Пример №2
34
V595 The 'node' pointer was utilized before it was
verified against nullptr. Check lines: 1421, 1424.
DoomDLL brushbsp.cpp 1421
Пример №2
35
void idBrushBSP::FloodThroughPortals_r
(idBrushBSPNode *node, ...)
{
...
if ( node->occupied ) {
common->Error( "Node already occupiedn" );
}
if ( !node ) {
common->Error( "NULL noden" );
}
...
}
Пример №2
36
V595 The 'node' pointer was utilized before it was
verified against nullptr. Check lines: 1421, 1424.
DoomDLL brushbsp.cpp 1421
void idBrushBSP::FloodThroughPortals_r
(idBrushBSPNode *node, ...)
{
...
if ( !node ) {
common->Error( "NULL noden" );
}
if ( node->occupied ) {
common->Error( "Node already occupiedn" );
}
...
}
Пример №2
37
V595 The 'node' pointer was utilized before it was
verified against nullptr. Check lines: 1421, 1424.
DoomDLL brushbsp.cpp 1421
osu! (C#)
38
public RulesetInfo GetRuleset(int id) =>
AvailableRulesets.FirstOrDefault(....);
....
public ScoreInfo CreateScoreInfo(RulesetStore rulesets) {
var ruleset = rulesets.GetRuleset(OnlineRulesetID);
var mods =
Mods != null
? ruleset.CreateInstance().GetAllMods().Where(....).ToArray()
: Array.Empty<Mod>();
....
}
Пример №1
39
public RulesetInfo GetRuleset(int id) =>
AvailableRulesets.FirstOrDefault(....);
....
public ScoreInfo CreateScoreInfo(RulesetStore rulesets) {
var ruleset = rulesets.GetRuleset(OnlineRulesetID);
var mods =
Mods != null
? ruleset.CreateInstance().GetAllMods().Where(....).ToArray()
: Array.Empty<Mod>();
....
}
Пример №1
40
V3146 Possible null dereference of 'ruleset'. The 'FirstOrDefault'
can return default null value. APILegacyScoreInfo.cs 24
public RulesetInfo GetRuleset(int id) =>
AvailableRulesets.FirstOrDefault(....);
....
public ScoreInfo CreateScoreInfo(RulesetStore rulesets) {
var ruleset = rulesets.GetRuleset(OnlineRulesetID);
var mods =
(Mods != null && ruleset != null)
? ruleset.CreateInstance().GetAllMods().Where(....).ToArray()
: Array.Empty<Mod>();
....
}
Пример №1
41
V3146 Possible null dereference of 'ruleset'. The 'FirstOrDefault'
can return default null value. APILegacyScoreInfo.cs 24
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f;
}
Пример №2
42
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f;
}
Пример №2
43
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f;
}
Пример №2
44
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f;
}
Пример №2
45
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f;
}
Пример №2
46
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = (c * a) ?? b;
Пример №2
47
Что, если
((IOsuScreen)next)
окажется null?
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f;
}
Пример №2
48
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = (c * a) ?? b;
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
(null)?.BackgroundParallaxAmount ?? 1.0f;
}
Пример №2
49
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = (c * a) ?? b;
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
null ?? 1.0f;
}
Пример №2
50
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = (c * null) ?? b;
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
null
?? 1.0f;
}
Пример №2
51
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = null ?? b;
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount = 1.0f;
}
Пример №2
52
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = b;
Пример №2
53
Это ошибка!!!
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f;
}
Пример №2
54
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
(((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f);
}
Пример №2
55
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = c * (a ?? b);
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
(null?.BackgroundParallaxAmount ?? 1.0f);
}
Пример №2
56
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = c * (a ?? b);
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT *
(null ?? 1.0f);
}
Пример №2
57
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = c * (null ?? b);
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * 1.0f;
}
Пример №2
58
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = c * b;
private void onScreenChange(IScreen prev, IScreen next)
{
parallaxContainer.ParallaxAmount =
ParallaxContainer.DEFAULT_PARALLAX_AMOUNT;
}
Пример №2
59
V3123 Perhaps the '??' operator works in a different way than it
was expected. Its priority is lower than priority of other operators
in its left part. OsuScreenStack.cs 45
x = c * b;
VVVVVV (C++)
60
TiXmlElement *pElem;
....
pElem = hDoc.FirstChildElement().Element();
if (!pElem)
{
printf("No valid root! Corrupt level file?n");
}
pElem->QueryIntAttribute("version", &version);
Пример №1
61
TiXmlElement *pElem;
....
pElem = hDoc.FirstChildElement().Element();
if (!pElem)
{
printf("No valid root! Corrupt level file?n");
}
pElem->QueryIntAttribute("version", &version);
Пример №1
62
V1004 The 'pElem' pointer was used unsafely after it was
verified against nullptr. Check lines: 1739, 1744. editor.cpp 1744
TiXmlElement *pElem;
....
pElem = hDoc.FirstChildElement().Element();
if (!pElem)
{
printf("No valid root! Corrupt level file?n");
return;
}
pElem->QueryIntAttribute("version", &version);
Пример №1
63
V1004 The 'pElem' pointer was used unsafely after it was
verified against nullptr. Check lines: 1739, 1744. editor.cpp 1744
TiXmlElement *pElem;
....
pElem = hDoc.FirstChildElement().Element();
if (!pElem)
{
printf("No valid root! Corrupt level file?n");
return; // Также можно было сделать throw
}
pElem->QueryIntAttribute("version", &version);
Пример №1
64
V1004 The 'pElem' pointer was used unsafely after it was
verified against nullptr. Check lines: 1739, 1744. editor.cpp 1744
Адский switch
65
 V2008 Cyclomatic complexity: 548. Consider
refactoring the 'Game::updatestate' function.
Game.cpp 612
Адский switch
66
Адский switch
67
Адский switch
68
Адский switch
69
Адский switch
70
Адский switch
71
Адский switch
72
Адский switch
73
 3339 строк
 Около 300 case-ветвей
 Ни одной enum-константы
Мысли напоследок
74
 Всех ошибок можно было избежать,
используя статический анализ кода
 Показанные примеры – лишь вершина
айсберга
Мысли напоследок
75
id Software
Wargaming
Epic Games
Playrix
Warner Brothers
Кто уже использует статический анализ
76
Oculus
Codemasters
Rocksteady
ZeniMax Media
И другие…
77
Бесплатная лицензия
для open-source проектов:
Промокод на месяц:
www.viva64.com/pvs-free-
opensource
www.viva64.com/download-
devgamm

Contenu connexe

Tendances

Advance features of C++
Advance features of C++Advance features of C++
Advance features of C++
vidyamittal
 
Architecture for Massively Parallel HDL Simulations
Architecture for Massively Parallel HDL Simulations Architecture for Massively Parallel HDL Simulations
Architecture for Massively Parallel HDL Simulations
DVClub
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
Miller Lee
 
ISCA Final Presentaiton - Compilations
ISCA Final Presentaiton -  CompilationsISCA Final Presentaiton -  Compilations
ISCA Final Presentaiton - Compilations
HSA Foundation
 

Tendances (20)

Коварный code type ITGM #9
Коварный code type ITGM #9Коварный code type ITGM #9
Коварный code type ITGM #9
 
Es6 overview
Es6 overviewEs6 overview
Es6 overview
 
3
33
3
 
Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resources
 
Advance features of C++
Advance features of C++Advance features of C++
Advance features of C++
 
The Unicorn Getting Interested in KDE
The Unicorn Getting Interested in KDEThe Unicorn Getting Interested in KDE
The Unicorn Getting Interested in KDE
 
Advance C++notes
Advance C++notesAdvance C++notes
Advance C++notes
 
Architecture for Massively Parallel HDL Simulations
Architecture for Massively Parallel HDL Simulations Architecture for Massively Parallel HDL Simulations
Architecture for Massively Parallel HDL Simulations
 
TensorFlow XLA RPC
TensorFlow XLA RPCTensorFlow XLA RPC
TensorFlow XLA RPC
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
 
Java, Up to Date Sources
Java, Up to Date SourcesJava, Up to Date Sources
Java, Up to Date Sources
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
 
Arduino coding class
Arduino coding classArduino coding class
Arduino coding class
 
Programming with GUTs
Programming with GUTsProgramming with GUTs
Programming with GUTs
 
Arduino coding class part ii
Arduino coding class part iiArduino coding class part ii
Arduino coding class part ii
 
LLVM Backend の紹介
LLVM Backend の紹介LLVM Backend の紹介
LLVM Backend の紹介
 
Zarzadzanie pamiecia w .NET - WDI
Zarzadzanie pamiecia w .NET - WDIZarzadzanie pamiecia w .NET - WDI
Zarzadzanie pamiecia w .NET - WDI
 
SFO15-500: VIXL
SFO15-500: VIXLSFO15-500: VIXL
SFO15-500: VIXL
 
Aspect Mining for Large Systems
Aspect Mining for Large SystemsAspect Mining for Large Systems
Aspect Mining for Large Systems
 
ISCA Final Presentaiton - Compilations
ISCA Final Presentaiton -  CompilationsISCA Final Presentaiton -  Compilations
ISCA Final Presentaiton - Compilations
 

Similaire à Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты / Георгий Грибков (PVS-Studio)

JavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyJavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovy
Yasuharu Nakano
 

Similaire à Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты / Георгий Грибков (PVS-Studio) (20)

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
 
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
 
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...
 
A Spin-off: CryEngine 3 SDK Checked with CppCat
A Spin-off: CryEngine 3 SDK Checked with CppCatA Spin-off: CryEngine 3 SDK Checked with CppCat
A Spin-off: CryEngine 3 SDK Checked with CppCat
 
Stupid Awesome Python Tricks
Stupid Awesome Python TricksStupid Awesome Python Tricks
Stupid Awesome Python Tricks
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Analysis of Microsoft Code Contracts
Analysis of Microsoft Code ContractsAnalysis of Microsoft Code Contracts
Analysis of Microsoft Code Contracts
 
How to not write a boring test in Golang
How to not write a boring test in GolangHow to not write a boring test in Golang
How to not write a boring test in Golang
 
The Unicorn's Travel to the Microcosm
The Unicorn's Travel to the MicrocosmThe Unicorn's Travel to the Microcosm
The Unicorn's Travel to the Microcosm
 
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 1
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 1Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 1
Analysis of Haiku Operating System (BeOS Family) by PVS-Studio. Part 1
 
Clean Code Development
Clean Code DevelopmentClean Code Development
Clean Code Development
 
PVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error ExamplesPVS-Studio in 2021 - Error Examples
PVS-Studio in 2021 - Error Examples
 
JavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovyJavaSE7 Launch Event: Java7xGroovy
JavaSE7 Launch Event: Java7xGroovy
 
Chainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみたChainer-Compiler 動かしてみた
Chainer-Compiler 動かしてみた
 
Basic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmersBasic c++ 11/14 for python programmers
Basic c++ 11/14 for python programmers
 
Learning Dtrace
Learning DtraceLearning Dtrace
Learning Dtrace
 
lldb – Debugger auf Abwegen
lldb – Debugger auf Abwegenlldb – Debugger auf Abwegen
lldb – Debugger auf Abwegen
 
Analysis of the Ultimate Toolbox project
Analysis of the Ultimate Toolbox projectAnalysis of the Ultimate Toolbox project
Analysis of the Ultimate Toolbox project
 
Analysis of the Ultimate Toolbox project
Analysis of the Ultimate Toolbox projectAnalysis of the Ultimate Toolbox project
Analysis of the Ultimate Toolbox project
 
Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016Top 10 bugs in C++ open source projects, checked in 2016
Top 10 bugs in C++ open source projects, checked in 2016
 

Plus de DevGAMM Conference

Plus de DevGAMM Conference (20)

The art of small steps, or how to make sound for games in conditions of war /...
The art of small steps, or how to make sound for games in conditions of war /...The art of small steps, or how to make sound for games in conditions of war /...
The art of small steps, or how to make sound for games in conditions of war /...
 
Breaking up with FMOD - Why we ended things and embraced Metasounds / Daniel ...
Breaking up with FMOD - Why we ended things and embraced Metasounds / Daniel ...Breaking up with FMOD - Why we ended things and embraced Metasounds / Daniel ...
Breaking up with FMOD - Why we ended things and embraced Metasounds / Daniel ...
 
How Audio Objects Improve Spatial Accuracy / Mads Maretty Sønderup (Audiokine...
How Audio Objects Improve Spatial Accuracy / Mads Maretty Sønderup (Audiokine...How Audio Objects Improve Spatial Accuracy / Mads Maretty Sønderup (Audiokine...
How Audio Objects Improve Spatial Accuracy / Mads Maretty Sønderup (Audiokine...
 
Why indie developers should consider hyper-casual right now / Igor Gurenyov (...
Why indie developers should consider hyper-casual right now / Igor Gurenyov (...Why indie developers should consider hyper-casual right now / Igor Gurenyov (...
Why indie developers should consider hyper-casual right now / Igor Gurenyov (...
 
AI / ML for Indies / Tyler Coleman (Retora Games)
AI / ML for Indies / Tyler Coleman (Retora Games)AI / ML for Indies / Tyler Coleman (Retora Games)
AI / ML for Indies / Tyler Coleman (Retora Games)
 
Agility is the Key: Power Up Your GameDev Project Management with Agile Pract...
Agility is the Key: Power Up Your GameDev Project Management with Agile Pract...Agility is the Key: Power Up Your GameDev Project Management with Agile Pract...
Agility is the Key: Power Up Your GameDev Project Management with Agile Pract...
 
New PR Tech and AI Tools for 2023: A Game Changer for Outreach / Kirill Perev...
New PR Tech and AI Tools for 2023: A Game Changer for Outreach / Kirill Perev...New PR Tech and AI Tools for 2023: A Game Changer for Outreach / Kirill Perev...
New PR Tech and AI Tools for 2023: A Game Changer for Outreach / Kirill Perev...
 
Playable Ads - Revolutionizing mobile games advertising / Jakub Kukuryk (Popc...
Playable Ads - Revolutionizing mobile games advertising / Jakub Kukuryk (Popc...Playable Ads - Revolutionizing mobile games advertising / Jakub Kukuryk (Popc...
Playable Ads - Revolutionizing mobile games advertising / Jakub Kukuryk (Popc...
 
Creative Collaboration: Managing an Art Team / Nastassia Radzivonava (Glera G...
Creative Collaboration: Managing an Art Team / Nastassia Radzivonava (Glera G...Creative Collaboration: Managing an Art Team / Nastassia Radzivonava (Glera G...
Creative Collaboration: Managing an Art Team / Nastassia Radzivonava (Glera G...
 
From Local to Global: Unleashing the Power of Payments / Jan Kuhlmannn (Xsolla)
From Local to Global: Unleashing the Power of Payments / Jan Kuhlmannn (Xsolla)From Local to Global: Unleashing the Power of Payments / Jan Kuhlmannn (Xsolla)
From Local to Global: Unleashing the Power of Payments / Jan Kuhlmannn (Xsolla)
 
Strategies and case studies to grow LTV in 2023 / Julia Iljuk (Balancy)
Strategies and case studies to grow LTV in 2023 / Julia Iljuk (Balancy)Strategies and case studies to grow LTV in 2023 / Julia Iljuk (Balancy)
Strategies and case studies to grow LTV in 2023 / Julia Iljuk (Balancy)
 
Why is ASO not working in 2023 and how to change it? / Olena Vedmedenko (Keya...
Why is ASO not working in 2023 and how to change it? / Olena Vedmedenko (Keya...Why is ASO not working in 2023 and how to change it? / Olena Vedmedenko (Keya...
Why is ASO not working in 2023 and how to change it? / Olena Vedmedenko (Keya...
 
How to increase wishlists & game sales from China? Growth marketing tactics &...
How to increase wishlists & game sales from China? Growth marketing tactics &...How to increase wishlists & game sales from China? Growth marketing tactics &...
How to increase wishlists & game sales from China? Growth marketing tactics &...
 
Turkish Gaming Industry and HR Insights / Mustafa Mert EFE (Zindhu)
Turkish Gaming Industry and HR Insights / Mustafa Mert EFE (Zindhu)Turkish Gaming Industry and HR Insights / Mustafa Mert EFE (Zindhu)
Turkish Gaming Industry and HR Insights / Mustafa Mert EFE (Zindhu)
 
Building an Awesome Creative Team from Scratch, Capable of Scaling Up / Sasha...
Building an Awesome Creative Team from Scratch, Capable of Scaling Up / Sasha...Building an Awesome Creative Team from Scratch, Capable of Scaling Up / Sasha...
Building an Awesome Creative Team from Scratch, Capable of Scaling Up / Sasha...
 
Seven Reasons Why Your LiveOps Is Not Performing / Alexander Devyaterikov (Be...
Seven Reasons Why Your LiveOps Is Not Performing / Alexander Devyaterikov (Be...Seven Reasons Why Your LiveOps Is Not Performing / Alexander Devyaterikov (Be...
Seven Reasons Why Your LiveOps Is Not Performing / Alexander Devyaterikov (Be...
 
The Power of Game and Music Collaborations: Reaching and Engaging the Masses ...
The Power of Game and Music Collaborations: Reaching and Engaging the Masses ...The Power of Game and Music Collaborations: Reaching and Engaging the Masses ...
The Power of Game and Music Collaborations: Reaching and Engaging the Masses ...
 
Branded Content: How to overcome players' immunity to advertising / Alex Brod...
Branded Content: How to overcome players' immunity to advertising / Alex Brod...Branded Content: How to overcome players' immunity to advertising / Alex Brod...
Branded Content: How to overcome players' immunity to advertising / Alex Brod...
 
Resurrecting Chasm: The Rift - A Source-less Remastering Journey / Gennadii P...
Resurrecting Chasm: The Rift - A Source-less Remastering Journey / Gennadii P...Resurrecting Chasm: The Rift - A Source-less Remastering Journey / Gennadii P...
Resurrecting Chasm: The Rift - A Source-less Remastering Journey / Gennadii P...
 
How NOT to do showcase events: Behind the scenes of Midnight Show / Andrew Ko...
How NOT to do showcase events: Behind the scenes of Midnight Show / Andrew Ko...How NOT to do showcase events: Behind the scenes of Midnight Show / Andrew Ko...
How NOT to do showcase events: Behind the scenes of Midnight Show / Andrew Ko...
 

Dernier

%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
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
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 
%+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
 

Dernier (20)

%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%+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...
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
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...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
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...
 
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...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
%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 Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
%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
 
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...
 
%+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...
 
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...
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%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
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 

Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты / Георгий Грибков (PVS-Studio)

  • 1. Самые вкусные баги из игрового кода: как ошибаются наши коллеги-программисты Докладчик: Георгий Грибков
  • 2. Докладчик Георгий Грибков Программист C++, разработчик статического анализатора кода PVS-Studio Автор статей и докладов о поиске ошибок в играх (Вангеры, VVVVVV) и других проектах с открытым исходным кодом gribkov@viva64.com 2
  • 3. 1. Как мы ищем ошибки в коде 2. Примеры и разбор найденных ошибок 3. Мысли напоследок Содержание 3
  • 4. Как мы ищем ошибки в коде 4
  • 5. Как мы ищем ошибки в коде 5 Обновляемый список статей о проверке проектов:
  • 6. Примеры и разбор найденных ошибок 6
  • 8. fix Terrain( fix X, fix Y, int deriv ) { if( deriv == 0 ) return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) ); if( deriv == 1 ) return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) ); if( deriv == 2 ) return 0; return 0; } Пример №1 8
  • 9. fix Terrain( fix X, fix Y, int deriv ) { if( deriv == 0 ) return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) ); if( deriv == 1 ) return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) ); if( deriv == 2 ) return 0; return 0; } Пример №1 9 V751 Parameter 'Y' is not used inside function body. BTEST.C 67
  • 10. fix Terrain( fix X, fix Y, int deriv ) { if( deriv == 0 ) return fix_mul( fix_make(0,0x2000), (X - fix_make(20,0) ) ); if( deriv == 1 ) return fix_mul( fix_make(0,0x2000), (Y - fix_make(20,0) ) ); if( deriv == 2 ) return 0; return 0; } Пример №1 10 V751 Parameter 'Y' is not used inside function body. BTEST.C 67
  • 11. // And here, ladies and gentlemen, // is a celebration of C and C++ and their untamed passion... // ================== TerrainData terrain_info; // Now the actual stuff... // ======================= Забавные комментарии 11
  • 12. // it's a wonderful world, with a lot of strange men // who are standing around, and they all wearing towels // Returns whether or not in the humble opinion of the // sound system, the sample should be politely // obliterated out of existence Забавные комментарии 12
  • 14. if (....) MySandboxGame.Log.WriteLine(string.Format( "Could not find any sound for '{0}'", cueName)); else { if (....) string.Format( "Could not find arcade sound for '{0}'", cueName); if (....) string.Format( "Could not find realistic sound for '{0}'", cueName); } Пример №1 14
  • 15. if (....) MySandboxGame.Log.WriteLine(string.Format( "Could not find any sound for '{0}'", cueName)); else { if (....) string.Format( "Could not find arcade sound for '{0}'", cueName); if (....) string.Format( "Could not find realistic sound for '{0}'", cueName); } Пример №1 15 V3010 The return value of function 'Format' is required to be utilized. Sandbox.Game MyEntity3DSoundEmitter.cs
  • 16. if (....) MySandboxGame.Log.WriteLine(string.Format( "Could not find any sound for '{0}'", cueName)); else { if (....) MySandboxGame.Log.WriteLine(string.Format( "Could not find arcade sound for '{0}'", cueName)); if (....) MySandboxGame.Log.WriteLine(string.Format( "Could not find realistic sound for '{0}'", cueName)); } Пример №1 16 V3010 The return value of function 'Format' is required to be utilized. Sandbox.Game MyEntity3DSoundEmitter.cs
  • 17. var actionsItem = item as MyToolbarItemActions; if (item != null) { if (idx < 0 || idx >= actionsItem .PossibleActions(....) .Count) RemoveToolbarItem(slot); .... } Пример №2 17
  • 18. var actionsItem = item as MyToolbarItemActions; if (item != null) { if (idx < 0 || idx >= actionsItem .PossibleActions(....) .Count) RemoveToolbarItem(slot); .... } Пример №2 18 V3019 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'item', 'actionsItem'. Sandbox.Game MyGuiControlToolbar.cs 511
  • 19. var actionsItem = item as MyToolbarItemActions; if (item != null) { if (idx < 0 || idx >= actionsItem .PossibleActions(....) .Count) RemoveToolbarItem(slot); .... } Пример №2 19 V3019 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'item', 'actionsItem'. Sandbox.Game MyGuiControlToolbar.cs 511
  • 20. var actionsItem = item as MyToolbarItemActions; if (actionsItem != null) { if (idx < 0 || idx >= actionsItem .PossibleActions(....) .Count) RemoveToolbarItem(slot); .... } Пример №2 20 V3019 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'item', 'actionsItem'. Sandbox.Game MyGuiControlToolbar.cs 511
  • 21. C&C: Tiberian Dawn и C&C: Red Alert (C++) 21
  • 22. // Maximum number of multi players possible. #define MAX_PLAYERS 8 // max # of players we can have for (int i = 0; i < MAX_PLAYERS && i < 4; i++) { if (GlyphxPlayerIDs[i] == player_id) { MultiplayerStartPositions[i] = XY_Cell(x, y); } } Пример №1 22
  • 23. // Maximum number of multi players possible. #define MAX_PLAYERS 8 // max # of players we can have for (int i = 0; i < MAX_PLAYERS && i < 4; i++) { if (GlyphxPlayerIDs[i] == player_id) { MultiplayerStartPositions[i] = XY_Cell(x, y); } } Пример №1 23 V590 Consider inspecting the 'i < 8 && i < 4' expression. The expression is excessive or contains a misprint. DLLInterface.cpp 2238
  • 24. // Maximum number of multi players possible. #define MAX_PLAYERS 8 // max # of players we can have for (int i = 0; i < MAX_PLAYERS || i < 4; i++) { if (GlyphxPlayerIDs[i] == player_id) { MultiplayerStartPositions[i] = XY_Cell(x, y); } } Пример №1 24 V590 Consider inspecting the 'i < 8 && i < 4' expression. The expression is excessive or contains a misprint. DLLInterface.cpp 2238
  • 25. void * ptr = new char [sizeof(100)]; if (ptr) { sprintf((char *)ptr, "%cTrack %dt%d:%02dt%s", ....); listbox.Add_Item((char const *)ptr); } Пример №2 25
  • 26. void * ptr = new char [sizeof(100)]; if (ptr) { sprintf((char *)ptr, "%cTrack %dt%d:%02dt%s", ....); listbox.Add_Item((char const *)ptr); } Пример №2 26 V512 A call of the 'sprintf' function will lead to overflow of the buffer '(char *) ptr'. SOUNDDLG.CPP 250
  • 27. void * ptr = new char [100]; if (ptr) { sprintf((char *)ptr, "%cTrack %dt%d:%02dt%s", ....); listbox.Add_Item((char const *)ptr); } Пример №2 27 V512 A call of the 'sprintf' function will lead to overflow of the buffer '(char *) ptr'. SOUNDDLG.CPP 250
  • 28. 28
  • 30. for ( j = 0; j < w.GetNumPoints(); j++ ) { for ( k = 0; k < verts.Num(); j++ ) { if ( verts[k].xyz.Compare(w[j].ToVec3(), POLYTOPE_VERTEX_EPSILON)) { break; } } ... } Пример №1 30
  • 31. for ( j = 0; j < w.GetNumPoints(); j++ ) { for ( k = 0; k < verts.Num(); j++ ) { if ( verts[k].xyz.Compare(w[j].ToVec3(), POLYTOPE_VERTEX_EPSILON)) { break; } } ... } Пример №1 31 V533 It is likely that a wrong variable is being incremented inside the 'for' operator. Consider reviewing 'j'. idLib surface_polytope.cpp 65
  • 32. for ( j = 0; j < w.GetNumPoints(); j++ ) { for ( k = 0; k < verts.Num(); k++ ) { if ( verts[k].xyz.Compare(w[j].ToVec3(), POLYTOPE_VERTEX_EPSILON)) { break; } } ... } Пример №1 32 V533 It is likely that a wrong variable is being incremented inside the 'for' operator. Consider reviewing 'j'. idLib surface_polytope.cpp 65
  • 33. void idBrushBSP::FloodThroughPortals_r (idBrushBSPNode *node, ...) { ... if ( node->occupied ) { common->Error( "Node already occupiedn" ); } if ( !node ) { common->Error( "NULL noden" ); } ... } Пример №2 33
  • 34. void idBrushBSP::FloodThroughPortals_r (idBrushBSPNode *node, ...) { ... if ( node->occupied ) { common->Error( "Node already occupiedn" ); } if ( !node ) { common->Error( "NULL noden" ); } ... } Пример №2 34 V595 The 'node' pointer was utilized before it was verified against nullptr. Check lines: 1421, 1424. DoomDLL brushbsp.cpp 1421
  • 36. void idBrushBSP::FloodThroughPortals_r (idBrushBSPNode *node, ...) { ... if ( node->occupied ) { common->Error( "Node already occupiedn" ); } if ( !node ) { common->Error( "NULL noden" ); } ... } Пример №2 36 V595 The 'node' pointer was utilized before it was verified against nullptr. Check lines: 1421, 1424. DoomDLL brushbsp.cpp 1421
  • 37. void idBrushBSP::FloodThroughPortals_r (idBrushBSPNode *node, ...) { ... if ( !node ) { common->Error( "NULL noden" ); } if ( node->occupied ) { common->Error( "Node already occupiedn" ); } ... } Пример №2 37 V595 The 'node' pointer was utilized before it was verified against nullptr. Check lines: 1421, 1424. DoomDLL brushbsp.cpp 1421
  • 39. public RulesetInfo GetRuleset(int id) => AvailableRulesets.FirstOrDefault(....); .... public ScoreInfo CreateScoreInfo(RulesetStore rulesets) { var ruleset = rulesets.GetRuleset(OnlineRulesetID); var mods = Mods != null ? ruleset.CreateInstance().GetAllMods().Where(....).ToArray() : Array.Empty<Mod>(); .... } Пример №1 39
  • 40. public RulesetInfo GetRuleset(int id) => AvailableRulesets.FirstOrDefault(....); .... public ScoreInfo CreateScoreInfo(RulesetStore rulesets) { var ruleset = rulesets.GetRuleset(OnlineRulesetID); var mods = Mods != null ? ruleset.CreateInstance().GetAllMods().Where(....).ToArray() : Array.Empty<Mod>(); .... } Пример №1 40 V3146 Possible null dereference of 'ruleset'. The 'FirstOrDefault' can return default null value. APILegacyScoreInfo.cs 24
  • 41. public RulesetInfo GetRuleset(int id) => AvailableRulesets.FirstOrDefault(....); .... public ScoreInfo CreateScoreInfo(RulesetStore rulesets) { var ruleset = rulesets.GetRuleset(OnlineRulesetID); var mods = (Mods != null && ruleset != null) ? ruleset.CreateInstance().GetAllMods().Where(....).ToArray() : Array.Empty<Mod>(); .... } Пример №1 41 V3146 Possible null dereference of 'ruleset'. The 'FirstOrDefault' can return default null value. APILegacyScoreInfo.cs 24
  • 42. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; } Пример №2 42
  • 43. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; } Пример №2 43 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45
  • 44. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; } Пример №2 44 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45
  • 45. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; } Пример №2 45 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45
  • 46. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; } Пример №2 46 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = (c * a) ?? b;
  • 48. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; } Пример №2 48 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = (c * a) ?? b;
  • 49. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * (null)?.BackgroundParallaxAmount ?? 1.0f; } Пример №2 49 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = (c * a) ?? b;
  • 50. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * null ?? 1.0f; } Пример №2 50 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = (c * null) ?? b;
  • 51. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = null ?? 1.0f; } Пример №2 51 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = null ?? b;
  • 52. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = 1.0f; } Пример №2 52 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = b;
  • 54. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; } Пример №2 54 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45
  • 55. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * (((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f); } Пример №2 55 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = c * (a ?? b);
  • 56. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * (null?.BackgroundParallaxAmount ?? 1.0f); } Пример №2 56 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = c * (a ?? b);
  • 57. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * (null ?? 1.0f); } Пример №2 57 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = c * (null ?? b);
  • 58. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * 1.0f; } Пример №2 58 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = c * b;
  • 59. private void onScreenChange(IScreen prev, IScreen next) { parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT; } Пример №2 59 V3123 Perhaps the '??' operator works in a different way than it was expected. Its priority is lower than priority of other operators in its left part. OsuScreenStack.cs 45 x = c * b;
  • 61. TiXmlElement *pElem; .... pElem = hDoc.FirstChildElement().Element(); if (!pElem) { printf("No valid root! Corrupt level file?n"); } pElem->QueryIntAttribute("version", &version); Пример №1 61
  • 62. TiXmlElement *pElem; .... pElem = hDoc.FirstChildElement().Element(); if (!pElem) { printf("No valid root! Corrupt level file?n"); } pElem->QueryIntAttribute("version", &version); Пример №1 62 V1004 The 'pElem' pointer was used unsafely after it was verified against nullptr. Check lines: 1739, 1744. editor.cpp 1744
  • 63. TiXmlElement *pElem; .... pElem = hDoc.FirstChildElement().Element(); if (!pElem) { printf("No valid root! Corrupt level file?n"); return; } pElem->QueryIntAttribute("version", &version); Пример №1 63 V1004 The 'pElem' pointer was used unsafely after it was verified against nullptr. Check lines: 1739, 1744. editor.cpp 1744
  • 64. TiXmlElement *pElem; .... pElem = hDoc.FirstChildElement().Element(); if (!pElem) { printf("No valid root! Corrupt level file?n"); return; // Также можно было сделать throw } pElem->QueryIntAttribute("version", &version); Пример №1 64 V1004 The 'pElem' pointer was used unsafely after it was verified against nullptr. Check lines: 1739, 1744. editor.cpp 1744
  • 65. Адский switch 65  V2008 Cyclomatic complexity: 548. Consider refactoring the 'Game::updatestate' function. Game.cpp 612
  • 73. Адский switch 73  3339 строк  Около 300 case-ветвей  Ни одной enum-константы
  • 75.  Всех ошибок можно было избежать, используя статический анализ кода  Показанные примеры – лишь вершина айсберга Мысли напоследок 75
  • 76. id Software Wargaming Epic Games Playrix Warner Brothers Кто уже использует статический анализ 76 Oculus Codemasters Rocksteady ZeniMax Media И другие…
  • 77. 77 Бесплатная лицензия для open-source проектов: Промокод на месяц: www.viva64.com/pvs-free- opensource www.viva64.com/download- devgamm