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

chore(profiling): add non-running tests for stack v2 [backport 2.7] #8824

Merged
merged 2 commits into from
Apr 2, 2024
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
15 changes: 14 additions & 1 deletion ddtrace/internal/datadog/profiling/cmake/AnalysisFunc.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ function(add_ddup_config target)
"$<$<CONFIG:Release>:-s>"
-Wl,--as-needed -Wl,-Bsymbolic-functions -Wl,--gc-sections
)
set_property(TARGET ${target} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

# If we can IPO, then do so
check_ipo_supported(RESULT result)
if (result)
set_property(TARGET ${target} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
Expand All @@ -22,6 +23,18 @@ function(add_ddup_config target)
# pointers, so we include it here.
target_compile_options(${target} PRIVATE -fsanitize=${SANITIZE_OPTIONS} -fno-omit-frame-pointer)
target_link_options(${target} PRIVATE -fsanitize=${SANITIZE_OPTIONS})

# We need to do a little bit of work in order to ensure the dynamic *san libraries can be linked
# Procedure adapted from datadog/ddprof :)
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=
OUTPUT_VARIABLE LIBSAN_LIB_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE COMMAND_ERROR_IS_FATAL ANY
)
set_target_properties(${target} PROPERTIES
INSTALL_RPATH ${LIBSAN_LIB_PATH}
BUILD_RPATH ${LIBSAN_LIB_PATH}
)
endif()

# If DO_FANALYZER is specified and we're using gcc, then we can use -fanalyzer
Expand Down
19 changes: 19 additions & 0 deletions ddtrace/internal/datadog/profiling/cmake/FindClangtidy.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Enable clang-tidy by default
option(DO_CLANGTIDY "Enable clang-tidy" OFF)

# Default executable for clang-tidy
if (NOT DEFINED CLANGTIDY_CMD)
find_program(CLANGTIDY_CMD NAMES clang-tidy)
endif()

function(add_clangtidy_target TARGET)
if (NOT DO_CLANGTIDY)
return()
endif()

if (CLANGTIDY_CMD)
set_target_properties(${TARGET} PROPERTIES CXX_CLANG_TIDY "${CLANGTIDY_CMD};--checks=bugprone-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,performance-*,readability-*,-modernize-use-trailing-return-type,-performance-avoid-endl")
else()
message(FATAL_ERROR "clang-tidy requested but executable not found")
endif()
endfunction()
29 changes: 22 additions & 7 deletions ddtrace/internal/datadog/profiling/cmake/FindCppcheck.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,21 @@ if (TARGET cppcheck_project)
return()
endif()

# Set the default value for the cppcheck option
option(DO_CPPCHECK "Enable cppcheck" OFF)

include(ExternalProject)

# Build cppcheck from sources
if (DO_CPPCHECK)
ExternalProject_Add(cppcheck_project
GIT_REPOSITORY https://github.com/danmar/cppcheck.git
GIT_TAG "2.13.3"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/cppcheck
)
set(CPPCHECK_EXECUTABLE ${CMAKE_BINARY_DIR}/cppcheck/bin/cppcheck)
if (NOT CPPCHECK_EXECUTABLE OR NOT EXISTS "${CPPCHECK_EXECUTABLE}")
ExternalProject_Add(cppcheck_project
GIT_REPOSITORY https://github.com/danmar/cppcheck.git
GIT_TAG "2.13.3"
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/cppcheck
)
set(CPPCHECK_EXECUTABLE ${CMAKE_BINARY_DIR}/cppcheck/bin/cppcheck)
endif()

# The function we use to register targets for cppcheck would require us to run separate
# commands for each target, which is annoying. Instead we'll consolidate all the targets
Expand All @@ -30,7 +35,7 @@ function(add_cppcheck_target)
cmake_parse_arguments(PARSE_ARGV 0 ARG "${options}" "${oneValueArgs}" "${multiValueArgs}")

# Automatically generate the cppcheck target name
set(NAME "cppcheck_dd_${ARGV0}")
set(NAME "cppcheck_${ARGV0}")

if (DO_CPPCHECK)
# Initialize command variable
Expand All @@ -50,6 +55,7 @@ function(add_cppcheck_target)

# Append include directories to the command
foreach(INCLUDE_DIR ${ARG_INCLUDE})
message(STATUS "Adding include directory to cppcheck: ${INCLUDE_DIR}")
list(APPEND cppcheck_cmd -I ${INCLUDE_DIR})
endforeach()

Expand All @@ -73,4 +79,13 @@ function(add_cppcheck_target)
COMMENT "cppcheck is disabled for ${ARGV0}"
)
endif()

# Create a standard target to run everything
if (NOT TARGET cppcheck)
add_custom_target(cppcheck COMMENT "Runs cppcheck on all projects")
endif()

if (DO_CPPCHECK)
add_dependencies(cppcheck ${NAME})
endif()
endfunction()
66 changes: 66 additions & 0 deletions ddtrace/internal/datadog/profiling/cmake/FindInfer.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Only add this project if Infer is not defined
if(TARGET Infer)
return()
endif()

include(ExternalProject)
# Only grab infer dependencies if we need to
if (DO_INFER)
if (NOT Infer_EXECUTABLE OR NOT EXISTS "${Infer_EXECUTABLE}")
set(TAG_INFER
"v1.1.0"
CACHE STRING "infer github tag")

set(Infer_BUILD_DIR ${CMAKE_BINARY_DIR}/infer)
set(Infer_ROOT ${Infer_BUILD_DIR}/infer-${TAG_LIBDATADOG})

message(STATUS "${CMAKE_CURRENT_LIST_DIR}/tools/fetch_infer.sh ${TAG_INFER} ${Infer_ROOT}")
execute_process(
COMMAND "${CMAKE_CURRENT_LIST_DIR}/tools/fetch_infer.sh" ${TAG_INFER} ${Infer_ROOT}
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
COMMAND_ERROR_IS_FATAL ANY
)

set(Infer_DIR "${Infer_ROOT}")
set(Infer_EXECUTABLE "${Infer_DIR}/bin/infer")
endif()
endif()

# Add a target for using infer. It does nothing if DO_INFER is not set
function(add_infer_target TARGET)
# Automatically generate the infer target name
set(NAME "infer_dd_${TARGET}")

if (NOT TARGET ${TARGET})
message(FATAL_ERROR "Target ${TARGET} does not exist")
return()
endif()

if (DO_INFER)
# Initialize command variable
set(infer_cmd
${Infer_EXECUTABLE}
--compilation-database ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json
)

# Define the custom target with the constructed command
add_custom_target(${NAME}
COMMAND ${infer_cmd}
COMMENT "Running infer on ${TARGET}"
)

