mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-04 21:00:17 -06:00
Trace: add global_frame field to json-v1 format
Tools using the json-v1 format might want to trace stack frames across different `CMakeLists.txt` files, in order to, for example, provide stacktraces that span from the top-level `CMakeLists.txt` in a project. One would think that `frame` lets you do that, but it doesn't, because it tells you the depth of the stack within the current `CMakeLists.txt`, so it gets reset across calls to `add_subdirectory`. The solution involves adding a field with a "global frame". This value gets incremented on calls to `add_subdirectory`, which makes it easier for tools to reconstruct "global stacktraces". I considered changing the current "frame" value, but I didn't because it would be a breaking change. I cannot think of any use-case where "frame" is more useful to "global-frame", but maybe I'm missing something.
This commit is contained in:
@@ -298,7 +298,8 @@ Options
|
||||
"cmd": "add_executable",
|
||||
"args": ["foo", "bar"],
|
||||
"time": 1579512535.9687231,
|
||||
"frame": 2
|
||||
"frame": 2,
|
||||
"global_frame": 4
|
||||
}
|
||||
|
||||
The members are:
|
||||
@@ -325,7 +326,13 @@ Options
|
||||
Timestamp (seconds since epoch) of the function call.
|
||||
|
||||
``frame``
|
||||
Stack frame depth of the function that was called.
|
||||
Stack frame depth of the function that was called, within the
|
||||
context of the ``CMakeLists.txt`` being processed currently.
|
||||
|
||||
``global_frame``
|
||||
Stack frame depth of the function that was called, tracked globally
|
||||
across all ``CMakeLists.txt`` files involved in the trace. This field
|
||||
was added in minor version 2 of the ``json-v1`` format.
|
||||
|
||||
Additionally, the first JSON document outputted contains the
|
||||
``version`` key for the current major and minor version of the
|
||||
@@ -337,7 +344,7 @@ Options
|
||||
{
|
||||
"version": {
|
||||
"major": 1,
|
||||
"minor": 1
|
||||
"minor": 2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
Help/release/dev/trace-global-frame.rst
Normal file
8
Help/release/dev/trace-global-frame.rst
Normal file
@@ -0,0 +1,8 @@
|
||||
trace-global-frame
|
||||
------------------
|
||||
|
||||
* Add the field ``global_frame`` to the json-v1 trace format. This
|
||||
frame tracks the depth of the call stack globally across all
|
||||
``CMakeLists.txt`` files involved in the trace, and will let tools
|
||||
reconstruct stack traces that span from the top-level ``CMakeLists.txt``
|
||||
file of the project.
|
||||
@@ -302,6 +302,8 @@ void cmMakefile::PrintCommandTrace(
|
||||
val["time"] = cmSystemTools::GetTime();
|
||||
val["frame"] =
|
||||
static_cast<Json::Value::UInt64>(this->ExecutionStatusStack.size());
|
||||
val["global_frame"] =
|
||||
static_cast<Json::Value::UInt64>(this->RecursionDepth);
|
||||
msg << Json::writeString(builder, val);
|
||||
#endif
|
||||
break;
|
||||
|
||||
@@ -1434,7 +1434,7 @@ void cmake::PrintTraceFormatVersion()
|
||||
Json::StreamWriterBuilder builder;
|
||||
builder["indentation"] = "";
|
||||
version["major"] = 1;
|
||||
version["minor"] = 1;
|
||||
version["minor"] = 2;
|
||||
val["version"] = version;
|
||||
msg = Json::writeString(builder, val);
|
||||
#endif
|
||||
|
||||
@@ -46,8 +46,15 @@ required_traces = [
|
||||
{
|
||||
'args': msg_args,
|
||||
'cmd': 'message',
|
||||
'frame': 3 if expand else 2
|
||||
'frame': 3 if expand else 2,
|
||||
'global_frame': 3 if expand else 2
|
||||
},
|
||||
{
|
||||
'args': ['STATUS', 'nested global_frame'],
|
||||
'cmd': 'message',
|
||||
'frame': 3,
|
||||
'global_frame': 6 if expand else 5
|
||||
}
|
||||
]
|
||||
|
||||
with open(trace_file, 'r') as fp:
|
||||
@@ -56,15 +63,16 @@ with open(trace_file, 'r') as fp:
|
||||
assert sorted(vers.keys()) == ['version']
|
||||
assert sorted(vers['version'].keys()) == ['major', 'minor']
|
||||
assert vers['version']['major'] == 1
|
||||
assert vers['version']['minor'] == 1
|
||||
assert vers['version']['minor'] == 2
|
||||
|
||||
for i in fp.readlines():
|
||||
line = json.loads(i)
|
||||
assert sorted(line.keys()) == ['args', 'cmd', 'file', 'frame', 'line', 'time']
|
||||
assert sorted(line.keys()) == ['args', 'cmd', 'file', 'frame', 'global_frame','line', 'time']
|
||||
assert isinstance(line['args'], list)
|
||||
assert isinstance(line['cmd'], unicode)
|
||||
assert isinstance(line['file'], unicode)
|
||||
assert isinstance(line['frame'], int)
|
||||
assert isinstance(line['global_frame'], int)
|
||||
assert isinstance(line['line'], int)
|
||||
assert isinstance(line['time'], float)
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
function(f)
|
||||
message(STATUS "nested global_frame")
|
||||
endfunction()
|
||||
|
||||
function(g)
|
||||
f()
|
||||
endfunction()
|
||||
|
||||
g()
|
||||
@@ -3,3 +3,4 @@ set(ASDF fff sss " SPACES !!! ")
|
||||
set(FOO 42)
|
||||
set(BAR " space in string!")
|
||||
message(STATUS fff ${ASDF} " ${FOO} ${BAR}" " SPACES !!! ")
|
||||
add_subdirectory(trace-json-v1-nested)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{"args":\["DEFER","CALL","message","Deferred Message"\],"cmd":"cmake_language","file":"[^"]*/Tests/RunCMake/cmake_language/defer_call_trace_json.cmake","frame":2,"line":2,"time":[0-9.]+}
|
||||
{"args":\["Immediate Message"\],"cmd":"message","file":"[^"]*/Tests/RunCMake/cmake_language/defer_call_trace_json.cmake","frame":2,"line":3,"time":[0-9.]+}
|
||||
{"args":\["DEFER","CALL","message","Deferred Message"\],"cmd":"cmake_language","file":"[^"]*/Tests/RunCMake/cmake_language/defer_call_trace_json.cmake","frame":2,"global_frame":2,"line":2,"time":[0-9.]+}
|
||||
{"args":\["Immediate Message"\],"cmd":"message","file":"[^"]*/Tests/RunCMake/cmake_language/defer_call_trace_json.cmake","frame":2,"global_frame":2,"line":3,"time":[0-9.]+}
|
||||
Immediate Message
|
||||
{"args":\["Deferred Message"],"cmd":"message","defer":"__0","file":"[^"]*/Tests/RunCMake/cmake_language/defer_call_trace_json.cmake","frame":1,"line":2,"time":[0-9.]+}
|
||||
{"args":\["Deferred Message"],"cmd":"message","defer":"__0","file":"[^"]*/Tests/RunCMake/cmake_language/defer_call_trace_json.cmake","frame":1,"global_frame":1,"line":2,"time":[0-9.]+}
|
||||
Deferred Message$
|
||||
|
||||
Reference in New Issue
Block a user