Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for emitting ETW events to LTTng #4314

Merged
merged 3 commits into from
Dec 7, 2017

Conversation

MSLaguana
Copy link
Contributor

We define a number of ETW events on windows that we can emit for diagnostics purposes. With these changes, we support generating LTTng bindings for these same events so the same diagnostics approach can be used on linux and osx.

The script that generates the LTTng bindings from the ETW manifest is based on a similar script used by the dotnet team (see https://github.com/dotnet/coreclr/blob/master/src/scripts/genXplatLttng.py), but I have attempted to simplify it and adapt it for our purposes.

)

if(USE_LTTNG)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lttng is not for osx ++ we better share target_link_libs below.. So, move this under else() for linux below and define ${LTTNG....} and use it under the same target_link_libraries

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having multiple target_link_libraries is fine and additive so that shouldn't cause issues. Since lttng is opt-in, I was thinking that on mac people would just not specify the --lttng flag (or if they did and it broke, they would see that lttng wasn't supported on their system). Do you feel strongly about this?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be nice to combine them in the same place in order to prevent future what is happening here confusions.

@@ -65,3 +66,4 @@ void EtwTraceCore::UnRegister()
}

#endif
#endif
Copy link
Collaborator

@obastemur obastemur Nov 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could be nice to add // ENABLE_JS_LTTNG at the end of #endif

@@ -5968,7 +5968,7 @@ Recycler::ThreadProc()
}
#endif

#ifdef ENABLE_JS_ETW
#if defined(ENABLE_JS_ETW) && ! defined(ENABLE_JS_LTTNG)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because LTTng doesn't have any concept of EventActivityIdControl

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps call that out as the reason why, here?

@@ -6536,7 +6536,7 @@ RecyclerParallelThread::StaticThreadProc(LPVOID lpParameter)
dllHandle = NULL;
}
#endif
#ifdef ENABLE_JS_ETW
#if defined(ENABLE_JS_ETW) && ! defined(ENABLE_JS_LTTNG)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

@@ -143,7 +143,7 @@ void JsrtCallbackState::ObjectBeforeCallectCallbackWrapper(JsObjectBeforeCollect
ConfigParser::ParseOnModuleLoad(parser, mod);
}

#ifdef ENABLE_JS_ETW
#if defined(ENABLE_JS_ETW) && !defined(ENABLE_JS_LTTNG)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LTTng doesn't have the same register/unregister hooks that ETW has, so this is irrelevant for LTTng, and I thought it was simpler to just remove/avoid the whole registration concept.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might implement dummy functions instead?

Why -> Adding an additional platform comes with an additional set of dependencies / call requirements. It could be nice to have a common interface (even if it's a dummy function)

@@ -47,14 +48,17 @@ void EtwCallbackApi::OnSessionChange(ULONG controlCode, PVOID callbackContext)
}
}
}
#endif
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could be nice to add // ENABLE_JS_LTTNG at the end of #endif