# infer can't seem to find stdlib headers, so we have to add them to the target so they are included in the compile_commands.json
foreach(inc ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
target_include_directories(${TARGET} PRIVATE ${inc})
endforeach()

# Make the infer target a dependent of the specified target
add_dependencies(${TARGET} ${NAME})
else()
# Define a do-nothing target if infer is disabled
add_custom_target(${NAME}
COMMAND echo "infer target ${NAME} is disabled."
COMMENT "infer is disabled for ${TARGET}"
)
endif()
endfunction()
76 changes: 76 additions & 0 deletions ddtrace/internal/datadog/profiling/cmake/tools/fetch_infer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/bash
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euox pipefail
IFS=$'\n\t'

usage() {
echo "Usage :"
echo "$0 <version> <path>"
echo ""
echo "Example"
echo " $0 v0.7.0-rc.1 ./vendor"
}

if [ $# != 2 ] || [ "$1" == "-h" ]; then
usage
exit 1
fi

SCRIPTPATH=$(readlink -f "$0")
SCRIPTDIR=$(dirname "$SCRIPTPATH")

MARCH=$(uname -m)

TAG_INFER=$1
TARGET_EXTRACT=$2

CHECKSUM_FILE=${SCRIPTDIR}/infer_checksums.txt

# https://github.com/facebook/infer/releases/download/v1.1.0/infer-linux64-v1.1.0.tar.xz
TAR_INFER=infer-linux64-${TAG_INFER}.tar.xz
GITHUB_URL_INFER=https://github.com/facebook/infer/releases/download/${TAG_INFER}/${TAR_INFER}

SHA256_INFER="blank"
while IFS=' ' read -r checksum filename; do
if [ "$filename" == "$TAR_INFER" ]; then
SHA256_INFER="$checksum $filename"
break
fi
done < "$CHECKSUM_FILE"

if [ "$SHA256_INFER" == "blank" ]; then
echo "Could not find checksum for ${TAR_INFER} in ${CHECKSUM_FILE}"
exit 1
else
echo "Using infer sha256: ${SHA256_INFER}"
fi

mkdir -p "$TARGET_EXTRACT" || true
cd "$TARGET_EXTRACT"

if [[ -e "${TAR_INFER}" ]]; then
already_present=1
else
already_present=0
echo "Downloading infer ${GITHUB_URL_INFER}..."
if command -v curl > /dev/null 2>&1; then
curl -fsSLO "${GITHUB_URL_INFER}"
elif command -v wget > /dev/null 2>&1; then
wget -q -O "${GITHUB_URL_INFER##*/}" "${GITHUB_URL_INFER}"
else
echo "Error: neither curl nor wget is available." >&2
exit 1
fi
fi

echo "Checking infer sha256"
if ! echo "${SHA256_INFER}" | sha256sum -c -; then
echo "Error validating infer SHA256"
echo "Please clear $TARGET_EXTRACT before restarting"
exit 1
fi

if [[ $already_present -eq 0 ]]; then
echo "Extracting ${TAR_INFER}"
tar xf "${TAR_INFER}" --strip-components=1 --no-same-owner
fi
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5f5d453814422e93e2a70998d8946b09a2721628ff427f67ff0123dea87461d4 infer-linux64-v1.1.0.tar.xz
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ include(FetchContent)
include(ExternalProject)
include(FindLibdatadog)
include(AnalysisFunc)
include(FindClangtidy)
include(FindCppcheck)
include(FindInfer)

# Library sources
add_library(dd_wrapper SHARED
Expand Down Expand Up @@ -59,6 +61,9 @@ add_cppcheck_target(dd_wrapper
SRC ${CMAKE_CURRENT_SOURCE_DIR}/src
)

add_infer_target(dd_wrapper)
add_clangtidy_target(dd_wrapper)

# Add the tests
if (BUILD_TESTING)
enable_testing()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extern "C"

bool ddup_is_initialized();
void ddup_init();
void ddup_set_runtime_id(std::string_view id);
void ddup_set_runtime_id(std::string_view runtime_id);
bool ddup_upload();

// Proxy functions to the underlying sample
Expand All @@ -36,8 +36,8 @@ extern "C"
void ddup_push_cputime(Datadog::Sample* sample, int64_t cputime, int64_t count);
void ddup_push_acquire(Datadog::Sample* sample, int64_t acquire_time, int64_t count);
void ddup_push_release(Datadog::Sample* sample, int64_t release_time, int64_t count);
void ddup_push_alloc(Datadog::Sample* sample, uint64_t size, uint64_t count);
void ddup_push_heap(Datadog::Sample* sample, uint64_t size);
void ddup_push_alloc(Datadog::Sample* sample, int64_t size, int64_t count);
void ddup_push_heap(Datadog::Sample* sample, int64_t size);
void ddup_push_lock_name(Datadog::Sample* sample, std::string_view lock_name);
void ddup_push_threadinfo(Datadog::Sample* sample,
int64_t thread_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <iostream>
#include <string>
#include <string_view>
#include <variant>

extern "C"
{
Expand Down Expand Up @@ -126,6 +127,16 @@ add_tag(ddog_Vec_Tag& tags, const ExportTagKey key, std::string_view val, std::s
return add_tag(tags, key_sv, val, errmsg);
}

inline std::variant<ddog_prof_Exporter*, ddog_Error>
get_newexporter_result(const ddog_prof_Exporter_NewResult& res)
{
if (res.tag == DDOG_PROF_EXPORTER_NEW_RESULT_OK) {
return res.ok; // NOLINT (cppcoreguidelines-pro-type-union-access)
} else {
return res.err; // NOLINT (cppcoreguidelines-pro-type-union-access)
}
}

// Keep macros from propagating
#undef X_STR
#undef X_ENUM
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class Profile
void profile_release();

// String table manipulation
std::string_view insert_or_get(std::string_view sv);
std::string_view insert_or_get(std::string_view str);

// constref getters
const ValueIndex& val();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "profile.hpp"
#include "types.hpp"

#include <array>
#include <string>
#include <string_view>
#include <vector>
Expand Down Expand Up @@ -32,8 +31,7 @@ class Sample
uint64_t samples = 0;

// Storage for labels
std::array<ddog_prof_Label, static_cast<size_t>(ExportLabelKey::Length_)> labels{};
size_t cur_label = 0;
std::vector<ddog_prof_Label> labels{};

// Storage for values
std::vector<int64_t> values = {};
Expand All @@ -50,8 +48,8 @@ class Sample
bool push_cputime(int64_t cputime, int64_t count);
bool push_acquire(int64_t acquire_time, int64_t count);
bool push_release(int64_t lock_time, int64_t count);
bool push_alloc(uint64_t size, uint64_t count);
bool push_heap(uint64_t size);
bool push_alloc(int64_t size, int64_t count);
bool push_heap(int64_t size);

// Adds metadata to sample
bool push_lock_name(std::string_view lock_name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class SampleManager

// Sampling entrypoint (this could also be called `build_ptr()`)
static Sample* start_sample();
static void drop_sample(Sample* sample);

// Handles state management after forks
static void postfork_child();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ struct DdogProfExporterDeleter
void operator()(ddog_prof_Exporter* ptr) const;
};

struct DdogCancellationTokenDeleter
{
void operator()(ddog_CancellationToken* ptr) const;
};

class Uploader
{
private:
static inline std::mutex upload_lock{};
std::string errmsg;
static inline ddog_CancellationToken* cancel{ nullptr };
static inline std::unique_ptr<ddog_CancellationToken, DdogCancellationTokenDeleter> cancel;
std::string runtime_id;
std::string url;
std::unique_ptr<ddog_prof_Exporter, DdogProfExporterDeleter> ddog_exporter;
Expand Down
Loading
Loading