1 #include "../include/tracer.hpp"
2 #include "../include/util.hpp"
50 #ifdef CSDBG_WITH_PLUGIN
61 catch (std::exception &x) {
67 std::cerr <<
"plugin " << std::dec << i <<
": unidentified exception\r\n";
76 #ifdef CSDBG_WITH_FILTER
78 const i8 *path = proc->
ilookup(addr, base);
81 if (
likely(path != NULL) )
99 if (
likely(nm != NULL) ) {
100 #ifdef CSDBG_WITH_FILTER
125 catch (std::exception &x) {
161 #ifdef CSDBG_WITH_PLUGIN
172 catch (std::exception &x) {
178 std::cerr <<
"plugin " << std::dec << i <<
": unidentified exception\r\n";
186 #ifdef CSDBG_WITH_FILTER
188 const i8 *path = proc->
ilookup(addr, base);
191 if (
likely(path != NULL) )
209 if (
likely(nm != NULL) ) {
210 #ifdef CSDBG_WITH_FILTER
235 catch (std::exception x) {
279 catch (std::exception &x) {
327 throw exception(
"invalid argument: dso (=%p)", dso);
330 string path(dso->dlpi_name);
335 if (
unlikely(dso->dlpi_phnum == 0) )
340 if (
likely(arg != NULL) ) {
344 string *filt = filters->
at(i);
360 mem_addr_t base = dso->dlpi_addr + dso->dlpi_phdr[0].p_vaddr;
368 catch (std::exception &x) {
407 string cmd(
"addr2line -se %s 0x%x", path, addr);
410 pipe = popen(cmd.
cstr(),
"r");
413 "failed to open pipe for command '%s' (errno %d - %s)",
422 while (
likely(ch !=
'\n' && ch != EOF) ) {
428 throw exception(
"failed to read pipe for command '%s'", cmd.
cstr());
438 catch (std::exception &x) {
442 if (
likely(pipe != NULL) )
457 #ifdef CSDBG_WITH_PLUGIN
460 #ifdef CSDBG_WITH_FILTER
464 #ifdef CSDBG_WITH_PLUGIN
467 #ifdef CSDBG_WITH_FILTER
489 #ifdef CSDBG_WITH_PLUGIN
492 #ifdef CSDBG_WITH_FILTER
496 #ifdef CSDBG_WITH_PLUGIN
499 #ifdef CSDBG_WITH_FILTER
547 #ifdef CSDBG_WITH_PLUGIN
563 #ifdef CSDBG_WITH_PLUGIN
567 #ifdef CSDBG_WITH_FILTER
603 catch (std::exception &x) {
665 const i8 *nm = thr->
name();
668 dst.
append(
"at %s thread (0x%lx) {\r\n", nm, thr->
handle());
677 if (
likely (prev < thr->call_depth()) ) {
724 return const_cast<tracer&
> (*this);
727 const i8 *nm = thr->
name();
730 dst.
append(
"at %s thread (0x%lx) {\r\n", nm, thr->
handle());
739 if (
likely (prev < thr->call_depth()) ) {
752 return const_cast<tracer&
> (*this);
820 return const_cast<tracer&
> (*this);
830 #ifdef CSDBG_WITH_PLUGIN
859 retval =
new plugin(path, scope);
889 retval =
new plugin(bgn, end);
1018 #ifdef CSDBG_WITH_FILTER
1048 retval =
new filter(expr, icase, mode);
virtual string & append(const string &)
Append a string.
virtual u32 thread_count() const
Get the active thread count.
virtual plugin & begin(void *, void *) const
Begin instrumenting a function.
void __cyg_profile_func_enter(void *this_fn, void *call_site)
In code compiled with -finstrument-functions, g++ injects code to call this function at the beginning...
virtual T * at(u32) const
Get the node data pointer at a chain offset.
virtual const i8 * lookup(mem_addr_t)
Lookup an address to resolve a symbol.
virtual const plugin * get_plugin(const i8 *) const
Get a registered plugin module (DSO)
virtual tracer & destroy()
Release object resources.
static const i8 * exec_path()
Get the absolute path of the executable.
virtual thread & called(mem_addr_t, mem_addr_t, const i8 *)
Simulate a function call.
virtual u32 size() const
Get the chain size (node count)
virtual const i8 * path() const
Get the module file path.
virtual pthread_t handle() const
Get the thread handle.
void __cyg_profile_func_exit(void *this_fn, void *call_site)
In code compiled with -finstrument-functions, g++ injects code to call this function at the end of in...
char i8
8-bit signed integer
std::ostream & operator<<(std::ostream &, const std::exception &)
Stream insertion operator for std::exception objects.
virtual tracer & operator=(const tracer &)
Assignment operator.
virtual u32 filter_count() const
Get the number of registered filters.
Function instrumentation plugin.
static tracer * interface()
Get the interface object.
A tracer object is the default interface to libcsdbg for the instrumentation functions and for the li...
static const u16 g_minor
Library version minor.
static i32 on_dso_load(dl_phdr_info *, size_t, void *)
This is a dl_iterate_phdr (libdl) callback, called for each linked shared object. It loads the symbol...
virtual filter * get_filter(u32) const
Get a registered filter.
virtual thread * get_thread(pthread_t) const
Get a thread by ID.
static const i8 g_libs_env[]
DSO filtering shell variable.
chain< plugin > * m_plugins
Instrumentation plugins.
process * m_proc
Process handle.
#define likely(expr)
Offer a hint (positive) to the pipeline branch predictor.
static void dbg_warn(const i8 *,...)
Print a warning debug message on the standard error stream.
This class represents a program/library runtime function call.
virtual bool mode() const
Get the filter type.
virtual tracer * clone() const
Object virtual copy constructor.
virtual ~tracer()
Object destructor.
virtual thread & returned()
Simulate a function return.
static void lock()
Lock the global access mutex.
virtual bool apply(const i8 *) const
Apply the filter to a function signature or a module absolute path.
This class represents a thread of execution in the instrumented process.
virtual const i8 * msg() const
Get the exception message.
static void unlock()
Unlock the global access mutex.
virtual tracer & trace(string &)
Create an exception stack trace using the simulated call stack of the current thread. The trace is appended to a string and the simulated stack is unwinded.
virtual filter * add_filter(const i8 *, bool, bool=true)
Register a filter.
virtual i32 cmp(const string &, bool=false) const
Compare to another string.
virtual thread & unwind()
Unwind the simulated call stack to meet the real call stack.
static void dbg_error(const i8 *,...)
Print an error debug message on the standard error stream.
tracer()
Object default constructor.
static void on_lib_load() __attribute((constructor))
Library constructor.
virtual u32 call_depth() const
Get the size (call depth) of the simulated call stack.
virtual i32 lag() const
Get the size (call depth) of the simulated call stack with respect to the real call stack...
virtual tracer & unwind()
Unwind the simulated call stack of the current thread.
virtual const i8 * cstr() const
Get the C-string equivalent.
virtual tracer & remove_plugin(const i8 *)
Unregister a plugin module (DSO)
void(* modsym_t)(void *, void *)
Plugin callback.
virtual mem_addr_t site() const
Get the call site address.
This class represents a process, its entire namespace and thread group.
virtual bool match(const string &, bool=false) const
Match against a POSIX extended regular expression.
virtual const plugin * add_plugin(const i8 *, const i8 *=NULL)
Register a plugin module (DSO)
virtual mem_addr_t addr() const
Get the symbol address.
virtual process * clone() const
Object virtual copy constructor.
virtual u32 plugin_count() const
Get the number of registered plugins.
virtual process & add_module(const i8 *, mem_addr_t)
Add a symbol table to the namespace. The symbol table is loaded from a non stripped objective code fi...
virtual const i8 * name() const
Get the symbol name.
unsigned int u32
32-bit unsigned integer
static string & addr2line(string &, const i8 *, mem_addr_t)
Given an address in an objective code file, extract from the gdb-related debug information, the equivalent source code file name and line and append it to a string buffer.
int i32
32-bit signed integer
static chain< string > * getenv(const i8 *)
Parse a shell (environment) variable to its components.
virtual const i8 * ilookup(mem_addr_t, mem_addr_t &) const
Inverse lookup. Find the module (executable or DSO library) that defines a symbol and return its path...
virtual tracer & remove_filter(u32)
Unregister a filter.
virtual u32 length() const
Get the character count.
virtual const call * backtrace(u32) const
Peek at the simulated call stack.
virtual tracer & dump(string &) const
Create multiple stack traces using the simulated call stack of each thread. The traces are appended t...
static void header(std::ostream &, const i8 *)
Print a tagged message header on an output stream.
virtual const i8 * name() const
Get the thread name.
chain< filter > * m_filters
Instrumentation filters.
virtual process * proc() const
Get the process handle.
unsigned long long mem_addr_t
64-bit memory address
This class is a throwable with a textual description of an error.
virtual thread * current_thread()
Get the currently executing thread.
virtual u32 module_count() const
Get the number of modules.
#define unlikely(expr)
Offer a hint (negative) to the pipeline branch predictor.
static void dbg_info(const i8 *,...)
Print an informational debug message on the standard error stream.
virtual plugin & end(void *, void *) const
End a function instrumentation.
static void on_lib_unload() __attribute((destructor))
Library destructor.
static const u16 g_major
Library version major.
#define __D_ASSERT(x)
Assertion macro.
static tracer * m_iface
Interface object.