[lttng-dev] [RFC PATCH lttng-ust] Make lttng-ust aware of shared object base addresses (issue #474)

Woegerer, Paul Paul_Woegerer at mentor.com
Tue Sep 10 11:30:52 EDT 2013


Hi Mathieu,

I recently created a high-level document to explain the prototype to my
colleagues. Maybe it is also useful to have that here on the mailinglist
(attached pdf).

Best,
Paul

On 08/27/2013 11:55 AM, Woegerer, Paul wrote:
> ...sorry, KMail was sending my draft without asking me first...
> 
> Hello,
> 
> To allow graphical trace viewers to provide features like address-to-symbol resolution or source lookup (address-to-lineinfo), information about the shared object base address mappings are required. These mappings are inherently time based and potentially change during the application runtime (dlopen, dlcose, dlopen, ...). It's even possible that at a later point in the program execution the same shared object gets mapped to a different base address (I saw that on ARM or PPC)
> 
> The patch set below provides an initial (prof-of-concept) implementation (based on the previous discussion on https://bugs.lttng.org/issues/474). It's a starting point for further discussions that will hopefully help me to provide an implementation that is good enough for upstream inclusion.
> 
> Applying the patch provides the following additional events for userspace tracing:
> 
> *) ust_baddr:push with TP_ARGS(void *, baddr, const char*, sopath, int64_t, size, int64_t, mtime)
> *) ust_baddr:pop with TP_ARGS(void *, baddr)
> 
> Tracepoints 'ust_baddr:push' and 'ust_baddr:pop' are emitted for every runtime object that makes use of tracing (i.e emits tracepoints/includes tracepoint.h). This is also true for shared objects that get loaded during application run time. Loading a shared object via dlopen will, for example, result in emitting:
> [14:22:07.841547445] ust_baddr:push: { cpu_id = 4 }, { baddr = 0x7F8D13DFD000, sopath = "/path/to/plugin1.so", size = 21968, mtime = 1377519722 }
> ..likewise sometime later a corresponding dlclose in the program will result in emitting:
> [14:22:07.841867307] ust_baddr:pop: { cpu_id = 4 }, { baddr = 0x7F8D13DFD000 }
> 
> *) ust_baddr:init with TP_ARGS(void *, baddr, const char*, sopath, int64_t, size, int64_t, mtime)
> 
> In contrast, ust_baddr:init tracepoints are only emitted when a userspace application gets a "session enabled" sent by the sessiond (necessary if tracing starts in the middle of an already running application). In this case all the currently loaded shared objects are iterated and the base address mappings are recored as ust_baddr:init events with the same payload structure as ust_baddr:push. E.g.
> 
> [15:20:32.763114409]  ust_baddr:init: { cpu_id = 1 }, { baddr = 0x7F5BAC083000, sopath = "/lib64/libc-2.17.so", size = 1992089, mtime = 1359709982 }
> [15:20:32.763118346]  ust_baddr:init: { cpu_id = 1 }, { baddr = 0x7F5BAEAF0000, sopath = "/lib64/ld-2.17.so", size = 163493, mtime = 1359709980 }
> [15:20:32.763125921]  ust_baddr:init: { cpu_id = 1 }, { baddr = 0x7F5BAAE7C000, sopath = "/other/currently/loaded/shared-object.so.0.0.0", size = 58359, mtime = 1377516019 }
> ... and so on for all other currently loaded shared objects
> 
> I have attached sample traces to demonstrate how this looks in practice.
> 
> 
> The known deficiencies of the current implementation are:
> 
> *) Currently there is no way to disable the mechanism. I don't like the idea of using an environment variable for that (doesn't allow to enable for already running applications). Having this controllable via lttng commands would be preferable. But maybe it's not a real issue. The events a comparably low-frequency.
> 
> *) For ust_baddr:init I had to hook into lttng_session_enable/ust_listener_thread. Ideally this hook should be provided as API functionality, controllable via lttng commands. For example:
> 
>    lttng on-session-enable shared_obj_state_dumper.so
> 
> The requirement of dumping state information on session_enable is generic enough that other instrumentations could also benefit from it (e.g. stack dump for liblttng-ust-cyg-profile/liblttng-ust-cyg-profile-fast).
> 
> --
> Looking forward to your comments,
> Paul
> 
> Paul Woegerer, SW Development Engineer
> Sourcery Analyzer <http://go.mentor.com/sourceryanalyzer>
> Mentor Graphics, Embedded Software Division
> 
> From 3fb50c1e8503963980f68223b4b810e792dfee66 Mon Sep 17 00:00:00 2001
> From: Paul Woegerer <paul_woegerer at mentor.com>
> Date: Thu, 22 Aug 2013 14:43:40 +0200
> Subject: [PATCH 1/2] Basic support for base address tracing
> 
> ---
>  Makefile.am                          |  1 +
>  configure.ac                         |  1 +
>  include/lttng/tracepoint.h           | 50 ++++++++++++++++++++++++
>  liblttng-ust-baddr/Makefile.am       | 17 ++++++++
>  liblttng-ust-baddr/lttng-ust-baddr.c | 74 +++++++++++++++++++++++++++++++++++
>  liblttng-ust-baddr/ust_baddr.h       | 76 ++++++++++++++++++++++++++++++++++++
>  6 files changed, 219 insertions(+)
>  create mode 100644 liblttng-ust-baddr/Makefile.am
>  create mode 100644 liblttng-ust-baddr/lttng-ust-baddr.c
>  create mode 100644 liblttng-ust-baddr/ust_baddr.h
> 
> diff --git a/Makefile.am b/Makefile.am
> index dc88c46..f9fcbf3 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -4,6 +4,7 @@ SUBDIRS = . include snprintf libringbuffer liblttng-ust-comm \
>  		liblttng-ust \
>  		liblttng-ust-ctl \
>  		liblttng-ust-fork \
> +		liblttng-ust-baddr \
>  		liblttng-ust-libc-wrapper \
>  		liblttng-ust-cyg-profile \
>  		tools \
> diff --git a/configure.ac b/configure.ac
> index 94f8182..a29ac48 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -282,6 +282,7 @@ AC_CONFIG_FILES([
>  	liblttng-ust/Makefile
>  	liblttng-ust-ctl/Makefile
>  	liblttng-ust-fork/Makefile
> +	liblttng-ust-baddr/Makefile
>  	liblttng-ust-java/Makefile
>  	liblttng-ust-libc-wrapper/Makefile
>  	liblttng-ust-cyg-profile/Makefile
> diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h
> index b3b01cc..462ab52 100644
> --- a/include/lttng/tracepoint.h
> +++ b/include/lttng/tracepoint.h
> @@ -219,6 +219,21 @@ struct tracepoint_dlopen {
>  
>  extern struct tracepoint_dlopen tracepoint_dlopen;
>  
> +#ifndef LTTNG_UST_BADDR_PROVIDER
> +/*
> + * shared object base address handling (callbacks). Hidden visibility:
> + * shared across objects in a module/main executable.
> + */
> +struct baddr_dlopen {
> +	void *liblttngust_handle;
> +
> +	int (*push_baddr)(void *ctor_addr);
> +	int (*pop_baddr)(void *ctor_addr);
> +};
> +
> +extern struct baddr_dlopen baddr_dlopen;
> +#endif
> +
>  #if defined(TRACEPOINT_DEFINE) || defined(TRACEPOINT_CREATE_PROBES)
>  
>  /*
> @@ -232,6 +247,10 @@ int __tracepoint_ptrs_registered
>  	__attribute__((weak, visibility("hidden")));
>  struct tracepoint_dlopen tracepoint_dlopen
>  	__attribute__((weak, visibility("hidden")));
> +#ifndef LTTNG_UST_BADDR_PROVIDER
> +struct baddr_dlopen baddr_dlopen
> +	__attribute__((weak, visibility("hidden")));
> +#endif
>  
>  #ifndef _LGPL_SOURCE
>  static inline void lttng_ust_notrace
> @@ -383,6 +402,24 @@ __tracepoints__ptrs_init(void)
>  				__stop___tracepoints_ptrs -
>  				__start___tracepoints_ptrs);
>  	}
> +#ifndef LTTNG_UST_BADDR_PROVIDER
> +	if (!baddr_dlopen.liblttngust_handle)
> +		baddr_dlopen.liblttngust_handle =
> +			dlopen("liblttng-ust-baddr.so.0", RTLD_NOW | RTLD_GLOBAL);
> +	if (!baddr_dlopen.liblttngust_handle)
> +		return;
> +	baddr_dlopen.push_baddr =
> +		URCU_FORCE_CAST(int (*)(void *),
> +				dlsym(baddr_dlopen.liblttngust_handle,
> +					"push_baddr"));
> +	baddr_dlopen.pop_baddr =
> +		URCU_FORCE_CAST(int (*)(void *),
> +				dlsym(baddr_dlopen.liblttngust_handle,
> +					"pop_baddr"));
> +	if (baddr_dlopen.push_baddr)
> +		baddr_dlopen.push_baddr(
> +				URCU_FORCE_CAST(void *, &__tracepoints__ptrs_init));
> +#endif
>  }
>  
>  static void lttng_ust_notrace __attribute__((destructor))
> @@ -394,6 +431,19 @@ __tracepoints__ptrs_destroy(void)
>  
>  	if (--__tracepoint_ptrs_registered)
>  		return;
> +#ifndef LTTNG_UST_BADDR_PROVIDER
> +	if (baddr_dlopen.pop_baddr)
> +		baddr_dlopen.pop_baddr(
> +				URCU_FORCE_CAST(void *, &__tracepoints__ptrs_init));
> +	if (baddr_dlopen.liblttngust_handle) {
> +		ret = dlclose(baddr_dlopen.liblttngust_handle);
> +		if (ret) {
> +			fprintf(stderr, "Error (%d) in dlclose\n", ret);
> +			abort();
> +		}
> +		memset(&baddr_dlopen, 0, sizeof(baddr_dlopen));
> +	}
> +#endif
>  	if (tracepoint_dlopen.tracepoint_unregister_lib)
>  		tracepoint_dlopen.tracepoint_unregister_lib(__start___tracepoints_ptrs);
>  	if (tracepoint_dlopen.liblttngust_handle && !__tracepoint_registered) {
> diff --git a/liblttng-ust-baddr/Makefile.am b/liblttng-ust-baddr/Makefile.am
> new file mode 100644
> index 0000000..6fdfda1
> --- /dev/null
> +++ b/liblttng-ust-baddr/Makefile.am
> @@ -0,0 +1,17 @@
> +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include
> +AM_CFLAGS = -fno-strict-aliasing
> +
> +lib_LTLIBRARIES = liblttng-ust-baddr.la
> +liblttng_ust_baddr_la_SOURCES = \
> +	lttng-ust-baddr.c \
> +	ust_baddr.h
> +liblttng_ust_baddr_la_LIBADD = \
> +	-L$(top_builddir)/liblttng-ust/.libs \
> +	-llttng-ust
> +
> +if LTTNG_UST_BUILD_WITH_LIBDL
> +liblttng_ust_baddr_la_LIBADD += -ldl
> +endif
> +if LTTNG_UST_BUILD_WITH_LIBC_DL
> +liblttng_ust_baddr_la_LIBADD += -lc
> +endif
> diff --git a/liblttng-ust-baddr/lttng-ust-baddr.c b/liblttng-ust-baddr/lttng-ust-baddr.c
> new file mode 100644
> index 0000000..bcfc9df
> --- /dev/null
> +++ b/liblttng-ust-baddr/lttng-ust-baddr.c
> @@ -0,0 +1,74 @@
> +/*
> + * Copyright (C) 2013  Paul Woegerer <paul_woegerer at mentor.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
> + */
> +
> +#define _GNU_SOURCE
> +#include <dlfcn.h>
> +
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <unistd.h>
> +
> +#include <errno.h>
> +#include <stdint.h>
> +#include <stddef.h>
> +#include <stdio.h>
> +#include "usterr.h"
> +
> +#define TRACEPOINT_DEFINE
> +#define TRACEPOINT_CREATE_PROBES
> +#include "ust_baddr.h"
> +
> +int push_baddr(void *ctor_addr)
> +{
> +	Dl_info info = { 0 };
> +	if (!dladdr(ctor_addr, &info))
> +	{
> +		ERR("dladdr failed for addr %p", ctor_addr);
> +		return 0;
> +	}
> +
> +	char resolved_path[PATH_MAX];
> +	if (!realpath(info.dli_fname, resolved_path))
> +	{
> +		ERR("could no resolve path %s", info.dli_fname);
> +		return 0;
> +	}
> +
> +	struct stat sostat;
> +	if (stat(resolved_path, &sostat))
> +	{
> +		ERR("could no access file status for %s", resolved_path);
> +		return 0;
> +	}
> +
> +	tracepoint(ust_baddr, push, info.dli_fbase, resolved_path, sostat.st_size, sostat.st_mtime);
> +	return 0;
> +}
> +
> +int pop_baddr(void *ctor_addr)
> +{
> +	Dl_info info = { 0 };
> +	if (!dladdr(ctor_addr, &info))
> +	{
> +		ERR("dladdr failed for addr %p", ctor_addr);
> +		return 0;
> +	}
> +
> +	tracepoint(ust_baddr, pop, info.dli_fbase);
> +	return 0;
> +}
> diff --git a/liblttng-ust-baddr/ust_baddr.h b/liblttng-ust-baddr/ust_baddr.h
> new file mode 100644
> index 0000000..635c678
> --- /dev/null
> +++ b/liblttng-ust-baddr/ust_baddr.h
> @@ -0,0 +1,76 @@
> +#undef TRACEPOINT_PROVIDER
> +#define TRACEPOINT_PROVIDER ust_baddr
> +
> +#if !defined(_TRACEPOINT_UST_BADDR_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
> +#define _TRACEPOINT_UST_BADDR_H
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/*
> + * Copyright (C) 2013  Paul Woegerer <paul_woegerer at mentor.com>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */
> +
> +#include <stdint.h>
> +#include <unistd.h>
> +
> +#define LTTNG_UST_BADDR_PROVIDER
> +#include <lttng/tracepoint.h>
> +
> +TRACEPOINT_EVENT(ust_baddr, init,
> +	TP_ARGS(void *, baddr, const char*, sopath, int64_t, size, int64_t, mtime),
> +	TP_FIELDS(
> +		ctf_integer_hex(void *, baddr, baddr)
> +		ctf_string(sopath, sopath)
> +		ctf_integer(int64_t, size, size)
> +		ctf_integer(int64_t, mtime, mtime)
> +	)
> +)
> +
> +TRACEPOINT_EVENT(ust_baddr, push,
> +	TP_ARGS(void *, baddr, const char*, sopath, int64_t, size, int64_t, mtime),
> +	TP_FIELDS(
> +		ctf_integer_hex(void *, baddr, baddr)
> +		ctf_string(sopath, sopath)
> +		ctf_integer(int64_t, size, size)
> +		ctf_integer(int64_t, mtime, mtime)
> +	)
> +)
> +
> +TRACEPOINT_EVENT(ust_baddr, pop,
> +	TP_ARGS(void *, baddr),
> +	TP_FIELDS(
> +		ctf_integer_hex(void *, baddr, baddr)
> +	)
> +)
> +
> +#endif /* _TRACEPOINT_UST_BADDR_H */
> +
> +#undef TRACEPOINT_INCLUDE
> +#define TRACEPOINT_INCLUDE "./ust_baddr.h"
> +
> +/* This part must be outside ifdef protection */
> +#include <lttng/tracepoint-event.h>
> +
> +#ifdef __cplusplus
> +}
> +#endif
> 
> 
> 
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
> 


-- 
Paul Woegerer, SW Development Engineer
Sourcery Analyzer <http://go.mentor.com/sourceryanalyzer>
Mentor Graphics, Embedded Software Division
-------------- next part --------------
A non-text attachment was scrubbed...
Name: base_address_recording_prototype.pdf
Type: application/pdf
Size: 29246 bytes
Desc: not available
URL: <http://lists.lttng.org/pipermail/lttng-dev/attachments/20130910/f66c62d3/attachment-0001.pdf>


More information about the lttng-dev mailing list