Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
Prog2
/
labor_peldak
/
lab_13
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
820b2618
authored
May 16, 2019
by
Szeberényi Imre
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
v0
parents
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
899 additions
and
0 deletions
+899
-0
bugs/bugs.cbp
+48
-0
bugs/bugs.cpp
+89
-0
bugs/memtrace.cpp
+537
-0
bugs/memtrace.h
+225
-0
No files found.
bugs/bugs.cbp
0 → 100644
View file @
820b2618
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion
major=
"1"
minor=
"6"
/>
<Project>
<Option
title=
"bugs"
/>
<Option
pch_mode=
"2"
/>
<Option
compiler=
"gcc"
/>
<Build>
<Target
title=
"Debug"
>
<Option
output=
"bin/Debug/bugs"
prefix_auto=
"1"
extension_auto=
"1"
/>
<Option
object_output=
"obj/Debug/"
/>
<Option
type=
"1"
/>
<Option
compiler=
"gcc"
/>
<Compiler>
<Add
option=
"-g"
/>
<Add
option=
"-DMEMTRACE"
/>
</Compiler>
</Target>
<Target
title=
"Release"
>
<Option
output=
"bin/Release/bugs"
prefix_auto=
"1"
extension_auto=
"1"
/>
<Option
object_output=
"obj/Release/"
/>
<Option
type=
"1"
/>
<Option
compiler=
"gcc"
/>
<Compiler>
<Add
option=
"-O2"
/>
</Compiler>
<Linker>
<Add
option=
"-s"
/>
</Linker>
</Target>
</Build>
<Compiler>
<Add
option=
"-pedantic"
/>
<Add
option=
"-std=c++11"
/>
<Add
option=
"-Wall"
/>
<Add
option=
"-Werror"
/>
</Compiler>
<Unit
filename=
"bugs.cpp"
/>
<Unit
filename=
"memtrace.cpp"
/>
<Unit
filename=
"memtrace.h"
/>
<Extensions>
<code_completion
/>
<envvars
/>
<debugger
/>
<lib_finder
disable_auto=
"1"
/>
</Extensions>
</Project>
</CodeBlocks_project_file>
bugs/bugs.cpp
0 → 100644
View file @
820b2618
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include "memtrace.h"
const
char
*
str
(
std
::
stringstream
&
ss
)
{
return
ss
.
str
().
c_str
();
}
void
bug1
()
{
std
::
stringstream
ss
;
ss
<<
"Hello"
;
std
::
cout
<<
ss
.
str
()
<<
std
::
endl
;
std
::
cout
<<
str
(
ss
)
<<
std
::
endl
;
}
void
feltolt
(
std
::
vector
<
const
char
*>&
v
,
std
::
string
s
)
{
v
.
push_back
(
s
.
c_str
());
}
void
kiir
(
std
::
vector
<
const
char
*>&
v
)
{
for
(
size_t
i
=
0
;
i
<
v
.
size
();
i
++
)
{
std
::
cout
<<
v
[
i
]
<<
std
::
endl
;
}
}
void
bug2
()
{
std
::
vector
<
const
char
*>
v
;
feltolt
(
v
,
"Hello"
);
feltolt
(
v
,
"World"
);
kiir
(
v
);
}
struct
Mat
{
int
**
p
;
int
siz
;
Mat
(
int
n
=
0
)
:
siz
(
n
)
{
p
=
new
int
*
[
siz
];
for
(
int
i
=
0
;
i
<
siz
;
i
++
)
p
[
i
]
=
new
int
[
siz
];
}
size_t
size
()
const
{
return
siz
;
}
~
Mat
()
{
for
(
int
i
=
0
;
i
<
siz
;
i
++
)
delete
[]
p
[
i
];
delete
[]
*
p
;
}
};
void
bug3
()
{
Mat
m
;
std
::
cout
<<
"size:"
<<
m
.
size
()
<<
std
::
endl
;
}
void
prmenu
()
{
#ifdef MEMTRACE
std
::
cout
<<
"
\n\t
MEMTRACE bekapcsolva
\n
"
;
#else
std
::
cout
<<
"
\n\t
MEMTRACE nincs bekapcsolva
\n
"
;
#endif
std
::
cout
<<
"Melyik teszteset legynen? (1,2,3): "
;
}
int
main
()
{
int
i
;
prmenu
();
while
(
std
::
cin
>>
i
)
{
switch
(
i
)
{
case
1
:
std
::
cout
<<
"TEST1
\n
"
;
bug1
();
break
;
case
2
:
std
::
cout
<<
"TEST2
\n
"
;
bug2
();
break
;
case
3
:
std
::
cout
<<
"TEST3
\n
"
;
bug3
();
break
;
}
prmenu
();
}
}
bugs/memtrace.cpp
0 → 100644
View file @
820b2618
/*********************************
Memoriaszivargas-detektor
Keszitette: Peregi Tamas, BME IIT, 2011
petamas@iit.bme.hu
Kanari: Szeberenyi Imre, 2013.
VS 2012: Szeberényi Imre, 2015.,
mem_dump: 2016.
meset felszabaditaskor: 2018.
typo: 2019.
*********************************/
/*definialni kell, ha nem paracssorbol allitjuk be (-DMEMTRACE) */
/*#define MEMTRACE */
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#ifdef MEMTRACE
#define FROM_MEMTRACE_CPP
#include "memtrace.h"
#define FMALLOC 0
#define FCALLOC 1
#define FREALLOC 2
#define FFREE 3
#define FNEW 4
#define FDELETE 5
#define FNEWARR 6
#define FDELETEARR 7
#define COMP(a,d) (((a)<=3 && (d)<=3) || ((d)==(a)+1))
#define PU(p) ((char*)p+CANARY_LEN) // mem pointerbol user poi
#define P(pu) ((char*)pu-CANARY_LEN) // user pointerbol mem poi
#define XSTR(s) STR(s)
#define STR(s) #s
/*******************************************************************/
/* Segedfuggvenyek es egyebek */
/*******************************************************************/
START_NAMESPACE
static
FILE
*
fperror
;
#ifdef MEMTRACE_TO_MEMORY
static
const
unsigned
int
CANARY_LEN
=
64
;
#else
static
const
unsigned
int
CANARY_LEN
=
0
;
#endif
static
const
unsigned
char
canary_byte1
=
'k'
;
static
const
unsigned
char
canary_byte2
=
'K'
;
static
unsigned
char
random_byte
;
typedef
enum
{
FALSE
,
TRUE
}
BOOL
;
static
const
char
*
pretty
[]
=
{
"malloc("
,
"calloc("
,
"realloc("
,
"free("
,
"new"
,
"delete"
,
"new[]"
,
"delete[]"
};
static
const
char
*
basename
(
const
char
*
s
)
{
const
char
*
s1
,
*
s2
;
s1
=
strrchr
(
s
,
'/'
);
if
(
s1
==
NULL
)
s1
=
s
;
else
s1
++
;
s2
=
strrchr
(
s1
,
'\\'
);
if
(
s2
==
NULL
)
s2
=
s1
;
else
s2
++
;
return
s2
;
}
static
char
*
StrCpy
(
char
**
to
,
const
char
*
from
)
{
if
(
from
==
NULL
)
{
*
to
=
NULL
;
}
else
{
*
to
=
(
char
*
)
malloc
(
strlen
(
from
)
+
1
);
if
(
*
to
)
strcpy
(
*
to
,
from
);
}
return
*
to
;
}
static
void
*
canary_malloc
(
size_t
size
,
unsigned
char
data
)
{
char
*
p
=
(
char
*
)
malloc
(
size
+
2
*
CANARY_LEN
);
if
(
p
)
{
memset
(
p
,
canary_byte1
,
CANARY_LEN
);
memset
(
p
+
CANARY_LEN
,
data
,
size
);
memset
(
p
+
CANARY_LEN
+
size
,
canary_byte2
,
CANARY_LEN
);
}
return
p
;
}
static
int
chk_canary
(
void
*
p
,
size_t
size
)
{
unsigned
char
*
pc
=
(
unsigned
char
*
)
p
;
unsigned
int
i
;
for
(
i
=
0
;
i
<
CANARY_LEN
;
i
++
)
if
(
pc
[
i
]
!=
canary_byte1
)
return
-
1
;
pc
+=
CANARY_LEN
+
size
;
for
(
i
=
0
;
i
<
CANARY_LEN
;
i
++
)
if
(
pc
[
i
]
!=
canary_byte2
)
return
1
;
return
0
;
}
typedef
struct
{
int
f
;
/* allocator func */
int
line
;
char
*
par_txt
;
char
*
file
;
}
call_t
;
static
call_t
pack
(
int
f
,
const
char
*
par_txt
,
int
line
,
const
char
*
file
)
{
call_t
ret
;
ret
.
f
=
f
;
ret
.
line
=
line
;
StrCpy
(
&
ret
.
par_txt
,
par_txt
);
StrCpy
(
&
ret
.
file
,
file
);
return
ret
;
}
static
void
print_call
(
const
char
*
msg
,
call_t
call
)
{
if
(
msg
)
fprintf
(
fperror
,
"%s"
,
msg
);
fprintf
(
fperror
,
"%s"
,
pretty
[
call
.
f
]);
fprintf
(
fperror
,
"%s"
,
call
.
par_txt
?
call
.
par_txt
:
"?"
);
if
(
call
.
f
<=
3
)
fprintf
(
fperror
,
")"
);
fprintf
(
fperror
,
" @ %s:"
,
call
.
file
?
basename
(
call
.
file
)
:
"?"
);
fprintf
(
fperror
,
"%d
\n
"
,
call
.
line
?
call
.
line
:
0
);
}
/* memoriateruletet dump */
static
void
dump_memory
(
void
const
*
mem
,
size_t
size
,
size_t
can_len
,
FILE
*
fp
)
{
unsigned
char
const
*
m
=
(
unsigned
char
const
*
)
mem
;
unsigned
int
s
,
o
;
if
(
can_len
>
0
)
fprintf
(
fp
,
"Dump (addr: %p kanari hossz: %d):
\n
"
,
m
+
can_len
,
(
int
)
can_len
);
else
fprintf
(
fp
,
"Dump: (addr: %p)
\n
"
,
m
);
size
+=
2
*
can_len
;
for
(
s
=
0
;
s
<
(
size
+
15
)
/
16
;
s
++
)
{
fprintf
(
fp
,
"%04x:%c "
,
s
*
16
,
s
*
16
<
can_len
||
s
*
16
>=
size
-
can_len
?
' '
:
'*'
);
for
(
o
=
0
;
o
<
16
;
o
++
)
{
if
(
o
==
8
)
fprintf
(
fp
,
" "
);
if
(
s
*
16
+
o
<
size
)
fprintf
(
fp
,
"%02x "
,
m
[
s
*
16
+
o
]);
else
fprintf
(
fp
,
" "
);
}
fprintf
(
fp
,
" "
);
for
(
o
=
0
;
o
<
16
;
o
++
)
{
if
(
s
*
16
+
o
<
size
)
fprintf
(
fp
,
"%c"
,
isprint
(
m
[
s
*
16
+
o
])
?
m
[
s
*
16
+
o
]
:
'.'
);
else
fprintf
(
fp
,
" "
);
}
fprintf
(
fp
,
"
\n
"
);
}
}
void
mem_dump
(
void
const
*
mem
,
size_t
size
,
FILE
*
fp
)
{
dump_memory
(
mem
,
size
,
0
,
fp
);
}
static
BOOL
dying
;
static
void
die
(
const
char
*
msg
,
void
*
p
,
size_t
size
,
call_t
*
a
,
call_t
*
d
)
{
#ifdef MEMTRACE_ERRFILE
fperror
=
fopen
(
XSTR
(
MEMTRACE_ERRFILE
),
"w"
);
#endif
fprintf
(
fperror
,
"%s
\n
"
,
msg
);
if
(
p
)
{
fprintf
(
fperror
,
"
\t
Pointer:
\t
%p"
,
PU
(
p
));
if
(
size
)
fprintf
(
fperror
,
" (%d byte)"
,
(
int
)
size
);
fprintf
(
fperror
,
"
\n
"
);
}
if
(
a
)
print_call
(
"
\t
Foglalas:
\t
"
,
*
a
);
if
(
d
)
print_call
(
"
\t
Felszabaditas:
\t
"
,
*
d
);
if
(
p
)
dump_memory
(
p
,
size
,
CANARY_LEN
,
fperror
);
dying
=
TRUE
;
exit
(
120
);
}
static
void
initialize
();
END_NAMESPACE
/*******************************************************************/
/* MEMTRACE_TO_MEMORY */
/*******************************************************************/
#ifdef MEMTRACE_TO_MEMORY
START_NAMESPACE
typedef
struct
_registry_item
{
void
*
p
;
/* mem pointer*/
size_t
size
;
/* size*/
call_t
call
;
struct
_registry_item
*
next
;
}
registry_item
;
static
registry_item
registry
;
/*sentinel*/
static
void
print_registry_item
(
registry_item
*
p
)
{
if
(
p
)
{
print_registry_item
(
p
->
next
);
fprintf
(
fperror
,
"
\t
%p%5d byte "
,
p
->
p
,
(
int
)
p
->
size
);
print_call
(
NULL
,
p
->
call
);
if
(
p
->
call
.
par_txt
)
free
(
p
->
call
.
par_txt
);
if
(
p
->
call
.
file
)
free
(
p
->
call
.
file
);
free
(
p
);
}
}
/* ha nincs hiba, akkor 0-val tér vissza */
int
mem_check
(
void
)
{
initialize
();
if
(
dying
)
return
2
;
/* címzési hiba */
if
(
registry
.
next
)
{
/*szivarog*/
#ifdef MEMTRACE_ERRFILE
fperror
=
fopen
(
XSTR
(
MEMTRACE_ERRFILE
),
"w"
);
#endif
fprintf
(
fperror
,
"Szivargas:
\n
"
);
print_registry_item
(
registry
.
next
);
registry
.
next
=
NULL
;
return
1
;
/* memória fogyás */
}
return
0
;
}
END_NAMESPACE
#endif
/*MEMTRACE_TO_MEMORY*/
/*******************************************************************/
/* MEMTRACE_TO_FILE */
/*******************************************************************/
#ifdef MEMTRACE_TO_FILE
START_NAMESPACE
static
FILE
*
trace_file
;
END_NAMESPACE
#endif
/*******************************************************************/
/* register/unregister */
/*******************************************************************/
START_NAMESPACE
static
int
allocated_blks
;
int
allocated_blocks
()
{
return
allocated_blks
;
}
static
BOOL
register_memory
(
void
*
p
,
size_t
size
,
call_t
call
)
{
initialize
();
allocated_blks
++
;
#ifdef MEMTRACE_TO_FILE
fprintf
(
trace_file
,
"%p
\t
%d
\t
%s%s"
,
PU
(
p
),
(
int
)
size
,
pretty
[
call
.
f
],
call
.
par_txt
?
call
.
par_txt
:
"?"
);
if
(
call
.
f
<=
3
)
fprintf
(
trace_file
,
")"
);
fprintf
(
trace_file
,
"
\t
%d
\t
%s
\n
"
,
call
.
line
,
call
.
file
?
call
.
file
:
"?"
);
fflush
(
trace_file
);
#endif
#ifdef MEMTRACE_TO_MEMORY
{
/*C-blokk*/
registry_item
*
n
=
(
registry_item
*
)
malloc
(
sizeof
(
registry_item
));
if
(
n
==
NULL
)
return
FALSE
;
n
->
p
=
p
;
n
->
size
=
size
;
n
->
call
=
call
;
n
->
next
=
registry
.
next
;
registry
.
next
=
n
;
}
/*C-blokk*/
#endif
return
TRUE
;
}
#ifdef MEMTRACE_TO_MEMORY
static
registry_item
*
find_registry_item
(
void
*
p
)
{
registry_item
*
n
=
&
registry
;
for
(;
n
->
next
&&
n
->
next
->
p
!=
p
;
n
=
n
->
next
);
return
n
;
}
#endif
static
void
unregister_memory
(
void
*
p
,
call_t
call
)
{
initialize
();
#ifdef MEMTRACE_TO_FILE
fprintf
(
trace_file
,
"%p
\t
%d
\t
%s%s"
,
PU
(
p
),
-
1
,
pretty
[
call
.
f
],
call
.
par_txt
?
call
.
par_txt
:
"?"
);
if
(
call
.
f
<=
3
)
fprintf
(
trace_file
,
")"
);
fprintf
(
trace_file
,
"
\t
%d
\t
%s
\n
"
,
call
.
line
,
call
.
file
?
call
.
file
:
"?"
);
fflush
(
trace_file
);
#endif
#ifdef MEMTRACE_TO_MEMORY
{
/*C-blokk*/
registry_item
*
n
=
find_registry_item
(
p
);
if
(
n
->
next
)
{
allocated_blks
--
;
registry_item
*
r
=
n
->
next
;
n
->
next
=
r
->
next
;
if
(
COMP
(
r
->
call
.
f
,
call
.
f
))
{
int
chk
=
chk_canary
(
r
->
p
,
r
->
size
);
if
(
chk
<
0
)
die
(
"Blokk elott serult a memoria:"
,
r
->
p
,
r
->
size
,
&
r
->
call
,
&
call
);
if
(
chk
>
0
)
die
(
"Blokk utan serult a memoria"
,
r
->
p
,
r
->
size
,
&
r
->
call
,
&
call
);
/*rendben van minden*/
if
(
call
.
par_txt
)
free
(
call
.
par_txt
);
if
(
r
->
call
.
par_txt
)
free
(
r
->
call
.
par_txt
);
if
(
call
.
file
)
free
(
call
.
file
);
if
(
r
->
call
.
file
)
free
(
r
->
call
.
file
);
memset
(
PU
(
r
->
p
),
'f'
,
r
->
size
);
PU
(
r
->
p
)[
r
->
size
-
1
]
=
0
;
free
(
r
);
}
else
{
/*hibas felszabaditas*/
die
(
"Hibas felszabaditas:"
,
r
->
p
,
r
->
size
,
&
r
->
call
,
&
call
);
}
}
else
{
die
(
"Nem letezo, vagy mar felszabaditott adat felszabaditasa:"
,
p
,
0
,
NULL
,
&
call
);
}
}
/*C-blokk*/
#endif
}
END_NAMESPACE
/*******************************************************************/
/* C-stílusú memóriakezelés */
/*******************************************************************/
#ifdef MEMTRACE_C
START_NAMESPACE
void
*
traced_malloc
(
size_t
size
,
const
char
*
par_txt
,
int
line
,
const
char
*
file
)
{
void
*
p
;
initialize
();
p
=
canary_malloc
(
size
,
random_byte
);
if
(
p
)
{
if
(
!
register_memory
(
p
,
size
,
pack
(
FMALLOC
,
par_txt
,
line
,
file
)))
{
free
(
p
);
return
NULL
;
}
return
PU
(
p
);
}
return
NULL
;
}
void
*
traced_calloc
(
size_t
count
,
size_t
size
,
const
char
*
par_txt
,
int
line
,
const
char
*
file
)
{
void
*
p
;
initialize
();
size
*=
count
;
p
=
canary_malloc
(
size
,
0
);
if
(
p
)
{
if
(
!
register_memory
(
p
,
size
,
pack
(
FCALLOC
,
par_txt
,
line
,
file
)))
{
free
(
p
);
return
NULL
;
}
return
PU
(
p
);
}
return
NULL
;
}
void
traced_free
(
void
*
pu
,
const
char
*
par_txt
,
int
line
,
const
char
*
file
)
{
initialize
();
if
(
pu
)
{
unregister_memory
(
P
(
pu
),
pack
(
FFREE
,
par_txt
,
line
,
file
));
free
(
P
(
pu
));
}
else
{
/*free(NULL) eset*/
#ifdef MEMTRACE_TO_FILE
fprintf
(
trace_file
,
"%s
\t
%d
\t
%10s
\t
"
,
"NULL"
,
-
1
,
pretty
[
FFREE
]);
fprintf
(
trace_file
,
"%d
\t
%s
\n
"
,
line
,
file
?
file
:
"?"
);
fflush
(
trace_file
);
#endif
#ifndef ALLOW_FREE_NULL
{
/*C-blokk*/
call_t
call
;
call
=
pack
(
FFREE
,
par_txt
,
line
,
file
);
die
(
"free(NULL) hivasa:"
,
NULL
,
0
,
NULL
,
&
call
);
}
/*C-blokk*/
#endif
}
}
void
*
traced_realloc
(
void
*
old
,
size_t
size
,
const
char
*
par_txt
,
int
line
,
const
char
*
file
)
{
void
*
p
;
size_t
oldsize
=
0
;
registry_item
*
n
;
initialize
();
#ifdef MEMTRACE_TO_MEMORY
n
=
find_registry_item
(
P
(
old
));
if
(
n
)
oldsize
=
n
->
next
->
size
;
p
=
canary_malloc
(
size
,
random_byte
);
#else
p
=
realloc
(
old
,
size
);
#endif
if
(
p
)
{
/*Ha sikerult a foglalas, regisztraljuk*/
register_memory
(
p
,
size
,
pack
(
FREALLOC
,
par_txt
,
line
,
file
));
if
(
old
)
{
#ifdef MEMTRACE_TO_MEMORY
int
cpsize
=
2
*
CANARY_LEN
;
if
(
oldsize
<
size
)
cpsize
+=
oldsize
;
else
cpsize
+=
size
;
memcpy
(
p
,
P
(
old
),
cpsize
);
#endif
unregister_memory
(
P
(
old
),
pack
(
FREALLOC
,
par_txt
,
line
,
file
));
#ifdef MEMTRACE_TO_MEMORY
free
P
(
old
);
#endif
}
return
PU
(
p
);
}
else
{
return
NULL
;
}
}
END_NAMESPACE
#endif
/*MEMTRACE_C*/
/*******************************************************************/
/* C++-stílusú memóriakezelés */
/*******************************************************************/
#ifdef MEMTRACE_CPP
START_NAMESPACE
std
::
new_handler
_new_handler
;
void
_set_new_handler
(
std
::
new_handler
h
)
{
initialize
();
_new_handler
=
h
;
}
static
call_t
delete_call
;
static
BOOL
delete_called
;
void
set_delete_call
(
int
line
,
const
char
*
file
)
{
initialize
();
delete_call
=
pack
(
0
,
""
,
line
,
file
);
/*func értéke lényegtelen, majd felülírjuk*/
delete_called
=
TRUE
;
}
void
*
traced_new
(
size_t
size
,
int
line
,
const
char
*
file
,
int
func
)
{
initialize
();
for
(;;)
{
void
*
p
=
canary_malloc
(
size
,
random_byte
);
if
(
p
)
{
register_memory
(
p
,
size
,
pack
(
func
,
""
,
line
,
file
));
return
PU
(
p
);
}
if
(
_new_handler
==
0
)
throw
std
::
bad_alloc
();
_new_handler
();
}
}
void
traced_delete
(
void
*
pu
,
int
func
)
{
initialize
();
if
(
pu
)
{
/*kiolvasom call-t, ha van*/
memtrace
::
call_t
call
=
delete_called
?
(
delete_call
.
f
=
func
,
delete_call
)
:
pack
(
func
,
NULL
,
0
,
NULL
);
memtrace
::
unregister_memory
(
P
(
pu
),
call
);
free
(
P
(
pu
));
}
delete_called
=
FALSE
;
}
END_NAMESPACE
void
*
operator
new
(
size_t
size
,
int
line
,
const
char
*
file
)
THROW_BADALLOC
{
return
memtrace
::
traced_new
(
size
,
line
,
file
,
FNEW
);
}
void
*
operator
new
[](
size_t
size
,
int
line
,
const
char
*
file
)
THROW_BADALLOC
{
return
memtrace
::
traced_new
(
size
,
line
,
file
,
FNEWARR
);
}
void
*
operator
new
(
size_t
size
)
THROW_BADALLOC
{
return
memtrace
::
traced_new
(
size
,
0
,
NULL
,
FNEW
);
}
void
*
operator
new
[](
size_t
size
)
THROW_BADALLOC
{
return
memtrace
::
traced_new
(
size
,
0
,
NULL
,
FNEWARR
);
}
void
operator
delete
(
void
*
p
)
THROW_NOTHING
{
memtrace
::
traced_delete
(
p
,
FDELETE
);
}
void
operator
delete
[](
void
*
p
)
THROW_NOTHING
{
memtrace
::
traced_delete
(
p
,
FDELETEARR
);
}
/* Visual C++ 2012 miatt kell, mert háklis, hogy nincs megfelelő delete, bár senki sem használja */
void
operator
delete
(
void
*
p
,
int
,
const
char
*
)
THROW_NOTHING
{
memtrace
::
traced_delete
(
p
,
FDELETE
);
}
void
operator
delete
[](
void
*
p
,
int
,
const
char
*
)
THROW_NOTHING
{
memtrace
::
traced_delete
(
p
,
FDELETE
);
}
#endif
/*MEMTRACE_CPP*/
/*******************************************************************/
/* initialize */
/*******************************************************************/
START_NAMESPACE
static
void
initialize
()
{
static
BOOL
first
=
TRUE
;
if
(
first
)
{
fperror
=
stderr
;
random_byte
=
(
unsigned
char
)
time
(
NULL
);
first
=
FALSE
;
dying
=
FALSE
;
#ifdef MEMTRACE_TO_MEMORY
registry
.
next
=
NULL
;
#if !defined(USE_ATEXIT_OBJECT) && defined(MEMTRACE_AUTO)
atexit
((
void
(
*
)(
void
))
mem_check
);
#endif
#endif
#ifdef MEMTRACE_TO_FILE
trace_file
=
fopen
(
"memtrace.dump"
,
"w"
);
#endif
#ifdef MEMTRACE_CPP
_new_handler
=
NULL
;
delete_called
=
FALSE
;
delete_call
=
pack
(
0
,
NULL
,
0
,
NULL
);
#endif
}
}
#if defined(MEMTRACE_TO_MEMORY) && defined(USE_ATEXIT_OBJECT)
int
atexit_class
::
counter
=
0
;
int
atexit_class
::
err
=
0
;
#endif
END_NAMESPACE
#endif
bugs/memtrace.h
0 → 100644
View file @
820b2618
/*********************************
Memoriaszivargas-detektor
Keszitette: Peregi Tamas, BME IIT, 2011
petamas@iit.bme.hu
Kanari: Szeberenyi Imre, 2013.,
VS 2012: Szeberényi Imre, 2015.,
mem_dump: 2016.
inclue-ok: 2017., 2018. 2019.
*********************************/
#ifndef MEMTRACE_H
#define MEMTRACE_H
#if defined(MEMTRACE)
/*ha definiálva van, akkor a hibakat ebbe a fajlba írja, egyébkent stderr-re*/
/*#define MEMTRACE_ERRFILE MEMTRACE.ERR*/
/*ha definialva van, akkor futas kozben lancolt listat epit. Javasolt a hasznalata*/
#define MEMTRACE_TO_MEMORY
/*ha definialva van, akkor futas kozben fajlba irja a foglalasokat*/
/*ekkor nincs ellenorzes, csak naplozas*/
/*#define MEMTRACE_TO_FILE*/
/*ha definialva van, akkor a megallaskor automatikus riport keszul */
#define MEMTRACE_AUTO
/*ha definialva van, akkor malloc()/calloc()/realloc()/free() kovetve lesz*/
#define MEMTRACE_C
#ifdef MEMTRACE_C
/*ha definialva van, akkor free(NULL) nem okoz hibat*/
#define ALLOW_FREE_NULL
#endif
#ifdef __cplusplus
/*ha definialva van, akkor new/delete/new[]/delete[] kovetve lesz*/
#define MEMTRACE_CPP
#endif
#if defined(__cplusplus) && defined(MEMTRACE_TO_MEMORY)
/*ha definialva van, akkor atexit helyett objektumot hasznal*/
/*ajanlott bekapcsolni*/
#define USE_ATEXIT_OBJECT
#endif
/******************************************/
/* INNEN NE MODOSITSD */
/******************************************/
#ifdef NO_MEMTRACE_TO_FILE
#undef MEMTRACE_TO_FILE
#endif
#ifdef NO_MEMTRACE_TO_MEMORY
#undef MEMTRACE_TO_MEMORY
#endif
#ifndef MEMTRACE_AUTO
#undef USE_ATEXIT_OBJECT
#endif
#ifdef __cplusplus
#define START_NAMESPACE namespace memtrace {
#define END_NAMESPACE }
/*namespace*/
#define TRACEC(func) memtrace::func
#include <new>
#else
#define START_NAMESPACE
#define END_NAMESPACE
#define TRACEC(func) func
#endif
// THROW deklaráció változatai
#if defined(_MSC_VER)
// VS rosszul kezeli az __cplusplus makrot
#if _MSC_VER < 1900
// * nem biztos, hogy jó így *
#define THROW_BADALLOC
#define THROW_NOTHING
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#else
#if __cplusplus < 201103L
// C++2003 vagy régebbi
#define THROW_BADALLOC throw (std::bad_alloc)
#define THROW_NOTHING throw ()
#else
// C++11 vagy újabb
#define THROW_BADALLOC noexcept(false)
#define THROW_NOTHING noexcept
#endif
#endif
START_NAMESPACE
int
allocated_blocks
();
END_NAMESPACE
#if defined(MEMTRACE_TO_MEMORY)
START_NAMESPACE
int
mem_check
(
void
);
END_NAMESPACE
#endif
#if defined(MEMTRACE_TO_MEMORY) && defined(USE_ATEXIT_OBJECT)
#include <cstdio>
START_NAMESPACE
class
atexit_class
{
private
:
static
int
counter
;
static
int
err
;
public
:
atexit_class
()
{
#if defined(CPORTA) && !defined(CPORTA_NOSETBUF)
if
(
counter
==
0
)
{
setbuf
(
stdout
,
0
);
setbuf
(
stderr
,
0
);
}
#endif
counter
++
;
}
int
check
()
{
if
(
--
counter
==
0
)
err
=
mem_check
();
return
err
;
}
~
atexit_class
()
{
check
();
}
};
static
atexit_class
atexit_obj
;
END_NAMESPACE
#endif
/*MEMTRACE_TO_MEMORY && USE_ATEXIT_OBJECT*/
/*Innentol csak a "normal" include eseten kell, kulonben osszezavarja a mukodest*/
#ifndef FROM_MEMTRACE_CPP
#include <stdlib.h>
#ifdef __cplusplus
#include <iostream>
/* ide gyűjtjük a nemtrace-vel összeakadó headereket, hogy előbb legyenek */
#include <fstream> // VS 2013 headerjében van deleted definició
#include <sstream>
#include <vector>
#include <list>
#include <map>
#include <algorithm>
#include <functional>
#include <memory>
#include <iomanip>
#include <locale>
#include <typeinfo>
#include <ostream>
#include <stdexcept>
#endif
#ifdef MEMTRACE_CPP
namespace
std
{
typedef
void
(
*
new_handler
)();
}
#endif
#ifdef MEMTRACE_C
START_NAMESPACE
#undef malloc
#define malloc(size) TRACEC(traced_malloc)(size,#size,__LINE__,__FILE__)
void
*
traced_malloc
(
size_t
size
,
const
char
*
size_txt
,
int
line
,
const
char
*
file
);
#undef calloc
#define calloc(count,size) TRACEC(traced_calloc)(count, size, #count","#size,__LINE__,__FILE__)
void
*
traced_calloc
(
size_t
count
,
size_t
size
,
const
char
*
size_txt
,
int
line
,
const
char
*
file
);
#undef free
#define free(p) TRACEC(traced_free)(p, #p,__LINE__,__FILE__)
void
traced_free
(
void
*
p
,
const
char
*
size_txt
,
int
line
,
const
char
*
file
);
#undef realloc
#define realloc(old,size) TRACEC(traced_realloc)(old,size,#size,__LINE__,__FILE__)
void
*
traced_realloc
(
void
*
old
,
size_t
size
,
const
char
*
size_txt
,
int
line
,
const
char
*
file
);
void
mem_dump
(
void
const
*
mem
,
size_t
size
,
FILE
*
fp
);
END_NAMESPACE
#endif
/*MEMTRACE_C*/
#ifdef MEMTRACE_CPP
START_NAMESPACE
#undef set_new_handler
#define set_new_handler(f) TRACEC(_set_new_handler)(f)
void
_set_new_handler
(
std
::
new_handler
h
);
void
set_delete_call
(
int
line
,
const
char
*
file
);
END_NAMESPACE
void
*
operator
new
(
size_t
size
,
int
line
,
const
char
*
file
)
THROW_BADALLOC
;
void
*
operator
new
[](
size_t
size
,
int
line
,
const
char
*
file
)
THROW_BADALLOC
;
void
*
operator
new
(
size_t
size
)
THROW_BADALLOC
;
void
*
operator
new
[](
size_t
size
)
THROW_BADALLOC
;
void
operator
delete
(
void
*
p
)
THROW_NOTHING
;
void
operator
delete
[](
void
*
p
)
THROW_NOTHING
;
/* Visual C++ 2012 miatt kell, mert háklis, hogy nincs megfelelő delete, bár senki sem használja */
void
operator
delete
(
void
*
p
,
int
,
const
char
*
)
THROW_NOTHING
;
void
operator
delete
[](
void
*
p
,
int
,
const
char
*
)
THROW_NOTHING
;
#define new new(__LINE__, __FILE__)
#define delete memtrace::set_delete_call(__LINE__, __FILE__),delete
#ifdef CPORTA
#define system(...) // system(__VA_ARGS__)
#endif
#endif
/*MEMTRACE_CPP*/
#endif
/*FROM_MEMTRACE_CPP*/
#endif
/*MEMCHECK*/
#endif
/*MEMTRACE_H*/
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment