Skip to content

Commit

Permalink
Make debuginfod configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
cvonelm committed Feb 11, 2025
1 parent 9ad8f3c commit add3923
Show file tree
Hide file tree
Showing 24 changed files with 443 additions and 320 deletions.
30 changes: 17 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ IfUpdatedUnsetAll(lo2s_USE_STATIC_LIBS
Radare_USE_STATIC_LIBS
Sensors_USE_STATIC_LIBS
Veosinfo_USE_STATIC_LIBS
Audit_USE_STATIC_LIBS)
Audit_USE_STATIC_LIBS
Debuginfod_USE_STATIC_LIBS
)

if(lo2s_USE_STATIC_LIBS STREQUAL "OFF")
set(Dl_USE_STATIC_LIBS OFF CACHE BOOL "")
Expand All @@ -56,7 +58,6 @@ if(lo2s_USE_STATIC_LIBS STREQUAL "OFF")
else()
if(lo2s_USE_STATIC_LIBS STREQUAL "MOSTLY")
set(Dl_USE_STATIC_LIBS OFF CACHE BOOL "")

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc")
elseif(lo2s_USE_STATIC_LIBS STREQUAL "ALL")
set(Dl_USE_STATIC_LIBS ON CACHE BOOL "")
Expand All @@ -67,8 +68,6 @@ else()
set(CMAKE_LINK_SEARCH_START_STATIC 1)
set(CMAKE_LINK_SEARCH_END_STATIC 1)
endif()

if(lo2s_USE_STATIC_LIBS STREQUAL "MOSTLY")
set(Dl_USE_STATIC_LIBS OFF CACHE BOOL "")
set(LibElf_USE_STATIC_LIBS ON CACHE BOOL "")
set(OTF2_USE_STATIC_LIBS ON CACHE BOOL "")
Expand All @@ -81,6 +80,8 @@ else()
set(Veosinfo_USE_STATIC_LIBS ON CACHE BOOL "")
set(Radare_USE_STATIC_LIBS ON CACHE BOOL "")
set(Audit_USE_STATIC_LIBS ON CACHE BOOL "")
set(Debuginfod_USE_STATIC_LIBS ON CACHE BOOL "")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc")
endif()

# Check if we are running Linux
Expand Down Expand Up @@ -116,6 +117,7 @@ find_package(CUDAToolkit)
find_package(Radare)
find_package(Audit)
find_package(LibElf REQUIRED)
find_package(Debuginfod)


# configurable options
Expand All @@ -135,6 +137,8 @@ CMAKE_DEPENDENT_OPTION(USE_VEOSINFO "Use libveosinfo to sample NEC SX-Aurora Tsu
add_feature_info("USE_VEOSINFO" USE_VEOSINFO "Use libveosinfo to sample NEC SX-Aurora Tsubasa cards.")
CMAKE_DEPENDENT_OPTION(USE_CUPTI "Use CUPTI to record CUDA activity." ON "CUDAToolkit_FOUND" OFF)
add_feature_info("USE_CUPTI" USE_CUPTI "Use CUPTI to record CUDA activity.")
CMAKE_DEPENDENT_OPTION(USE_DEBUGINFOD "Use Debuginfod to download debug information on-demand." ON "Debuginfod_FOUND" OFF)
add_feature_info("USE_DEBUGINFOD" USE_DEBUGINFOD "Use Debuginfod to download debug information on-demand.")
# system configuration checks
CHECK_INCLUDE_FILES(linux/hw_breakpoint.h HAVE_HW_BREAKPOINT_H)
CHECK_STRUCT_HAS_MEMBER("struct perf_event_attr" clockid linux/perf_event.h HAVE_PERF_EVENT_ATTR_CLOCKID)
Expand Down Expand Up @@ -231,17 +235,8 @@ target_link_libraries(lo2s
std::filesystem
LibElf::LibElf
LibElf::LibDw
debuginfod
)

find_path(DEBUGINFOD_INCLUDE_DIRS elfutils/debuginfod.h
PATHS ENV C_INCLUDE_PATH ENV CPATH
PATH_SUFFIXES include)

if(DEBUGINFOD_INCLUDE_DIRS)
target_compile_definitions(lo2s PUBLIC HAVE_DEBUGINFOD)
endif()

# old glibc versions require -lrt for clock_gettime()
if(NOT CLOCK_GETTIME_FOUND)
if(CLOCK_GETTIME_FOUND_WITH_RT)
Expand Down Expand Up @@ -321,6 +316,15 @@ if (USE_VEOSINFO)
endif()
endif()

if (USE_DEBUGINFOD)
if (Debuginfod_FOUND)
target_compile_definitions(lo2s PUBLIC HAVE_DEBUGINFOD)
target_link_libraries(lo2s PRIVATE Debuginfod::Debuginfod)
else()
message(SEND_ERROR "Debuginfod not found but requested")
endif()
endif()

if (USE_LIBPFM)
if (Libpfm_FOUND)
target_compile_definitions(lo2s PUBLIC HAVE_LIBPFM)
Expand Down
56 changes: 56 additions & 0 deletions cmake/FindDebuginfod.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright (c) 2022, Technische Universität Dresden, Germany
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification, are permitted
# provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions
# and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
# and the following disclaimer in the documentation and/or other materials provided with the
# distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
# or promote products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

include(${CMAKE_CURRENT_LIST_DIR}/UnsetIfUpdated.cmake)

# Linking libelf isn't a great default because it produces warnings
option(Debuginfod_USE_STATIC_LIBS "Link debuginfod statically." OFF)

UnsetIfUpdated(Debuginfod_LIBRARY Debuginfod_USE_STATIC_LIBS)

find_path(Debuginfod_INCLUDE_DIRS libelf.h
PATHS ENV C_INCLUDE_PATH ENV CPATH
PATH_SUFFIXES include)

if(Debuginfod_USE_STATIC_LIBS)
find_library(Debuginfod_LIBRARY NAMES libdebuginfod.a
HINTS ENV LIBRARY_PATH)
else()
find_library(Debuginfod_LIBRARY NAMES libdebuginfod.so
HINTS ENV LIBRARY_PATH LD_LIBRARY_PATH)
endif()

include (FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Debuginfod DEFAULT_MSG
Debuginfod_LIBRARY
Debuginfod_INCLUDE_DIRS)

if(Debuginfod_FOUND)
add_library(Debuginfod::Debuginfod UNKNOWN IMPORTED)
set_property(TARGET Debuginfod::Debuginfod PROPERTY IMPORTED_LOCATION ${Debuginfod_LIBRARY})
target_include_directories(Debuginfod::Debuginfod INTERFACE ${Debuginfod_INCLUDE_DIRS})
endif()

mark_as_advanced(Debuginfod_LIBRARY Debuginfod_INCLUDE_DIRS)
8 changes: 6 additions & 2 deletions include/lo2s/dwarf_resolve.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@ class DwarfFunctionResolver : public FunctionResolver
public:
DwarfFunctionResolver(std::string name);

static FunctionResolver& cache(std::string name)
static std::shared_ptr<FunctionResolver> cache(std::string name)
{
return StringCache<DwarfFunctionResolver>::instance()[name];
return BinaryCache<DwarfFunctionResolver>::instance()[name];
}

DwarfFunctionResolver(DwarfFunctionResolver&) = delete;
DwarfFunctionResolver& operator=(DwarfFunctionResolver&) = delete;
DwarfFunctionResolver(DwarfFunctionResolver&&) = delete;
DwarfFunctionResolver& operator=(DwarfFunctionResolver&&) = delete;
~DwarfFunctionResolver();
virtual LineInfo lookup_line_info(Address addr) override;

Expand Down
2 changes: 1 addition & 1 deletion include/lo2s/execution_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class ExecutionScope
case ExecutionScopeType::THREAD:
return fmt::format("thread {}", id);
case ExecutionScopeType::PROCESS:
return fmt::format("process {}");
return fmt::format("process {}", id);
case ExecutionScopeType::CPU:
return fmt::format("cpu {}", id);
default:
Expand Down
31 changes: 23 additions & 8 deletions include/lo2s/function_resolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
#include <lo2s/line_info.hpp>
#include <lo2s/util.hpp>

#include <string>
#include <regex>
#include <string>

namespace lo2s
{
Expand All @@ -36,9 +36,9 @@ class FunctionResolver
{
}

static FunctionResolver& cache(const std::string& name)
static std::shared_ptr<FunctionResolver> cache(const std::string& name)
{
return StringCache<FunctionResolver>::instance()[name];
return BinaryCache<FunctionResolver>::instance()[name];
}

virtual LineInfo lookup_line_info(Address)
Expand All @@ -51,6 +51,15 @@ class FunctionResolver
return name_;
}

virtual void insert(std::map<Address, std::string>& functions [[maybe_unused]])
{
throw std::runtime_error("Class does not support inserting elements");
}

virtual ~FunctionResolver()
{
}

protected:
std::string name_;
};
Expand All @@ -61,8 +70,14 @@ class Kallsyms : public FunctionResolver
Kallsyms() : FunctionResolver("[kernel]")
{
std::map<Address, std::string> entries;
std::ifstream ksyms_file("/proc/kallsyms");
std::ifstream ksyms_file;
ksyms_file.exceptions(std::ifstream::badbit);
ksyms_file.open("/proc/kallsyms");

if (!ksyms_file.good())
{
return;
}
std::regex ksym_regex("([0-9a-f]+) (?:t|T) ([^[:space:]]+)");
std::smatch ksym_match;

Expand Down Expand Up @@ -107,9 +122,9 @@ class Kallsyms : public FunctionResolver
}
}

static Kallsyms& cache()
static std::shared_ptr<Kallsyms> cache()
{
static Kallsyms k;
static std::shared_ptr<Kallsyms> k = std::make_shared<Kallsyms>();
return k;
}

Expand All @@ -125,6 +140,6 @@ class Kallsyms : public FunctionResolver

