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

Remove some dependencies on ddprof::Parser #336

Merged
merged 1 commit into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ set(DD_PROFILING_SOURCES
src/lib/saveregisters.cc
src/lib/symbol_overrides.cc
src/logger.cc
src/logger_setup.cc
src/perf.cc
src/perf_clock.cc
src/perf_ringbuffer.cc
Expand Down Expand Up @@ -254,8 +253,6 @@ if(BUILD_UNIVERSAL_DDPROF)
endif()
endif()

target_link_libraries(dd_profiling-embedded PRIVATE DDProf::Parser)

# Fix for link error in sanitizeddebug build mode with gcc:
# ~~~
# /usr/bin/ld: ./libdd_profiling.so: undefined reference to `__dynamic_cast'
Expand Down Expand Up @@ -343,7 +340,7 @@ target_include_directories(dd_profiling-static PUBLIC ${CMAKE_SOURCE_DIR}/includ
${CMAKE_SOURCE_DIR}/include)
set_target_properties(dd_profiling-static
PROPERTIES PUBLIC_HEADER "${CMAKE_SOURCE_DIR}/include/lib/dd_profiling.h")
target_link_libraries(dd_profiling-static PRIVATE DDProf::Parser ddprof_exe_object)
target_link_libraries(dd_profiling-static PRIVATE ddprof_exe_object)
target_link_libraries(dd_profiling-static PUBLIC dl pthread rt)

if(USE_LOADER)
Expand All @@ -359,7 +356,7 @@ else()
# Without loader, libdd_profiling.so is basically the same as libdd_profiling-embedded.so plus an
# embedded ddprof executable.
add_library(dd_profiling-shared SHARED ${DD_PROFILING_SOURCES} src/lib/lib_embedded_data.c)
target_link_libraries(dd_profiling-shared PRIVATE DDProf::Parser ddprof_exe_object)
target_link_libraries(dd_profiling-shared PRIVATE ddprof_exe_object)
target_compile_definitions(dd_profiling-shared PRIVATE DDPROF_EMBEDDED_EXE_DATA)

# Fix for link error in sanitizeddebug build mode with gcc:
Expand Down
9 changes: 0 additions & 9 deletions include/ddprof_cmdline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@

#pragma once

#include "ddprof_defs.hpp"

#include <cstddef>
#include <cstdint>
#include <vector>

namespace ddprof {

struct PerfWatcher;

/**************************** Cmdline Helpers *********************************/
// Helper functions for processing commandline arguments.
//
Expand All @@ -32,8 +27,4 @@ bool arg_inset(const char *str, char const *const *set, int sz_set);

bool arg_yesno(const char *str, int mode);

bool watchers_from_str(
const char *str, std::vector<PerfWatcher> &watchers,
uint32_t stack_sample_size = k_default_perf_stack_sample_size);

} // namespace ddprof
22 changes: 22 additions & 0 deletions include/ddprof_cmdline_watcher.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0. This product includes software
// developed at Datadog (https://www.datadoghq.com/). Copyright 2021-Present
// Datadog, Inc.

#pragma once

#include "ddprof_defs.hpp"

#include <cstddef>
#include <cstdint>
#include <vector>

namespace ddprof {

struct PerfWatcher;

bool watchers_from_str(
const char *str, std::vector<PerfWatcher> &watchers,
uint32_t stack_sample_size = k_default_perf_stack_sample_size);

} // namespace ddprof
1 change: 1 addition & 0 deletions src/ddprof_cli.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "CLI/CLI11.hpp"
#include "constants.hpp"
#include "ddprof_cmdline.hpp"
#include "ddprof_cmdline_watcher.hpp"
#include "ddprof_defs.hpp"
#include "ddres.hpp"
#include "logger.hpp"
Expand Down
117 changes: 0 additions & 117 deletions src/ddprof_cmdline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,104 +7,9 @@

#include <cassert>
#include <strings.h>
#include <utility>

#include "event_config.hpp"
#include "perf_watcher.hpp"
#include "tracepoint_config.hpp"

namespace ddprof {

namespace {
bool watcher_from_config(EventConf *conf, PerfWatcher *watcher) {
constexpr int64_t kIgnoredWatcherID = -1L;

// If there's no eventname, then this configuration is invalid
if (conf->eventname.empty()) {
return false;
}

// The watcher is templated; either from an existing Profiling template,
// keyed on the eventname, or it uses the generic template for Tracepoints
const PerfWatcher *tmp_watcher = ewatcher_from_str(conf->eventname.c_str());
if (tmp_watcher) {
*watcher = *tmp_watcher;
conf->id = kIgnoredWatcherID; // matched, so invalidate Tracepoint checks
} else if (!conf->groupname.empty()) {
// If the event doesn't match an ewatcher, it is only valid if a group was
// also provided (splitting events on ':' is the responsibility of the
// parser)
const auto *tmp_tracepoint_watcher = tracepoint_default_watcher();
if (!tmp_tracepoint_watcher) {
return false;
}
*watcher = *tmp_tracepoint_watcher;
} else {
return false;
}

if (conf->id != kIgnoredWatcherID) {
// The most likely thing to be invalid is the selection of the tracepoint
// from the trace events system. If the conf has a nonzero number for the
// id we assume the user has privileged information and knows what they
// want. Else, we use the group/event combination to extract that id from
// the tracefs filesystem in the canonical way.
int64_t tracepoint_id = 0;
if (conf->id > 0) {
tracepoint_id = conf->id;
} else {
tracepoint_id = tracepoint_get_id(conf->eventname, conf->groupname);
}
// At this point we needed to find a valid tracepoint id
if (tracepoint_id == kIgnoredWatcherID) {
return false;
}
watcher->config = tracepoint_id;
}

// Configure the sampling strategy. If no valid conf, use template default
if (conf->cadence != 0) {
if (conf->cad_type == EventConfCadenceType::kPeriod) {
watcher->sample_period = conf->cadence;
} else if (conf->cad_type == EventConfCadenceType::kFrequency) {
watcher->sample_frequency = conf->cadence;
watcher->options.is_freq = true;
}
}

// Configure value source
if (conf->value_source == EventConfValueSource::kRaw) {
watcher->value_source = EventConfValueSource::kRaw;
watcher->sample_type |= PERF_SAMPLE_RAW;
watcher->raw_off = conf->raw_offset;
if (conf->raw_size > 0) {
watcher->raw_sz = conf->raw_size;
} else {
watcher->raw_sz = sizeof(uint64_t); // default raw entry
}
} else if (conf->value_source == EventConfValueSource::kRegister) {
watcher->regno = conf->register_num;
watcher->value_source = EventConfValueSource::kRegister;
}

if (conf->value_scale != 0.0) {
watcher->value_scale = conf->value_scale;
}
watcher->aggregation_mode = conf->mode;
watcher->tracepoint_event = conf->eventname;
watcher->tracepoint_group = conf->groupname;
watcher->tracepoint_label = conf->label;
watcher->options.stack_sample_size = conf->stack_sample_size;
// Allocation watcher, has an extra field to ensure we capture address

if (watcher->config == kDDPROF_COUNT_ALLOCATIONS) {
watcher->sample_type |= PERF_SAMPLE_ADDR;
}

return true;
}
} // namespace

int arg_which(const char *str, char const *const *set, int sz_set) {
if (!str || !set) {
return -1;
Expand All @@ -130,26 +35,4 @@ bool arg_yesno(const char *str, int mode) {
return arg_which(str, set, sizeOfPatterns) != -1;
}

// If this returns false, then the passed watcher should be regarded as invalid
bool watchers_from_str(const char *str, std::vector<PerfWatcher> &watchers,
uint32_t stack_sample_size) {
std::vector<EventConf> configs;
const EventConf template_conf{
.mode = EventAggregationMode::kSum,
.stack_sample_size = stack_sample_size,
};
if (EventConf_parse(str, template_conf, configs) != 0) {
return false;
}

for (auto &conf : configs) {
PerfWatcher watcher;
if (!watcher_from_config(&conf, &watcher)) {
return false;
}
watchers.push_back(std::move(watcher));
}
return true;
}

} // namespace ddprof
128 changes: 128 additions & 0 deletions src/ddprof_cmdline_watcher.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0. This product includes software
// developed at Datadog (https://www.datadoghq.com/). Copyright 2021-Present
// Datadog, Inc.

#include "ddprof_cmdline_watcher.hpp"

#include <cassert>
#include <strings.h>
#include <utility>

#include "event_config.hpp"
#include "perf_watcher.hpp"
#include "tracepoint_config.hpp"

namespace ddprof {
namespace {
bool watcher_from_config(EventConf *conf, PerfWatcher *watcher) {
constexpr int64_t kIgnoredWatcherID = -1L;

// If there's no eventname, then this configuration is invalid
if (conf->eventname.empty()) {
return false;
}

// The watcher is templated; either from an existing Profiling template,
// keyed on the eventname, or it uses the generic template for Tracepoints
const PerfWatcher *tmp_watcher = ewatcher_from_str(conf->eventname.c_str());
if (tmp_watcher) {
*watcher = *tmp_watcher;
conf->id = kIgnoredWatcherID; // matched, so invalidate Tracepoint checks
} else if (!conf->groupname.empty()) {
// If the event doesn't match an ewatcher, it is only valid if a group was
// also provided (splitting events on ':' is the responsibility of the
// parser)
const auto *tmp_tracepoint_watcher = tracepoint_default_watcher();
if (!tmp_tracepoint_watcher) {
return false;
}
*watcher = *tmp_tracepoint_watcher;
} else {
return false;
}

if (conf->id != kIgnoredWatcherID) {
// The most likely thing to be invalid is the selection of the tracepoint
// from the trace events system. If the conf has a nonzero number for the
// id we assume the user has privileged information and knows what they
// want. Else, we use the group/event combination to extract that id from
// the tracefs filesystem in the canonical way.
int64_t tracepoint_id = 0;
if (conf->id > 0) {
tracepoint_id = conf->id;
} else {
tracepoint_id = tracepoint_get_id(conf->eventname, conf->groupname);
}
// At this point we needed to find a valid tracepoint id
if (tracepoint_id == kIgnoredWatcherID) {
return false;
}
watcher->config = tracepoint_id;
}

// Configure the sampling strategy. If no valid conf, use template default
if (conf->cadence != 0) {
if (conf->cad_type == EventConfCadenceType::kPeriod) {
watcher->sample_period = conf->cadence;
} else if (conf->cad_type == EventConfCadenceType::kFrequency) {
watcher->sample_frequency = conf->cadence;
watcher->options.is_freq = true;
}
}

// Configure value source
if (conf->value_source == EventConfValueSource::kRaw) {
watcher->value_source = EventConfValueSource::kRaw;
watcher->sample_type |= PERF_SAMPLE_RAW;
watcher->raw_off = conf->raw_offset;
if (conf->raw_size > 0) {
watcher->raw_sz = conf->raw_size;
} else {
watcher->raw_sz = sizeof(uint64_t); // default raw entry
}
} else if (conf->value_source == EventConfValueSource::kRegister) {
watcher->regno = conf->register_num;
watcher->value_source = EventConfValueSource::kRegister;
}

if (conf->value_scale != 0.0) {
watcher->value_scale = conf->value_scale;
}
watcher->aggregation_mode = conf->mode;
watcher->tracepoint_event = conf->eventname;
watcher->tracepoint_group = conf->groupname;
watcher->tracepoint_label = conf->label;
watcher->options.stack_sample_size = conf->stack_sample_size;
// Allocation watcher, has an extra field to ensure we capture address

if (watcher->config == kDDPROF_COUNT_ALLOCATIONS) {
watcher->sample_type |= PERF_SAMPLE_ADDR;
}

return true;
}
} // namespace
// If this returns false, then the passed watcher should be regarded as invalid
bool watchers_from_str(const char *str, std::vector<PerfWatcher> &watchers,
uint32_t stack_sample_size) {
std::vector<EventConf> configs;
const EventConf template_conf{
.mode = EventAggregationMode::kSum,
.stack_sample_size = stack_sample_size,
};
if (EventConf_parse(str, template_conf, configs) != 0) {
return false;
}

for (auto &conf : configs) {
PerfWatcher watcher;
if (!watcher_from_config(&conf, &watcher)) {
return false;
}
watchers.push_back(std::move(watcher));
}
return true;
}

} // namespace ddprof
2 changes: 1 addition & 1 deletion src/presets.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include "presets.hpp"

#include "ddprof_cmdline.hpp"
#include "ddprof_cmdline_watcher.hpp"
#include "ddres.hpp"

#include <algorithm>
Expand Down
Loading