Skip to content

Commit

Permalink
Split ddprof_cmdline into 2 files
Browse files Browse the repository at this point in the history
This allows to removing dependency on ddprof::Parser for profiling lib
and some unit tests.
  • Loading branch information
nsavoire committed Oct 24, 2023
1 parent 9932639 commit 000ddde
Show file tree
Hide file tree
Showing 10 changed files with 172 additions and 160 deletions.
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
std::optional<PerfWatcher> watchers_from_str(const char *str,
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 std::nullopt;
}

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

0 comments on commit 000ddde

Please sign in to comment.