private:
std::map<Range, std::string> kallsyms_;
uint64_t start_;
uint64_t start_ = UINT64_MAX;
};
}
} // namespace lo2s
11 changes: 8 additions & 3 deletions include/lo2s/instruction_resolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* along with lo2s. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once
#pragma once

#include <lo2s/address.hpp>
#ifdef HAVE_RADARE
Expand All @@ -28,6 +28,7 @@
#include <lo2s/util.hpp>

#include <string>

namespace lo2s
{
class InstructionResolver
Expand All @@ -47,6 +48,10 @@ class InstructionResolver
{
return "";
}

virtual ~InstructionResolver()
{
}
};
#ifdef HAVE_RADARE
class RadareInstructionResolver : public InstructionResolver
Expand All @@ -56,9 +61,9 @@ class RadareInstructionResolver : public InstructionResolver
{
}

static RadareInstructionResolver& cache(const std::string& name)
static std::shared_ptr<RadareInstructionResolver> cache(const std::string& name)
{
return StringCache<RadareInstructionResolver>::instance()[name];
return BinaryCache<RadareInstructionResolver>::instance()[name];
}

virtual std::string lookup_instruction(Address ip)
Expand Down
5 changes: 5 additions & 0 deletions include/lo2s/measurement_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@ struct MeasurementScope
return (lhs.scope == rhs.scope) && lhs.type == rhs.type;
}

MeasurementScope from_ex_scope(ExecutionScope new_scope)
{
return MeasurementScope(type, new_scope);
}

friend bool operator<(const MeasurementScope& lhs, const MeasurementScope& rhs)
{
if (lhs.type != rhs.type)
Expand Down
13 changes: 7 additions & 6 deletions include/lo2s/perf/calling_context_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

#include <lo2s/address.hpp>
#include <lo2s/log.hpp>

#include <lo2s/measurement_scope.hpp>
#include <otf2xx/otf2.hpp>

extern "C"
Expand All @@ -46,7 +46,7 @@ struct LocalCctx
class LocalCctxMap
{
public:
LocalCctxMap()
LocalCctxMap(MeasurementScope scope) : scope_(scope)
{
}

Expand Down Expand Up @@ -79,7 +79,7 @@ class LocalCctxMap
// information.
//
// Having these things in mind, look at this line and tell me, why it is still wrong:
auto children = &map[p];
auto children = &map[scope_.from_ex_scope(p.as_scope())];
uint64_t ref = -1;
for (uint64_t i = num_ips - 1;; i--)
{
Expand Down Expand Up @@ -112,7 +112,7 @@ class LocalCctxMap

otf2::definition::calling_context::reference_type sample_ref(Process p, uint64_t ip)
{
auto it = find_ip_child(ip, map[p]);
auto it = find_ip_child(ip, map[scope_.from_ex_scope(p.as_scope())]);

return it->second.ref;
}
Expand Down Expand Up @@ -140,7 +140,7 @@ class LocalCctxMap
return thread_cctxs_;
}

const std::map<Process, std::map<Address, LocalCctx>>& get_functions() const
const std::map<MeasurementScope, std::map<Address, LocalCctx>>& get_functions() const
{
return map;
}
Expand Down Expand Up @@ -170,8 +170,9 @@ class LocalCctxMap
}

private:
std::map<Process, std::map<Address, LocalCctx>> map;
std::map<MeasurementScope, std::map<Address, LocalCctx>> map;
std::map<Process, std::map<Thread, LocalCctx>> thread_cctxs_;
MeasurementScope scope_;

/*
* Stores calling context information for each sample writer / monitoring thread.
Expand Down
4 changes: 0 additions & 4 deletions include/lo2s/perf/event_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ class EventReader
using RecordUnknownType = perf_event_header;

using RecordMmapType = lo2s::RecordMmapType;
using RecordMmap2Type = lo2s::RecordMmap2Type;
using RecordCommType = lo2s::RecordCommType;

struct RecordLostType
Expand Down Expand Up @@ -176,9 +175,6 @@ class EventReader
case PERF_RECORD_MMAP:
stop = crtp_this->handle((const RecordMmapType*)event_header_p);
break;
case PERF_RECORD_MMAP2:
stop = crtp_this->handle((const RecordMmap2Type*)event_header_p);
break;
case PERF_RECORD_SWITCH:
stop = crtp_this->handle((const RecordSwitchType*)event_header_p);
break;
Expand Down
2 changes: 1 addition & 1 deletion include/lo2s/perf/sample/writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Writer : public Reader<Writer>
public:
using Reader<Writer>::handle;
bool handle(const Reader::RecordSampleType* sample);
bool handle(const Reader::RecordMmap2Type* mmap_event);
bool handle(const Reader::RecordMmapType* mmap_event);
bool handle(const Reader::RecordCommType* comm);
bool handle(const Reader::RecordSwitchCpuWideType* context_switch);
bool handle(const Reader::RecordSwitchType* context_switch);
Expand Down
Loading

0 comments on commit add3923

Please sign in to comment.