@@ -52,6 +52,7 @@ PRINT_USAGE() {
echo " --libs-only Do not build CH and GCStress"
echo " --lto Enables LLVM Full LTO"
echo " --lto-thin Enables LLVM Thin LTO - xcode 8+ or clang 3.9+"
echo " --lttng Enables LTTng support for ETW events"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

show error / warning if it's used on OSX? or add a note here?

build.sh Outdated
if [[ $HAS_LTTNG == 1 ]]; then
python tools/lttng.py --man `pwd`/manifests/Microsoft-Scripting-Chakra-Instrumentation.man --intermediate `pwd`/out/intermediate
mkdir -p `pwd`/out/lttng
diff -q `pwd`/out/intermediate/lttng/jscriptEtw.h `pwd`/out/lttng/jscriptEtw.h || cp `pwd`/out/intermediate/lttng/* `pwd`/out/lttng/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you create jscriptEtw.h already and put it under PlatformAgnostic/Linux ? What's the gain of doing this here dynamically?

++ This approach doesn't comply with build.sh --target-path folder selection.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jscriptEtw.h is one of the generated files, made from the ETW manifest. We could check it in to source control, but then it would get out of date when changes are made to the ETW manifest and that would cause issues. The diff check here is to try to improve incremental builds; if jscriptEtw.h is the same then the manifest hasn't changed, and so (barring changes to the generation script) all the generated files should be the same, so no need to dirty them which would cause most files to be recompiled

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding --target-path I wasn't aware of that; how would you recommend addressing that? It looks like currently the target path is contained completely within build.sh, and so I wouldn't be able to have the CMakeLists.txt reference the generated files without passing in their specific location.

@MSLaguana
Copy link
Contributor Author

I've also found an issue with our static builds; I suspect my cmake changes aren't quite right, since when ch dynamically links against libChakraCore.so I can get LTTng support, but when I do static builds and link against libChakraCoreStatic.a it's missing all the custom events. Trying to work out why still.

By placing structs at the end, it is simpler to generate the LTTng bindings
There was also a redundant ETW event parameter which was confusing the generator.
@obastemur
Copy link
Collaborator

@dotnet-bot test OSX static_osx_osx_debug please

@obastemur
Copy link
Collaborator

CCLock assert issue showsup on slow osx debug runs (similarly static build on exit). This is due to same xplat cleanup issue. Prioritizing it.

cmakeLines = []
cmakeLines.append("project(Chakra.LTTng)")
cmakeLines.append("")
cmakeLines.append("add_compile_options(-fPIC)")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Code-Gen-Options.html#Code-Gen-Options

fPIC vs fPIE?

++ could be nice to have these files under (i.e. pal/)lttng ? (instead of creating them dynamically)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LTTng docs all refer to -fPIC rather than -fPIE.

I could pre-generate these files, but then they would get out of sync with the ETW manifest. These are supposed to be equivalent to the auto-generated-as-part-of-build etw headers e.g. VcBuild\obj\x64_debug\CoreManifests\Microsoft-Scripting-Chakra-InstrumentationEvents.h.

Copy link
Collaborator

@obastemur obastemur Nov 27, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The LTTng docs all refer to -fPIC rather than -fPIE.

fPIC -> Shared Library
fPIE -> Executable.

(referring to ch-static builds)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to pre-generate to fix this.

cmakeLines.append("if(SHARED_LIBRARY)");
cmakeLines.append(    "add_compile_options(-fPIC)");
cmakeLines.append("endif()");

Root ChakraCore CmakeList embeds this file. So SHARED_LIBRARY will be set when necessary.

@obastemur
Copy link
Collaborator

I've also found an issue with our static builds; I suspect my cmake changes aren't quite right, since when ch dynamically links against libChakraCore.so

Please try -> https://github.com/Microsoft/ChakraCore/pull/4314/files#r153289187

@MSLaguana
Copy link
Contributor Author

I believe I've sorted out the dynamic vs static issue; now instead of always #define TRACEPOINT_PROBE_DYNAMIC_LINKAGE as the .net team do, I define it conditionally only if we will be dynamically linking (based on whether CHAKRA_STATIC_LIBRARY is defined).

@obastemur
Copy link
Collaborator

I believe I've sorted out the dynamic vs static issue

If things work, we can consider this as an initial step and incrementally make some changes. i.e. I'm feeling strong about removing that py file and having the cpp/h/cmake files under a folder. I also see we still have -fPIC is set regardless, not sure how that works for static builds though?

@MSLaguana
Copy link
Contributor Author

I noticed that some events weren't firing, turns out that __int64 was sometimes #defined to be unsigned long and sometimes not, and lttng was comparing the signature string of the tracepoints and deciding that they were different, and thus not enabling the tracepoints. By #undefining __int64 in that header it seems to fix the issue.

@obastemur
Copy link
Collaborator

undefining __int64 shouldn't be an issue (for xplat lttng) until we have ARM/x86 around. so please add a macro check to alert us if build arch is not x64.

@MSLaguana
Copy link
Contributor Author

I've added a preprocessor check to make sure we are building 64bit.

@MSLaguana
Copy link
Contributor Author

I've now also added proper support for --target-path by exposing that path to cmake and using directories relative to it.

@MSLaguana
Copy link
Contributor Author

Also just added support for the custom ETW events exposed to JS by moving the (fairly trivial) implementation out of PlatformAgnostic and into its one callsite. @digitalinfinity

@obastemur
Copy link
Collaborator

LGTM (#4314 (comment) could be really nice to have. Others nit.)

p.s. CI fail doesn't look serious. (unused variable)

@@ -47,6 +47,10 @@
#define JS_ETW(s) s
#define IS_JS_ETW(s) s

#ifdef ENABLE_JS_LTTNG
#include "jscriptEtw.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is somewhat confusing here (if lttng { include etw }) -- can the output file be jscriptLTTng.h instead? (Or, even better, JScriptLTTng.h or JScriptLttng.h

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The jscriptEtw.h file is kind of the cross-over point between ETW and our LTTng support: it provides an ETW-like interface (e.g. EmitEvent* functions) that call into our LTTng functions. If you still think it is confusing, I don't mind changing the name.

@@ -5968,7 +5968,7 @@ Recycler::ThreadProc()
}
#endif

#ifdef ENABLE_JS_ETW
#if defined(ENABLE_JS_ETW) && ! defined(ENABLE_JS_LTTNG)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps call that out as the reason why, here?

tools/lttng.py Outdated
"win:UInt16" :"const unsigned short",
"win:UInt8" :"const unsigned char",
"win:Int8" :"const char",
"win:Pointer" :"const size_t",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - I have no idea how this impacts things, but perhaps uintptr_t is a better xplat version of a Pointer type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I think I agree.

"win:Struct" :"const void",
"win:GUID" :"const GUID",
"win:AnsiString" :"LPCSTR",
"win:UnicodeString" :"PCWSTR",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit - my understanding was the (!L)P*STRs were more or less deprecated, since most of the code base uses LP data types rather than P data types (even though they map down to the same thing"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that some of these mappings here, including the string types, are part of the ETW interface. E.g. if you are passing a UnicodeString to an ETW event handler, I believe it expects a PCWSTR.

Running build.sh with the --lttng flag will generate ETW-like event emitting
functions that produce LTTng events. This means that you can get improved
diagnostics on non-windows platforms like so:

```bash
./build.sh --lttng # + whatever other flags
lttng create mySession
lttng enable-event -u "JScript:*" # or more specific events specified in the ETW manifest
lttng start
out/Release/ch script.js
lttng stop
lttng view
```
Since LTTng support replaces ETW backing functions, the code supporting
the JS-accessible custom ETW event works cross platform, if LTTng support
is compiled in. There is no need for the additional platform specific code.
@chakrabot chakrabot merged commit 41d2de9 into chakra-core:master Dec 7, 2017
chakrabot pushed a commit that referenced this pull request Dec 7, 2017
Merge pull request #4314 from MSLaguana:lttng

We define a number of ETW events on windows that we can emit for diagnostics purposes. With these changes, we support generating LTTng bindings for these same events so the same diagnostics approach can be used on linux and osx.

The script that generates the LTTng bindings from the ETW manifest is based on a similar script used by the dotnet team (see https://github.com/dotnet/coreclr/blob/master/src/scripts/genXplatLttng.py), but I have attempted to simplify it and adapt it for our purposes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants