From a69a67301e3addeee96166bdc477d904e38553cf Mon Sep 17 00:00:00 2001 From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Date: Tue, 13 Dec 2022 16:46:30 +0000 Subject: [PATCH] Adds BYOND-Tracy as part of the repo (#19839) * [DNM] Adds BYOND-Tracy as part of the repo * And its ready * Update code/_compile_options.dm --- code/__DEFINES/_init.dm | 5 + code/_compile_options.dm | 5 + code/game/world.dm | 3 + prof.dll | Bin 0 -> 116736 bytes tools/tracy_replay/README.MD | 7 + tools/tracy_replay/replay.py | 432 +++++++++++++++++++++++++++++++++++ 6 files changed, 452 insertions(+) create mode 100644 prof.dll create mode 100644 tools/tracy_replay/README.MD create mode 100644 tools/tracy_replay/replay.py diff --git a/code/__DEFINES/_init.dm b/code/__DEFINES/_init.dm index e7deaa481f9..5346b087c0d 100644 --- a/code/__DEFINES/_init.dm +++ b/code/__DEFINES/_init.dm @@ -4,6 +4,11 @@ // This exists so that world.Profile() is THE FIRST PROC TO RUN in the init sequence. // This allows us to get the real details of everything lagging at server start. world.Profile(PROFILE_START) + #if defined(ENABLE_BYOND_TRACY) && (DM_BUILD == 1589) + var/tracy_init = CALL_EXT("prof.dll", "init")() // Setup Tracy integration + if(tracy_init != "0") + CRASH("Tracy init error: [tracy_init]") + #endif // After that, the debugger is initialized. // Doing it this early makes it possible to set breakpoints in the New() // of things assigned to global variables or objects included in a compiled map file. diff --git a/code/_compile_options.dm b/code/_compile_options.dm index d418f30c78d..6a14468ac8f 100644 --- a/code/_compile_options.dm +++ b/code/_compile_options.dm @@ -4,6 +4,11 @@ // Uncomment the following line to compile unit tests. // #define UNIT_TESTS +// Uncomment the following line to enable Tracy profiling. +// DO NOT DO THIS UNLESS YOU UNDERSTAND THE IMPLICATIONS +// Your data directory will grow by about a gigabyte every time you launch the server, as well as introducing potential instabilities over multiple BYOND versions. +// #define ENABLE_BYOND_TRACY + #ifdef CIBUILDING #define UNIT_TESTS diff --git a/code/game/world.dm b/code/game/world.dm index 59f53b8c02c..cbeb8144f55 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -299,4 +299,7 @@ GLOBAL_LIST_EMPTY(world_topic_handlers) rustg_close_async_http_client() // Close the HTTP client. If you dont do this, youll get phantom threads which can crash DD from memory access violations disable_auxtools_debugger() // Disables the debugger if running. See above comment rustg_redis_disconnect() // Disconnects the redis connection. See above. + #ifdef ENABLE_BYOND_TRACY + CALL_EXT("prof.dll", "destroy")() // Setup Tracy integration + #endif ..() diff --git a/prof.dll b/prof.dll new file mode 100644 index 0000000000000000000000000000000000000000..33a6da229474e94358ecd852cc6ad3dc380306a3 GIT binary patch literal 116736 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

O@lXf}RJ|5Qt?=O{gg~t!CAnT2M=B8TnCG z>uN*Q>N?$^8+8+yfTG%IRJsjS?nH%qbwB)YNRNPCC-jt_M#bk)?Il!t1yx>0g=~zM!@>6!&&e}P~jiHv9!?IJ6>L=T)eCkDl^7!~7UQsl)9Sae=2iXw=9Rji2$*e@pQWgI)Zq$Kd{ zl+4Ih*)Fr#;q}Nq5cD9Za8!=VNtu^3Apd!}D2uWrSFr=ANJqsK{=hzXF{y~+Dy1?Y z#&)nzm+Db{Du+GHuo}eKtQ1t$3Poj27o4UKS{j6o zMxmie=w}AnnTKwQ(9A0IQh`=t&`I1TY|;|TZ3;V%R&Z$+WZGl zY{AZB-&wRJyNcwhAZKFW)_9bNk`ak`l!`Lo$@VB4bwxcY8jmKUJczb{ z_wN?Lw54b@T8k=pcWvujwL@a0p2SIlB#AR#48GB of RAM for this process. I am not joking. + +The version of `replay.py` in this folder is compatible with the protocol of `Tracy 0.8.2`. Newer versions will not work. It requires the `lz4` python module with the streams extension. This requires manually downloading, building and installing the `python-lz4/python-lz4` repo and building with `PYLZ4_EXPERIMENTAL=TRUE` as an environment variable. diff --git a/tools/tracy_replay/replay.py b/tools/tracy_replay/replay.py new file mode 100644 index 00000000000..a55d0993dd5 --- /dev/null +++ b/tools/tracy_replay/replay.py @@ -0,0 +1,432 @@ +import argparse +import ctypes +import socket +import selectors +import lz4.stream + +# file protocol +FileSignature = 0x6D64796361727475 +FileVersion = 2 +FileEventZoneBegin =15 +FileEventZoneEnd = 17 +FileEventZoneColor = 62 +FileEventFrameMark = 64 + +class FileHeader(ctypes.Structure): + _fields_ = ( + ("signature", ctypes.c_ulonglong), + ("version", ctypes.c_uint), + ("multiplier", ctypes.c_double), + ("init_begin", ctypes.c_longlong), + ("init_end", ctypes.c_longlong), + ("delay", ctypes.c_longlong), + ("resolution", ctypes.c_longlong), + ("epoch", ctypes.c_longlong), + ("exec_time", ctypes.c_longlong), + ("pid", ctypes.c_longlong), + ("sampling_period", ctypes.c_longlong), + ("flags", ctypes.c_byte), + ("cpu_arch", ctypes.c_byte), + ("cpu_manufacturer", ctypes.c_char * 12), + ("cpu_id", ctypes.c_uint), + ("program_name", ctypes.c_char * 64), + ("host_info", ctypes.c_char * 1024) + ) + +class FileZoneBegin(ctypes.Structure): + _fields_ = ( + ("tid", ctypes.c_uint32), + ("srcloc", ctypes.c_uint32), + ("timestamp", ctypes.c_int64) + ) + +class FileZoneEnd(ctypes.Structure): + _fields_ = ( + ("tid", ctypes.c_uint32), + ("timestamp", ctypes.c_int64) + ) + +class FileZoneColor(ctypes.Structure): + _fields_ = ( + ("tid", ctypes.c_uint32), + ("color", ctypes.c_uint32) + ) + +class FileFrameMark(ctypes.Structure): + _fields_ = ( + ("name", ctypes.c_uint32), + ("timestamp", ctypes.c_int64) + ) + +class FileEvent(ctypes.Structure): + class Events(ctypes.Union): + _fields_ = ( + ("zone_begin", FileZoneBegin), + ("zone_end", FileZoneEnd), + ("zone_color", FileZoneColor), + ("frame_mark", FileFrameMark), + ) + + _anonymous_ = ("event",) + _fields_ = ( + ("type", ctypes.c_byte), + ("event", Events) + ) + +# network protocol +NetworkMaxFrameSize = 256 * 1024 +NetworkHandshakeWelcome = b"\x01" +NetworkHandshakeProtocolMismatch = b"\x02" +NetworkEventZoneBegin = 15 +NetworkEventZoneEnd = 17 +NetworkEventTerminate = 55 +NetworkEventThreadContext = 57 +NetworkEventZoneColor = 62 +NetworkEventFrameMark = 64 +NetworkEventSrcloc = 67 +NetworkResponseServerQueryNoop = 87 +NetworkResponseSourceCodeNotAvailable = 88 +NetworkResponseSymbolCodeNotAvailable = 89 +NetworkResponseStringData = 94 +NetworkResponseThreadName = 95 +NetworkQueryTerminate = 0 +NetworkQueryString = 1 +NetworkQueryThreadString = 2 +NetworkQuerySrcloc = 3 +NetworkQueryPlotName = 4 +NetworkQueryFrameName = 5 +NetworkQueryParameter = 6 +NetworkQueryFiberName = 7 +NetworkQueryDisconnect = 8 +NetworkQueryCallstackFrame = 9 +NetworkQueryExternalName = 10 +NetworkQuerySymbol = 11 +NetworkQuerySymbolCode = 12 +NetworkQueryCodeLocation = 13 +NetworkQuerySourceCode = 14 +NetworkQueryDataTransfer = 15 +NetworkQueryDataTransferPart = 16 + + +class NetworkHeader(ctypes.Structure): + _pack_ = 1 + _fields_ = ( + ("multiplier", ctypes.c_double), + ("init_begin", ctypes.c_longlong), + ("init_end", ctypes.c_longlong), + ("delay", ctypes.c_longlong), + ("resolution", ctypes.c_longlong), + ("epoch", ctypes.c_longlong), + ("exec_time", ctypes.c_longlong), + ("pid", ctypes.c_longlong), + ("sampling_period", ctypes.c_longlong), + ("flags", ctypes.c_uint8), + ("cpu_arch", ctypes.c_uint8), + ("cpu_manufacturer", ctypes.c_char * 12), + ("cpu_id", ctypes.c_uint), + ("program_name", ctypes.c_char * 64), + ("host_info", ctypes.c_char * 1024) + ) + +class NetworkThreadContext(ctypes.Structure): + _pack_ = 1 + _fields_ = ( + ("type", ctypes.c_uint8), + ("tid", ctypes.c_uint32) + ) + +class NetworkZoneBegin(ctypes.Structure): + _pack_ = 1 + _fields_ = ( + ("type", ctypes.c_uint8), + ("timestamp", ctypes.c_int64), + ("srcloc", ctypes.c_uint64) + ) + +class NetworkZoneEnd(ctypes.Structure): + _pack_ = 1 + _fields_ = ( + ("type", ctypes.c_uint8), + ("timestamp", ctypes.c_int64) + ) + +class NetworkZoneColor(ctypes.Structure): + _pack_ = 1 + _fields_ = ( + ("type", ctypes.c_uint8), + ("r", ctypes.c_uint8), + ("g", ctypes.c_uint8), + ("b", ctypes.c_uint8) + ) + +class NetworkFrameMark(ctypes.Structure): + _pack_ = 1 + _fields_ = ( + ("type", ctypes.c_uint8), + ("timestamp", ctypes.c_int64), + ("name", ctypes.c_uint64) + ) + +class NetworkSrcloc(ctypes.Structure): + _pack_ = 1 + _fields_ = ( + ("type", ctypes.c_uint8), + ("name", ctypes.c_int64), + ("function", ctypes.c_int64), + ("file", ctypes.c_int64), + ("line", ctypes.c_uint32), + ("r", ctypes.c_uint8), + ("g", ctypes.c_uint8), + ("b", ctypes.c_uint8) + ) + +class NetworkRequest(ctypes.Structure): + _pack_ = 1 + _fields_ = ( + ("type", ctypes.c_uint8), + ("ptr", ctypes.c_int64), + ("extra", ctypes.c_uint32) + ) + +def main(stream): + def file_read_uint(): + ctype = ctypes.c_uint() + stream.readinto(ctype) + return ctype.value + + def file_read_chars(size): + if 0 == size: + return None + ctype = (ctypes.c_char * size)() + stream.readinto(ctype) + return ctype.value + + header = FileHeader() + stream.readinto(header) + if header.signature != FileSignature: + print("incorrect signature") + return + + if header.version != FileVersion: + print("incorrect version") + return + + srclocs_len = file_read_uint() + strings = {} + srclocs = [None] * srclocs_len + + for i in range(srclocs_len): + name_len = file_read_uint() + name = file_read_chars(name_len) + function_len = file_read_uint() + function = file_read_chars(function_len) + file_len = file_read_uint() + file = file_read_chars(file_len) + line = file_read_uint() + color = file_read_uint() + + if name != None: + digest = hash(name) + strings[digest] = name + name = digest + else: + name = 0 + + if function != None: + digest = hash(function) + strings[digest] = function + function = digest + else: + function = 0 + + if file != None: + digest = hash(file) + strings[digest] = file + file = digest + else: + file = 0 + + srclocs[i] = (name, function, file, line, color) + + server = socket.create_server(("127.0.0.1", 8086)) + server.listen(1) + print("listening on 127.0.0.1:8086...") + client, addr = server.accept() + + if client.recv(8) != b"TracyPrf": + print("bad client") + client.close() + return + + protocol = ctypes.c_uint() + client.recv_into(protocol) + + if protocol.value not in (56, 57): + print("bad protocol") + client.sendall(NetworkHandshakeProtocolMismatch) + client.close() + return + + print(f"client accepted from {addr}") + client.sendall(NetworkHandshakeWelcome) + + client.sendall(NetworkHeader( + multiplier = header.multiplier, + init_begin = header.init_begin, + init_end = header.init_end, + delay = header.delay, + resolution = header.resolution, + epoch = header.epoch, + exec_time = header.exec_time, + pid = header.pid, + sampling_period = header.sampling_period, + flags = header.flags, + cpu_arch = header.cpu_arch, + cpu_manufacturer = header.cpu_manufacturer, + cpu_id = header.cpu_id, + program_name = header.program_name, + host_info = header.host_info + )) + + event = FileEvent() + event_sz = ctypes.sizeof(event) + timestamp = 0 + tid = None + buffer = bytearray(NetworkMaxFrameSize // event_sz) + offset = 0 + compressor = lz4.stream.LZ4StreamCompressor( + "double_buffer", + NetworkMaxFrameSize, + store_comp_size = 4 + ) + + def commit(): + nonlocal offset + if offset > 0: + block = compressor.compress(buffer[:offset]) + client.sendall(block) + offset = 0 + + def write_msg(msg): + nonlocal offset, buffer + sz = ctypes.sizeof(msg) + if offset + sz > len(buffer): + commit() + + buffer[offset : offset + sz] = msg + offset += sz + + def thread_context(event): + nonlocal tid, timestamp + if event.zone_begin.tid != tid: + tid = event.zone_begin.tid + timestamp = 0 + write_msg(NetworkThreadContext( + type = NetworkEventThreadContext, + tid = tid + )) + + while event_sz == stream.readinto(event): + if event.type == FileEventZoneBegin: + thread_context(event) + write_msg(NetworkZoneBegin( + type = NetworkEventZoneBegin, + timestamp = event.zone_begin.timestamp - timestamp, + srcloc = event.zone_begin.srcloc + )) + timestamp = event.zone_begin.timestamp + + elif event.type == FileEventZoneEnd: + thread_context(event) + write_msg(NetworkZoneEnd( + type = NetworkEventZoneEnd, + timestamp = event.zone_end.timestamp - timestamp + )) + timestamp = event.zone_end.timestamp + + elif event.type == FileEventZoneColor: + thread_context(event) + write_msg(NetworkZoneColor( + type = NetworkEventZoneColor, + r = (event.zone_color.color >> 0x00) & 0xFF, + g = (event.zone_color.color >> 0x08) & 0xFF, + b = (event.zone_color.color >> 0x10) & 0xFF + )) + + elif event.type == FileEventFrameMark: + write_msg(NetworkFrameMark( + type = NetworkEventFrameMark, + name = 0, + timestamp = event.frame_mark.timestamp + )) + + commit() + + def respond_string(string, ptr, type): + string_sz = len(string) + + class NetworkStringData(ctypes.Structure): + _pack_ = 1 + _fields_ = ( + ("type", ctypes.c_uint8), + ("ptr", ctypes.c_uint64), + ("len", ctypes.c_uint16), + ("str", ctypes.c_char * string_sz) + ) + + write_msg(NetworkStringData( + type = type, + ptr = req.ptr, + len = string_sz, + str = string + )) + + req = NetworkRequest() + client.settimeout(1) + + try: + while ctypes.sizeof(req) == client.recv_into(req): + if req.type == NetworkQuerySrcloc: + srcloc = srclocs[req.ptr] + write_msg(NetworkSrcloc( + type = NetworkEventSrcloc, + name = srcloc[0], + function = srcloc[1], + file = srcloc[2], + line = srcloc[3], + r = (srcloc[4] >> 0x00) & 0xFF, + g = (srcloc[4] >> 0x08) & 0xFF, + b = (srcloc[4] >> 0x10) & 0xFF + )) + + elif req.type == NetworkQueryString: + respond_string(strings[req.ptr], req.ptr, NetworkResponseStringData) + + elif req.type == NetworkQuerySymbolCode: + write_msg(ctypes.c_uint8(NetworkResponseSymbolCodeNotAvailable)) + + elif req.type == NetworkQuerySourceCode: + write_msg(ctypes.c_uint8(NetworkResponseSourceCodeNotAvailable)) + + elif req.type == NetworkQueryDataTransfer: + write_msg(ctypes.c_uint8(NetworkResponseServerQueryNoop)) + + elif req.type == NetworkQueryDataTransferPart: + write_msg(ctypes.c_uint8(NetworkResponseServerQueryNoop)) + + elif req.type == NetworkQueryThreadString: + respond_string(b"main", req.ptr, NetworkResponseThreadName) + + else: + print("unknown req:", req.type) + + commit() + + except socket.timeout: + pass + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("file", type=argparse.FileType("rb")) + args = parser.parse_args() + main(args.file)