'Valgrind errors not reported when function is inlined
I've been trying to track down the cause of an error reported by Valgrind (see below). It says that a 'Conditional jump or move depends on uninitialised value(s)', pointing to a function call. When I inline that function however, the error is no longer reported.
Original function
bool is_unsafe_piece_hook(Gamestate & gs, const Square s) {
Piece p = gs.board.get(s);
Colour c = colour(p);
if (p == EMPTY) { return true; }
SquareControlStatus ss = gs.control_cache->get_control_status(s);
if (is_weak_status(gs, s, c, ss)) {
return gs.add_frame(unsafe_piece_hook.id, FeatureFrame{s, SQUARE_SENTINEL, ss.min_w, ss.min_b});
}
* if (pawn_is_en_passantable(gs, s)) {
return gs.add_frame(unsafe_piece_hook.id, FeatureFrame{s, SQUARE_SENTINEL, ss.min_w, ss.min_b});
}
return true;
}
Error reported
The line referred to is marked with an asterisk above.
==22305== Conditional jump or move depends on uninitialised value(s)
==22305== at 0x196D56: is_unsafe_piece_hook(Gamestate&, Square) (unsafe_piece.cpp:38)
==22305== by 0x194963: discover_feature_frames (cands.cpp:22)
==22305== by 0x194963: cands(Gamestate&, CandSet*) (cands.cpp:65)
==22305== by 0x192910: deepen(SearchNode*, CandList, int, Observer&, bool) (greedy.cpp:117)
==22305== by 0x192AD0: deepen(SearchNode*, CandList, int, Observer&, bool) (greedy.cpp:77)
==22305== by 0x192A01: deepen(SearchNode*, CandList, int, Observer&, bool) (greedy.cpp:133)
==22305== by 0x192A01: deepen(SearchNode*, CandList, int, Observer&, bool) (greedy.cpp:133)
==22305== by 0x192F8B: visit_node(SearchNode*, Observer&) [clone .part.0] (greedy.cpp:181)
==22305== by 0x193135: visit_node (greedy.cpp:151)
==22305== by 0x193135: visit_best_line(SearchNode*, bool, Observer&) (greedy.cpp:272)
==22305== by 0x193117: visit_best_line(SearchNode*, bool, Observer&) (greedy.cpp:271)
==22305== by 0x193117: visit_best_line(SearchNode*, bool, Observer&) (greedy.cpp:271)
==22305== by 0x193117: visit_best_line(SearchNode*, bool, Observer&) (greedy.cpp:271)
==22305== by 0x1932B1: visit_best_line (greedy.cpp:271)
==22305== by 0x1932B1: greedy_search(SearchNode*, int, Observer&) (greedy.cpp:299)
==22305== Uninitialised value was created by a heap allocation
==22305== at 0x483BE63: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==22305== by 0x18FC3C: new_node(Gamestate const&, Move) (search.cpp:183)
==22305== by 0x1928D5: deepen(SearchNode*, CandList, int, Observer&, bool) (greedy.cpp:116)
==22305== by 0x192AD0: deepen(SearchNode*, CandList, int, Observer&, bool) (greedy.cpp:77)
==22305== by 0x192A01: deepen(SearchNode*, CandList, int, Observer&, bool) (greedy.cpp:133)
==22305== by 0x192A01: deepen(SearchNode*, CandList, int, Observer&, bool) (greedy.cpp:133)
==22305== by 0x192F8B: visit_node(SearchNode*, Observer&) [clone .part.0] (greedy.cpp:181)
==22305== by 0x193135: visit_node (greedy.cpp:151)
==22305== by 0x193135: visit_best_line(SearchNode*, bool, Observer&) (greedy.cpp:272)
==22305== by 0x193117: visit_best_line(SearchNode*, bool, Observer&) (greedy.cpp:271)
==22305== by 0x193117: visit_best_line(SearchNode*, bool, Observer&) (greedy.cpp:271)
==22305== by 0x193117: visit_best_line(SearchNode*, bool, Observer&) (greedy.cpp:271)
==22305== by 0x1932B1: visit_best_line (greedy.cpp:271)
==22305== by 0x1932B1: greedy_search(SearchNode*, int, Observer&) (greedy.cpp:299)
Modified function
Valgrind reports no errors when using the modified version. The function pawn_is_en_passantable has been inlined (manually) corresponding to the code within the inner block marked with asterisks.
bool is_unsafe_piece_hook(Gamestate & gs, const Square s) {
Piece p = gs.board.get(s);
Colour c = colour(p);
if (p == EMPTY) { return true; }
SquareControlStatus ss = gs.control_cache->get_control_status(s);
if (is_weak_status(gs, s, c, ss)) {
return gs.add_frame(unsafe_piece_hook.id, FeatureFrame{s, SQUARE_SENTINEL, ss.min_w, ss.min_b});
}
bool en_passantable;
* {
Piece p2 = gs.board.get(s);
Colour c2 = colour(p2);
// check we have a pawn on the correct square
if (!gs.board.get_ep_exists()
|| type(p2) != PAWN
|| !equal(s, gs.board.get_ep_pawn_square())) {
return false;
}
// check there is indeed a pawn to capture it
Square l_sq = mksq(s.x + 1, s.y);
Square r_sq = mksq(s.x - 1, s.y);
Piece enemy_pawn = (c2 == WHITE ? B_PAWN : W_PAWN);
en_passantable =
(s.x > 0 && gs.board.get(l_sq) == enemy_pawn)
|| (s.x < 7 && gs.board.get(r_sq) == enemy_pawn);
* }
if (en_passantable) {
return gs.add_frame(unsafe_piece_hook.id, FeatureFrame{s, SQUARE_SENTINEL, ss.min_w, ss.min_b});
}
return true;
}
Question
- Is there actually an error here?
- Why does Valgrind behave like this?
I appreciate there might not be enough information to answer (1) - any suggestions on how to continue debugging also appreciated (this is the only error reported; I've check the initialisation the error refers to several times and the project also compiles cleanly with -Wall -Wextra).
Edit: using g++ 9.4.0 on Ubuntu.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
