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

Tracing DLLs in in-process mode #712

Closed
worawatt opened this issue Feb 20, 2024 · 3 comments
Closed

Tracing DLLs in in-process mode #712

worawatt opened this issue Feb 20, 2024 · 3 comments

Comments

@worawatt
Copy link

I am tracing my C++ application on Windows by following https://perfetto.dev/docs/instrumentation/tracing-sdk#recording and this example https://github.com/google/perfetto/blob/master/examples/sdk/example.cc (Tracing through the API in the in-process mode).

My application links to a DLL (let calls it foo.dll which built from foo.cpp).

I called tracing_session->StartBlocking() in the main function (example.cc) and added TRACE_EVENT in both example.cc and foo.cpp.
However, the trace result only contains the the trace from the example.cc but not foo.cpp.

Any suggestions?

Minimal code to show what I did (modified from https://github.com/google/perfetto/blob/master/examples/sdk/example.cc):

# CMakeLists.txt
...

# Define a static library for Perfetto. In this example, we expect the SDK
# (perfetto.cc and perfetto.h) to live in the top level sdk/ directory.
include_directories(../../sdk)
add_library(perfetto STATIC ../../sdk/perfetto.cc)

add_library(foo SHARED foo.cpp)
target_compile_definitions(foo PRIVATE FOO_IMPLEMENT)
target_include_directories(foo PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
target_link_libraries(foo perfetto)

# Link the library to the main executables.
add_executable(example example.cc trace_categories.cc)
target_link_libraries(example foo)

target_link_libraries(example perfetto
                      ${CMAKE_THREAD_LIBS_INIT})
...
// foo.hpp
#ifndef FOO_H
#define FOO_H

# ifdef FOO_IMPLEMENT
#  define DECLSPEC __declspec(dllexport)
# else
#  define DECLSPEC __declspec(dllimport)
# endif

DECLSPEC void foo();

#endif // FOO_H
// foo.cpp
#include "foo.hpp"
#include <iostream>
#include <trace_categories.h>

void foo() {
    TRACE_EVENT("rendering", "foo");
    std::cout << "Hello from foo!" << std::endl;
}
// example.cc
...

int main(int, const char**) {
  InitializePerfetto();
  auto tracing_session = StartTracing();

  // Give a custom name for the traced process.
  perfetto::ProcessTrack process_track = perfetto::ProcessTrack::Current();
  perfetto::protos::gen::TrackDescriptor desc = process_track.Serialize();
  desc.mutable_process()->set_process_name("Example");
  perfetto::TrackEvent::SetTrackDescriptor(process_track, desc);

  // Simulate some work that emits trace events.
  DrawGame();

  foo();

  StopTracing(std::move(tracing_session));
  return 0;
}

@ddiproietto
Copy link
Collaborator

Hi!

By linking statically the perfetto library to two separate DLLs, you're effectively creating two separate instances of the library, so the behavior you're observing is expected.

The most straightforward solution would be to avoid dynamic linking at all, that's what perfetto was originally designed for. I'm not sure it's an option in your case, though.

You can try linking dynamically, but the C++ annotations for dynamic linking (PERFETTO_EXPORT_COMPONENT) are supported on a best effort basis, mostly for tests.

Lastly, you can use the more restricted C API in include/perfetto/public (examples in examples/shared_lib/). Dynamic linking is officially supported there. The only blocker there is that there's no easy way to build the C shared library with CMake. I've opened #713 to keep track of this.

Those are the options at the moment, I believe. Let me know if you have any questions.

@worawatt
Copy link
Author

Thank you for this information!

I'll try dynamic linking (although it's not fully supported).

Does trace_categories.cc also have to be built as a dynamic library?

@ddiproietto
Copy link
Collaborator

Does trace_categories.cc also have to be built as a dynamic library?

Not really, you can have separate trace_categories.cc that are statically linked into each .DLL

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

No branches or pull requests

3 participants