[NFC][Stack Traces] Do not build a functor where we can use the translation map directly
PiperOrigin-RevId: 356403200 Change-Id: I6ae0231a08bcc24b103f3fa8f95233aa2116a952
This commit is contained in:
parent
2c596172d2
commit
969371e28f
tensorflow
@ -482,6 +482,7 @@ cc_library(
|
|||||||
],
|
],
|
||||||
deps = [
|
deps = [
|
||||||
"//tensorflow/core/platform:stack_frame",
|
"//tensorflow/core/platform:stack_frame",
|
||||||
|
"@com_google_absl//absl/container:flat_hash_map",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
"@com_google_absl//absl/types:optional",
|
"@com_google_absl//absl/types:optional",
|
||||||
],
|
],
|
||||||
|
@ -19,20 +19,22 @@ limitations under the License.
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "absl/container/flat_hash_map.h"
|
||||||
#include "absl/strings/match.h"
|
#include "absl/strings/match.h"
|
||||||
#include "absl/types/optional.h"
|
#include "absl/types/optional.h"
|
||||||
#include "tensorflow/core/platform/stack_frame.h"
|
#include "tensorflow/core/platform/stack_frame.h"
|
||||||
|
|
||||||
namespace tensorflow {
|
namespace tensorflow {
|
||||||
|
|
||||||
|
using SourceLoc = std::tuple<std::string, int>;
|
||||||
|
|
||||||
// Maps filename/line_no combination into a stack frame.
|
// Maps filename/line_no combination into a stack frame.
|
||||||
using StackTraceMap =
|
using SourceMap = absl::flat_hash_map<SourceLoc, StackFrame>;
|
||||||
std::function<absl::optional<StackFrame>(std::pair<const char*, int>)>;
|
|
||||||
|
|
||||||
// Returns "true" on filenames which should be skipped.
|
// Returns "true" on filenames which should be skipped.
|
||||||
using StackTraceFilter = std::function<bool(const char*)>;
|
using StackTraceFilter = std::function<bool(const char*)>;
|
||||||
|
|
||||||
using ToStackFramesFunctor = std::vector<StackFrame>(int, const StackTraceMap&,
|
using ToStackFramesFunctor = std::vector<StackFrame>(int, const SourceMap&,
|
||||||
const StackTraceFilter&,
|
const StackTraceFilter&,
|
||||||
bool, int);
|
bool, int);
|
||||||
|
|
||||||
@ -54,11 +56,12 @@ class ManagedStackTrace {
|
|||||||
: id_(id), to_stack_frames_(to_stack_frames) {}
|
: id_(id), to_stack_frames_(to_stack_frames) {}
|
||||||
|
|
||||||
// Returns stack trace as a vector of `StackFrame`s.
|
// Returns stack trace as a vector of `StackFrame`s.
|
||||||
std::vector<StackFrame> ToStackFrames(const StackTraceMap& mapper = {},
|
std::vector<StackFrame> ToStackFrames(const SourceMap& source_map = {},
|
||||||
const StackTraceFilter& filtered = {},
|
const StackTraceFilter& filtered = {},
|
||||||
bool reverse_traversal = false,
|
bool reverse_traversal = false,
|
||||||
int limit = -1) const {
|
int limit = -1) const {
|
||||||
return to_stack_frames_(id_, mapper, filtered, reverse_traversal, limit);
|
return to_stack_frames_(id_, source_map, filtered, reverse_traversal,
|
||||||
|
limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -42,7 +42,7 @@ const char* GetPythonString(PyObject* o) {
|
|||||||
namespace tensorflow {
|
namespace tensorflow {
|
||||||
|
|
||||||
std::vector<StackFrame> StackTrace::ToStackFrames(
|
std::vector<StackFrame> StackTrace::ToStackFrames(
|
||||||
const StackTraceMap& mapper, const StackTraceFilter& filtered,
|
const SourceMap& source_map, const StackTraceFilter& filtered,
|
||||||
bool reverse_traversal, int limit) const {
|
bool reverse_traversal, int limit) const {
|
||||||
DCheckPyGilStateForStackTrace();
|
DCheckPyGilStateForStackTrace();
|
||||||
std::vector<StackFrame> result;
|
std::vector<StackFrame> result;
|
||||||
@ -61,11 +61,9 @@ std::vector<StackFrame> StackTrace::ToStackFrames(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::optional<StackFrame> mapped =
|
const auto it = source_map.find(std::make_tuple(file_name, line_number));
|
||||||
mapper ? mapper(std::make_pair(file_name, line_number)) : absl::nullopt;
|
if (it != source_map.end()) {
|
||||||
|
result.push_back(it->second);
|
||||||
if (mapped) {
|
|
||||||
result.push_back(*mapped);
|
|
||||||
} else {
|
} else {
|
||||||
result.emplace_back(StackFrame{file_name, line_number,
|
result.emplace_back(StackFrame{file_name, line_number,
|
||||||
GetPythonString(code_obj.first->co_name)});
|
GetPythonString(code_obj.first->co_name)});
|
||||||
|
@ -88,12 +88,12 @@ class StackTrace final {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns a structured representation of the captured stack trace.
|
// Returns a structured representation of the captured stack trace.
|
||||||
// `mapper` provides a custom mapping for translating stack frames, `filter`
|
// `source_map` provides a custom mapping for translating stack frames,
|
||||||
// returns `true` for the stack frames which should be omitted.
|
// `filter` returns `true` for the stack frames which should be omitted.
|
||||||
//
|
//
|
||||||
// `reverse_traversal` changes the traversal order of the stack trace, and
|
// `reverse_traversal` changes the traversal order of the stack trace, and
|
||||||
// `limit` bounds the number of returned frames (after filtering).
|
// `limit` bounds the number of returned frames (after filtering).
|
||||||
std::vector<StackFrame> ToStackFrames(const StackTraceMap& mapper = {},
|
std::vector<StackFrame> ToStackFrames(const SourceMap& source_map = {},
|
||||||
const StackTraceFilter& filtered = {},
|
const StackTraceFilter& filtered = {},
|
||||||
bool reverse_traversal = false,
|
bool reverse_traversal = false,
|
||||||
int limit = -1) const;
|
int limit = -1) const;
|
||||||
@ -149,11 +149,11 @@ extern StackTraceManager* const stack_trace_manager;
|
|||||||
// Converts the ManagedStackTrace (identified by ID) to a vector of stack
|
// Converts the ManagedStackTrace (identified by ID) to a vector of stack
|
||||||
// frames.
|
// frames.
|
||||||
inline std::vector<StackFrame> ManagedStackTraceToStackFrames(
|
inline std::vector<StackFrame> ManagedStackTraceToStackFrames(
|
||||||
int id, const StackTraceMap& mapper, const StackTraceFilter& filtered,
|
int id, const SourceMap& source_map, const StackTraceFilter& filtered,
|
||||||
bool reverse_traversal, int limit) {
|
bool reverse_traversal, int limit) {
|
||||||
PyGILState_STATE gstate = PyGILState_Ensure();
|
PyGILState_STATE gstate = PyGILState_Ensure();
|
||||||
std::vector<StackFrame> result = stack_trace_manager->Get(id)->ToStackFrames(
|
std::vector<StackFrame> result = stack_trace_manager->Get(id)->ToStackFrames(
|
||||||
mapper, filtered, reverse_traversal, limit);
|
source_map, filtered, reverse_traversal, limit);
|
||||||
PyGILState_Release(gstate);
|
PyGILState_Release(gstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,6 @@ namespace {
|
|||||||
|
|
||||||
namespace py = pybind11;
|
namespace py = pybind11;
|
||||||
|
|
||||||
using SourceLoc = std::tuple<std::string, int>;
|
|
||||||
|
|
||||||
using SourceMap = absl::flat_hash_map<SourceLoc, StackFrame>;
|
|
||||||
|
|
||||||
using StringSet = absl::flat_hash_set<std::string>;
|
using StringSet = absl::flat_hash_set<std::string>;
|
||||||
|
|
||||||
// Python wrapper for a SourceMap.
|
// Python wrapper for a SourceMap.
|
||||||
@ -149,8 +145,7 @@ class StackTraceWrapper : public AbstractStackTrace {
|
|||||||
PyGILState_STATE state = PyGILState_Ensure();
|
PyGILState_STATE state = PyGILState_Ensure();
|
||||||
|
|
||||||
stack_frames_cache_ = captured_.ToStackFrames(
|
stack_frames_cache_ = captured_.ToStackFrames(
|
||||||
[&](std::pair<const char*, int> p) { return StackTraceMapping(p); },
|
*source_map_, [&](const char* f) { return StackTraceFiltering(f); });
|
||||||
[&](const char* f) { return StackTraceFiltering(f); });
|
|
||||||
stack_frames_cache_->pop_back(); // Drop last stack frame.
|
stack_frames_cache_->pop_back(); // Drop last stack frame.
|
||||||
PyGILState_Release(state);
|
PyGILState_Release(state);
|
||||||
return *stack_frames_cache_;
|
return *stack_frames_cache_;
|
||||||
@ -163,7 +158,7 @@ class StackTraceWrapper : public AbstractStackTrace {
|
|||||||
|
|
||||||
PyGILState_STATE state = PyGILState_Ensure();
|
PyGILState_STATE state = PyGILState_Ensure();
|
||||||
std::vector<StackFrame> last_frame = captured_.ToStackFrames(
|
std::vector<StackFrame> last_frame = captured_.ToStackFrames(
|
||||||
[&](std::pair<const char*, int> p) { return StackTraceMapping(p); },
|
*source_map_,
|
||||||
[&](const char* file_name) {
|
[&](const char* file_name) {
|
||||||
return StackTraceFiltering(file_name) ||
|
return StackTraceFiltering(file_name) ||
|
||||||
IsInternalFrameForFilename(file_name);
|
IsInternalFrameForFilename(file_name);
|
||||||
@ -226,14 +221,6 @@ class StackTraceWrapper : public AbstractStackTrace {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::optional<StackFrame> StackTraceMapping(SourceLoc loc) const {
|
|
||||||
if (source_map_->contains(loc)) {
|
|
||||||
return source_map_->at(loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return absl::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StackTraceFiltering(const char* file_name) const {
|
bool StackTraceFiltering(const char* file_name) const {
|
||||||
return filter_->contains(file_name);
|
return filter_->contains(file_name);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user