Fixes overwrite of last captured managed stack frame address in EventPipe stack trace...
authorJohan Lorensson <lateralusx.github@gmail.com>
Fri, 22 Jul 2022 07:44:45 +0000 (09:44 +0200)
committerGitHub <noreply@github.com>
Fri, 22 Jul 2022 07:44:45 +0000 (09:44 +0200)
commit0c32267664e1b9913f2329827d998646fecafd91
tree64ec006ca223db616ba0998f533d0d388412eded
parentd5d9d52fd8a89cce23453de81414e1cb26cb4cc8
Fixes overwrite of last captured managed stack frame address in EventPipe stack trace. (#72362)

When collecting stack frames in EventPipe, buffer manager buffer layout
depends on the struct layout of the compiler up until data gets
serialized into blocks and put into output stream following nettrace
format.

In the past, there was a 1:1 map between the data collected for a stack
trace and what was copied into buffer manager memory. Due to inefficiency,
wasting a lot of memory when having small stack traces, this was
optimized by https://github.com/dotnet/runtime/pull/68134, greatly
reducing overhead and improved EventPipe throughput.

That change started to use a different struct when capturing the
callstack compared to the layout written into buffer manager.
Since buffer manager memory still relies on compiler struct layout,
code must take that into account when copying stack data into
buffer manager memory, but the new optimized implementation didn't,
meaning that it fails in cases where compiler adds padding inside
EventPipeStackContentsInstance (done on 64-bit bit systems).
That in turn will write event payload, starting 4 bytes into last
captured stack frame causing issues for tools to symbolicate address,
but payload data will still be correct, since EventPipeEventInstance
keeps pointer to payload data, meaning most of the event will still be
correct, covering up the overwrite to only affect last managed stack
frame and only on 64-bit release builds.

Fix adjust the size calculation and make sure it takes any padding
added by compiler into the computation of EventPipeEventInstance size.
src/native/eventpipe/ep-buffer.c
src/native/eventpipe/ep-event-instance.h
src/native/eventpipe/ep-stack-contents.h