Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
4c2c9871
Unverified
Commit
4c2c9871
authored
Nov 26, 2019
by
Dominik Charousset
Committed by
GitHub
Nov 26, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #982
Fix undefined behavior, build with UBSan in Jenkins
parents
c6050d9b
1412244d
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
79 additions
and
92 deletions
+79
-92
CMakeLists.txt
CMakeLists.txt
+3
-3
Jenkinsfile
Jenkinsfile
+4
-3
configure
configure
+10
-21
libcaf_core/caf/detail/init_fun_factory.hpp
libcaf_core/caf/detail/init_fun_factory.hpp
+51
-38
libcaf_core/caf/intrusive/forward_iterator.hpp
libcaf_core/caf/intrusive/forward_iterator.hpp
+2
-2
libcaf_core/caf/intrusive/task_queue.hpp
libcaf_core/caf/intrusive/task_queue.hpp
+4
-15
libcaf_core/caf/mixin/subscriber.hpp
libcaf_core/caf/mixin/subscriber.hpp
+3
-7
libcaf_core/src/node_id.cpp
libcaf_core/src/node_id.cpp
+2
-1
libcaf_core/test/intrusive/drr_queue.cpp
libcaf_core/test/intrusive/drr_queue.cpp
+0
-1
libcaf_core/test/intrusive/task_queue.cpp
libcaf_core/test/intrusive/task_queue.cpp
+0
-1
No files found.
CMakeLists.txt
View file @
4c2c9871
...
@@ -313,10 +313,10 @@ else()
...
@@ -313,10 +313,10 @@ else()
endif
()
endif
()
# enable address sanitizer if requested by the user
# enable address sanitizer if requested by the user
if
(
CAF_
ENABLE_ADDRESS_SANITIZER AND NOT WIN32
)
if
(
CAF_
SANITIZERS
)
add_compile_options
(
"-fsanitize=
address
"
add_compile_options
(
"-fsanitize=
${
CAF_SANITIZERS
}
"
"-fno-omit-frame-pointer"
)
"-fno-omit-frame-pointer"
)
list
(
APPEND CAF_EXTRA_LDFLAGS
"-fsanitize=
address
"
)
list
(
APPEND CAF_EXTRA_LDFLAGS
"-fsanitize=
${
CAF_SANITIZERS
}
"
)
endif
()
endif
()
# -pthread is ignored on MacOSX but required on other platforms
# -pthread is ignored on MacOSX but required on other platforms
if
(
NOT APPLE AND NOT WIN32
)
if
(
NOT APPLE AND NOT WIN32
)
...
...
Jenkinsfile
View file @
4c2c9871
...
@@ -6,12 +6,11 @@
...
@@ -6,12 +6,11 @@
defaultReleaseBuildFlags
=
[
defaultReleaseBuildFlags
=
[
'CAF_ENABLE_RUNTIME_CHECKS:BOOL=yes'
,
'CAF_ENABLE_RUNTIME_CHECKS:BOOL=yes'
,
'CAF_NO_OPENCL:BOOL=yes'
,
'CAF_NO_OPENCL:BOOL=yes'
,
'CAF_INSTALL_UNIT_TESTS:BOOL=yes'
,
]
]
// Default CMake flags for debug builds.
// Default CMake flags for debug builds.
defaultDebugBuildFlags
=
defaultReleaseBuildFlags
+
[
defaultDebugBuildFlags
=
defaultReleaseBuildFlags
+
[
'CAF_
ENABLE_ADDRESS_SANITIZER:BOOL=yes
'
,
'CAF_
SANITIZERS:STRING=address,undefined
'
,
'CAF_LOG_LEVEL:STRING=TRACE'
,
'CAF_LOG_LEVEL:STRING=TRACE'
,
'CAF_ENABLE_ACTOR_PROFILER:BOOL=yes'
,
'CAF_ENABLE_ACTOR_PROFILER:BOOL=yes'
,
]
]
...
@@ -99,7 +98,9 @@ config = [
...
@@ -99,7 +98,9 @@ config = [
],
],
],
],
Windows:
[
Windows:
[
debug:
defaultDebugBuildFlags
+
[
debug:
[
'CAF_LOG_LEVEL:STRING=TRACE'
,
'CAF_ENABLE_ACTOR_PROFILER:BOOL=yes'
,
'CAF_BUILD_STATIC_ONLY:BOOL=yes'
,
'CAF_BUILD_STATIC_ONLY:BOOL=yes'
,
],
],
release:
defaultReleaseBuildFlags
+
[
release:
defaultReleaseBuildFlags
+
[
...
...
configure
View file @
4c2c9871
...
@@ -76,16 +76,14 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
...
@@ -76,16 +76,14 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
- INFO
- INFO
- DEBUG
- DEBUG
- TRACE
- TRACE
--with-address-sanitizer build with address sanitizer if available
--with-sanitizers=LIST build with this list of sanitizers enabled
--with-asan alias for --with-address-sanitier
--enable-asan alias for --with-address-sanitier
--with-gcov build with gcov coverage enabled
--with-actor-profiler enables the (experimental) actor_profiler API
--with-actor-profiler enables the (experimental) actor_profiler API
Convenience options:
Convenience options:
--dev-mode sets --build-type=debug, --no-examples,
--dev-mode sets --build-type=debug, --no-examples,
--no-tools, --with-runtime-checks,
--no-tools, --with-runtime-checks,
--log-level=trace, and --enable-asan
--log-level=trace, and
--sanitizers=address,undefined
Influential Environment Variables (only on first invocation):
Influential Environment Variables (only on first invocation):
CXX C++ compiler command
CXX C++ compiler command
...
@@ -238,17 +236,8 @@ while [ $# -ne 0 ]; do
...
@@ -238,17 +236,8 @@ while [ $# -ne 0 ]; do
--with-runtime-checks
)
--with-runtime-checks
)
append_cache_entry CAF_ENABLE_RUNTIME_CHECKS BOOL
yes
append_cache_entry CAF_ENABLE_RUNTIME_CHECKS BOOL
yes
;;
;;
--with-address-sanitizer
)
--with-sanitizers
=
*
)
append_cache_entry CAF_ENABLE_ADDRESS_SANITIZER BOOL
yes
append_cache_entry CAF_SANITIZERS STRING
"
$optarg
"
;;
--with-asan
)
append_cache_entry CAF_ENABLE_ADDRESS_SANITIZER BOOL
yes
;;
--enable-asan
)
append_cache_entry CAF_ENABLE_ADDRESS_SANITIZER BOOL
yes
;;
--with-gcov
)
append_cache_entry CAF_ENABLE_GCOV BOOL
yes
;;
;;
--with-actor-profiler
)
--with-actor-profiler
)
append_cache_entry CAF_ENABLE_ACTOR_PROFILER BOOL
yes
append_cache_entry CAF_ENABLE_ACTOR_PROFILER BOOL
yes
...
@@ -374,12 +363,12 @@ while [ $# -ne 0 ]; do
...
@@ -374,12 +363,12 @@ while [ $# -ne 0 ]; do
done
done
;;
;;
--dev-mode
)
--dev-mode
)
append_cache_entry CMAKE_BUILD_TYPE STRING Debug
for
var
in
CAF_NO_TOOLS CAF_NO_EXAMPLES CAF_ENABLE_RUNTIME_CHECKS
;
do
append_cache_entry CAF_NO_EXAMPLES BOOL
yes
append_cache_entry
$var
BOOL
yes
append_cache_entry CAF_NO_TOOLS BOOL
yes
done
append_cache_entry CMAKE_BUILD_TYPE STRING debug
append_cache_entry CAF_LOG_LEVEL STRING TRACE
append_cache_entry CAF_LOG_LEVEL STRING TRACE
append_cache_entry CAF_ENABLE_RUNTIME_CHECKS BOOL
yes
append_cache_entry CAF_SANITIZERS STRING address,undefined
append_cache_entry CAF_ENABLE_ADDRESS_SANITIZER BOOL
yes
;;
;;
*
)
*
)
echo
"Invalid option '
$1
'. Try
$0
--help to see available options."
echo
"Invalid option '
$1
'. Try
$0
--help to see available options."
...
...
libcaf_core/caf/detail/init_fun_factory.hpp
View file @
4c2c9871
...
@@ -55,13 +55,16 @@ protected:
...
@@ -55,13 +55,16 @@ protected:
};
};
/// Wraps a user-defined function and gives it a uniform signature.
/// Wraps a user-defined function and gives it a uniform signature.
template
<
class
Base
,
class
F
,
class
ArgsPtr
,
bool
ReturnsBehavior
,
template
<
class
Base
,
class
F
,
class
Tuple
,
bool
ReturnsBehavior
,
bool
HasSelfPtr
>
bool
HasSelfPtr
>
class
init_fun_factory_helper
final
:
public
init_fun_factory_helper_base
{
class
init_fun_factory_helper
final
:
public
init_fun_factory_helper_base
{
public:
public:
init_fun_factory_helper
(
F
fun
,
ArgsPtr
args
)
using
args_pointer
=
std
::
shared_ptr
<
Tuple
>
;
:
fun_
(
std
::
move
(
fun
)),
args_
(
std
::
move
(
args
))
{
static
constexpr
bool
args_empty
=
std
::
tuple_size
<
Tuple
>::
value
==
0
;
init_fun_factory_helper
(
F
fun
,
args_pointer
args
)
:
fun_
(
std
::
move
(
fun
)),
args_
(
std
::
move
(
args
))
{
// nop
// nop
}
}
...
@@ -72,41 +75,52 @@ public:
...
@@ -72,41 +75,52 @@ public:
behavior
operator
()(
local_actor
*
self
)
final
{
behavior
operator
()(
local_actor
*
self
)
final
{
if
(
hook_
!=
nullptr
)
if
(
hook_
!=
nullptr
)
hook_
(
self
);
hook_
(
self
);
bool_token
<
ReturnsBehavior
>
returns_behavior_token
;
auto
dptr
=
static_cast
<
Base
*>
(
self
);
bool_token
<
HasSelfPtr
>
captures_self_token
;
if
constexpr
(
ReturnsBehavior
)
{
return
apply
(
returns_behavior_token
,
captures_self_token
,
self
);
auto
unbox
=
[](
auto
x
)
->
behavior
{
return
std
::
move
(
x
.
unbox
());
};
}
if
constexpr
(
args_empty
)
{
if
constexpr
(
HasSelfPtr
)
{
// behavior (pointer)
private:
return
unbox
(
fun_
(
dptr
));
// behavior (pointer)
}
else
{
behavior
apply
(
std
::
true_type
,
std
::
true_type
,
local_actor
*
ptr
)
{
// behavior ()
auto
res
=
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
*
args_
,
return
unbox
(
fun_
());
static_cast
<
Base
*>
(
ptr
));
}
return
std
::
move
(
res
.
unbox
());
}
else
{
}
if
constexpr
(
HasSelfPtr
)
{
// behavior (pointer, args...)
// void (pointer)
auto
res
=
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
behavior
apply
(
std
::
false_type
,
std
::
true_type
,
local_actor
*
ptr
)
{
*
args_
,
dptr
);
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
return
unbox
(
std
::
move
(
res
));
*
args_
,
static_cast
<
Base
*>
(
ptr
));
}
else
{
return
behavior
{};
// behavior (args...)
}
return
unbox
(
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
));
}
// behavior ()
}
behavior
apply
(
std
::
true_type
,
std
::
false_type
,
local_actor
*
)
{
}
else
{
auto
res
=
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
);
if
constexpr
(
args_empty
)
{
return
std
::
move
(
res
.
unbox
());
if
constexpr
(
HasSelfPtr
)
{
}
// void (pointer)
fun_
(
dptr
);
// void ()
}
else
{
behavior
apply
(
std
::
false_type
,
std
::
false_type
,
local_actor
*
)
{
// void ()
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
);
fun_
();
return
behavior
{};
}
}
else
{
if
constexpr
(
HasSelfPtr
)
{
// void (pointer, args...)
apply_moved_args_prefixed
(
fun_
,
get_indices
(
*
args_
),
*
args_
,
dptr
);
}
else
{
// void (args...)
apply_args
(
fun_
,
get_indices
(
*
args_
),
*
args_
);
}
}
return
{};
}
}
}
F
fun_
;
F
fun_
;
ArgsPt
r
args_
;
args_pointe
r
args_
;
};
};
template
<
class
Base
,
class
F
>
template
<
class
Base
,
class
F
>
...
@@ -127,8 +141,7 @@ public:
...
@@ -127,8 +141,7 @@ public:
constexpr
bool
selfptr
=
std
::
is_pointer
<
first_arg
>::
value
;
constexpr
bool
selfptr
=
std
::
is_pointer
<
first_arg
>::
value
;
constexpr
bool
rets
=
std
::
is_convertible
<
res_type
,
behavior
>::
value
;
constexpr
bool
rets
=
std
::
is_convertible
<
res_type
,
behavior
>::
value
;
using
tuple_type
=
decltype
(
std
::
make_tuple
(
detail
::
spawn_fwd
<
Ts
>
(
xs
)...));
using
tuple_type
=
decltype
(
std
::
make_tuple
(
detail
::
spawn_fwd
<
Ts
>
(
xs
)...));
using
tuple_ptr
=
std
::
shared_ptr
<
tuple_type
>
;
using
helper
=
init_fun_factory_helper
<
Base
,
F
,
tuple_type
,
rets
,
selfptr
>
;
using
helper
=
init_fun_factory_helper
<
Base
,
F
,
tuple_ptr
,
rets
,
selfptr
>
;
return
ptr_type
{
new
helper
{
std
::
move
(
f
),
sizeof
...(
Ts
)
>
0
return
ptr_type
{
new
helper
{
std
::
move
(
f
),
sizeof
...(
Ts
)
>
0
?
std
::
make_shared
<
tuple_type
>
(
?
std
::
make_shared
<
tuple_type
>
(
detail
::
spawn_fwd
<
Ts
>
(
xs
)...)
detail
::
spawn_fwd
<
Ts
>
(
xs
)...)
...
...
libcaf_core/caf/intrusive/forward_iterator.hpp
View file @
4c2c9871
...
@@ -84,13 +84,13 @@ public:
...
@@ -84,13 +84,13 @@ public:
// -- operators --------------------------------------------------------------
// -- operators --------------------------------------------------------------
forward_iterator
&
operator
++
()
{
forward_iterator
&
operator
++
()
{
ptr
=
p
romote
(
ptr
->
next
)
;
ptr
=
p
tr
->
next
;
return
*
this
;
return
*
this
;
}
}
forward_iterator
operator
++
(
int
)
{
forward_iterator
operator
++
(
int
)
{
forward_iterator
res
=
*
this
;
forward_iterator
res
=
*
this
;
ptr
=
p
romote
(
ptr
->
next
)
;
ptr
=
p
tr
->
next
;
return
res
;
return
res
;
}
}
...
...
libcaf_core/caf/intrusive/task_queue.hpp
View file @
4c2c9871
...
@@ -173,10 +173,8 @@ public:
...
@@ -173,10 +173,8 @@ public:
/// @private
/// @private
task_size_type
next_task_size
()
const
noexcept
{
task_size_type
next_task_size
()
const
noexcept
{
if
(
head_
.
next
==
nullptr
)
auto
ptr
=
head_
.
next
;
return
0
;
return
ptr
!=
&
tail_
?
policy_
.
task_size
(
*
promote
(
ptr
))
:
0
;
auto
ptr
=
promote
(
head_
.
next
);
return
policy_
.
task_size
(
*
ptr
);
}
}
/// @private
/// @private
...
@@ -203,16 +201,6 @@ public:
...
@@ -203,16 +201,6 @@ public:
// -- iterator access --------------------------------------------------------
// -- iterator access --------------------------------------------------------
/// Returns an iterator to the dummy before the first element.
iterator
before_begin
()
noexcept
{
return
&
head_
;
}
/// Returns an iterator to the dummy before the first element.
const_iterator
before_begin
()
const
noexcept
{
return
&
head_
;
}
/// Returns an iterator to the dummy before the first element.
/// Returns an iterator to the dummy before the first element.
iterator
begin
()
noexcept
{
iterator
begin
()
noexcept
{
return
head_
.
next
;
return
head_
.
next
;
...
@@ -252,6 +240,7 @@ public:
...
@@ -252,6 +240,7 @@ public:
/// Returns a pointer to the last element.
/// Returns a pointer to the last element.
pointer
back
()
noexcept
{
pointer
back
()
noexcept
{
CAF_ASSERT
(
head_
.
next
!=
&
tail_
);
return
promote
(
tail_
.
next
);
return
promote
(
tail_
.
next
);
}
}
...
@@ -319,7 +308,7 @@ public:
...
@@ -319,7 +308,7 @@ public:
/// @private
/// @private
void
lifo_append
(
node_pointer
ptr
)
{
void
lifo_append
(
node_pointer
ptr
)
{
if
(
old_last_
==
nullptr
)
{
if
(
old_last_
==
nullptr
)
{
old_last_
=
back
()
;
old_last_
=
tail_
.
next
;
push_back
(
promote
(
ptr
));
push_back
(
promote
(
ptr
));
}
else
{
}
else
{
ptr
->
next
=
new_head_
;
ptr
->
next
=
new_head_
;
...
...
libcaf_core/caf/mixin/subscriber.hpp
View file @
4c2c9871
...
@@ -54,7 +54,7 @@ public:
...
@@ -54,7 +54,7 @@ public:
// -- overridden functions of monitorable_actor ------------------------------
// -- overridden functions of monitorable_actor ------------------------------
bool
cleanup
(
error
&&
fail_state
,
execution_unit
*
ptr
)
override
{
bool
cleanup
(
error
&&
fail_state
,
execution_unit
*
ptr
)
override
{
auto
me
=
dptr
()
->
ctrl
();
auto
me
=
this
->
ctrl
();
for
(
auto
&
subscription
:
subscriptions_
)
for
(
auto
&
subscription
:
subscriptions_
)
subscription
->
unsubscribe
(
me
);
subscription
->
unsubscribe
(
me
);
subscriptions_
.
clear
();
subscriptions_
.
clear
();
...
@@ -69,7 +69,7 @@ public:
...
@@ -69,7 +69,7 @@ public:
CAF_LOG_TRACE
(
CAF_ARG
(
what
));
CAF_LOG_TRACE
(
CAF_ARG
(
what
));
if
(
what
==
invalid_group
)
if
(
what
==
invalid_group
)
return
;
return
;
if
(
what
->
subscribe
(
dptr
()
->
ctrl
()))
if
(
what
->
subscribe
(
this
->
ctrl
()))
subscriptions_
.
emplace
(
what
);
subscriptions_
.
emplace
(
what
);
}
}
...
@@ -77,7 +77,7 @@ public:
...
@@ -77,7 +77,7 @@ public:
void
leave
(
const
group
&
what
)
{
void
leave
(
const
group
&
what
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
what
));
CAF_LOG_TRACE
(
CAF_ARG
(
what
));
if
(
subscriptions_
.
erase
(
what
)
>
0
)
if
(
subscriptions_
.
erase
(
what
)
>
0
)
what
->
unsubscribe
(
dptr
()
->
ctrl
());
what
->
unsubscribe
(
this
->
ctrl
());
}
}
/// Returns all subscribed groups.
/// Returns all subscribed groups.
...
@@ -86,10 +86,6 @@ public:
...
@@ -86,10 +86,6 @@ public:
}
}
private:
private:
Subtype
*
dptr
()
{
return
static_cast
<
Subtype
*>
(
this
);
}
// -- data members -----------------------------------------------------------
// -- data members -----------------------------------------------------------
/// Stores all subscribed groups.
/// Stores all subscribed groups.
...
...
libcaf_core/src/node_id.cpp
View file @
4c2c9871
...
@@ -100,7 +100,8 @@ bool node_id::default_data::valid() const noexcept {
...
@@ -100,7 +100,8 @@ bool node_id::default_data::valid() const noexcept {
size_t
node_id
::
default_data
::
hash_code
()
const
noexcept
{
size_t
node_id
::
default_data
::
hash_code
()
const
noexcept
{
// XOR the first few bytes from the node ID and the process ID.
// XOR the first few bytes from the node ID and the process ID.
auto
x
=
static_cast
<
size_t
>
(
pid_
);
auto
x
=
static_cast
<
size_t
>
(
pid_
);
auto
y
=
*
reinterpret_cast
<
const
size_t
*>
(
host_
.
data
());
size_t
y
;
memcpy
(
&
y
,
host_
.
data
(),
sizeof
(
size_t
));
return
x
^
y
;
return
x
^
y
;
}
}
...
...
libcaf_core/test/intrusive/drr_queue.cpp
View file @
4c2c9871
...
@@ -87,7 +87,6 @@ CAF_TEST(default_constructed) {
...
@@ -87,7 +87,6 @@ CAF_TEST(default_constructed) {
CAF_REQUIRE_EQUAL
(
queue
.
peek
(),
nullptr
);
CAF_REQUIRE_EQUAL
(
queue
.
peek
(),
nullptr
);
CAF_REQUIRE_EQUAL
(
queue
.
next
(),
nullptr
);
CAF_REQUIRE_EQUAL
(
queue
.
next
(),
nullptr
);
CAF_REQUIRE_EQUAL
(
queue
.
begin
(),
queue
.
end
());
CAF_REQUIRE_EQUAL
(
queue
.
begin
(),
queue
.
end
());
CAF_REQUIRE_EQUAL
(
queue
.
before_begin
()
->
next
,
queue
.
end
().
ptr
);
}
}
CAF_TEST
(
inc_deficit
)
{
CAF_TEST
(
inc_deficit
)
{
...
...
libcaf_core/test/intrusive/task_queue.cpp
View file @
4c2c9871
...
@@ -83,7 +83,6 @@ CAF_TEST(default_constructed) {
...
@@ -83,7 +83,6 @@ CAF_TEST(default_constructed) {
CAF_REQUIRE_EQUAL
(
queue
.
total_task_size
(),
0
);
CAF_REQUIRE_EQUAL
(
queue
.
total_task_size
(),
0
);
CAF_REQUIRE_EQUAL
(
queue
.
peek
(),
nullptr
);
CAF_REQUIRE_EQUAL
(
queue
.
peek
(),
nullptr
);
CAF_REQUIRE_EQUAL
(
queue
.
begin
(),
queue
.
end
());
CAF_REQUIRE_EQUAL
(
queue
.
begin
(),
queue
.
end
());
CAF_REQUIRE_EQUAL
(
queue
.
before_begin
()
->
next
,
queue
.
end
().
ptr
);
}
}
CAF_TEST
(
push_back
)
{
CAF_TEST
(
push_back
)
{
...
...
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