All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: instrumenting shared library
@ 2014-04-03 16:05 Thibault, Daniel
  0 siblings, 0 replies; 13+ messages in thread
From: Thibault, Daniel @ 2014-04-03 16:05 UTC (permalink / raw)
  To: lttng-dev; +Cc: Anand Neeli

----------------------------------------------------------------------
Date: Thu, 3 Apr 2014 16:55:38 +0530
From: Anand Neeli <anand.neeli@gmail.com>
To: "lttng-dev@lists.lttng.org" <lttng-dev@lists.lttng.org>

> I have a library which is instrumented and tracepoints are added. And I
> have 2 binary's (or daemons) which try to include this library. (one binary
> has instrumented code with tracepoints and other binary doesn't use
> tracing)
>
> I found that i need to instrument the daemon which includes the
> instrumented library for the code to compile.
>
> Can't I have a daemon (without tracing functionality) which can include an
> instrumented library (i don't want to use tracing functionality in this
> case)
>
> I'm only able to build if both library and daemon which includes it are
> instrumented.
>
> Can anyone please give me more details on how to do this?
> This is useful for huge code bases where you can selectively add tracing
> support to few libraries or daemons.
>
> Anand Neeli

   It can be done.  An uninstrumented app can rely on an instrumented shared object; whether the latter produces lttng events then depends on whether or not the tracepoint provider shared object is loaded when the app is invoked (using LD_PRELOAD).

   Here is sample_neeli.c:
#####
#include <stdio.h> //For printf
#include <unistd.h>

#include "cobject.h"
int main(int argc, char **argv)
{
	int i = 0;
	char themessage[20]; //Can hold up to "Hello World 9999999\0"

	fprintf(stderr, "sample_neeli starting\n");
	for (i = 0; i < 10000; i++) {
		//We either prepare themessage in this module, or rely on an
		//external shared object
		cobject_message(themessage, i);
		usleep(1);
	}
	fprintf(stderr, "sample_neeli done\n");
	return 0;
}
#####
cobject.c:
#####
#include <stdio.h> //For printf
#include <unistd.h>

#include "tp.h"

void cobject_message(char *themessage, int i)
{
	tracepoint(sample_component, event, "cobject_message");
	sprintf(themessage, "CObject %u", i);
}
#####
cobject.h:
#####
extern void cobject_message(char *themessage, int i);
#####
The tracepoint provider code should be easy to guess.

The relevant Makefile fragments:
#####
CC = gcc
LIBDL = -ldl # On Linux
#LIBDL = -lc # On BSD
LOCAL_CPPFLAGS += -I. $(AM_CPPFLAGS)
LDFLAGS += -L/usr/local/lib $(AM_LDFLAGS)
SOFLAGS = -fPIC
TP_DEFINE = -D TRACEPOINT_DEFINE
TP_DEFINE_DYNAMIC = $(TP_DEFINE) -D TRACEPOINT_PROBE_DYNAMIC_LINKAGE
SOVERSION_MAJOR = 1
SOVERSION_MINOR = 0

libcobject.so: libcobject.o
	@echo "~~~~~~Packaging $@:"
	$(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR) -Wl,-no-as-needed \
	   -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $^
	ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $@.$(SOVERSION_MAJOR)
	ln -sf $@.$(SOVERSION_MAJOR) $@

libcobject.o: cobject.c cobject.h tp.h
	@echo "~~~~~~Compiling $@:"
	$(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(SOFLAGS) $(TP_DEFINE_DYNAMIC) \
	   -c -o $@ $<

neeli_dynamic_lib:: neeli_dynamic_lib.o
	@echo "~~~~~~Linking sample_$@:"
	$(CC) -Wl,-no-as-needed -o $@ -L. -lcobject $^ $(LDFLAGS) \
	   $(LIBDL) -Wl,-rpath,'$$ORIGIN',--enable-new-dtags
	@echo "   Use '[LD_PRELOAD=./libtp.so] ./$@' to run $@"

neeli_dynamic_lib.o: sample_neeli.c cobject.h
	@echo "~~~~~~Compiling $@:"
	$(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) -c -o $@ $<
#####

   Running './neeli_dynamic_lib' yields no events.  Running 'LD_PRELOAD=./libtp.so ./neeli_dynamic_lib' yields the libcobject.so events.

Daniel U. Thibault
Protection des systèmes et contremesures (PSC) | Systems Protection & Countermeasures (SPC)
Cyber sécurité pour les missions essentielles (CME) | Mission Critical Cyber Security (MCCS)
R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D Canada - Valcartier (DRDC Valcartier)
2459 route de la Bravoure
Québec QC  G3J 1X5
CANADA
Vox : (418) 844-4000 x4245
Fax : (418) 844-4538
NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ>
Gouvernement du Canada | Government of Canada
<http://www.valcartier.drdc-rddc.gc.ca/>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found]             ` <CAM5kDqykNCO_XVjg8bOzDLTZ06Cja2UwdS4ZkHLpJrs9GR_sqw@mail.gmail.com>
@ 2014-04-07 15:27               ` Thibault, Daniel
  0 siblings, 0 replies; 13+ messages in thread
From: Thibault, Daniel @ 2014-04-07 15:27 UTC (permalink / raw)
  To: Anand Neeli; +Cc: lttng-dev


[-- Attachment #1.1: Type: text/plain, Size: 4085 bytes --]

De : Anand Neeli [mailto:anand.neeli@gmail.com]
Envoyé : 7 avril 2014 10:37

> - It doesn't matter if the tracepoints are static or dynamically loaded with the app. Once there is a change in tracepoints the app should be reloaded (even though not compiled). Even though the tracepoints can be shared, but changing tracepoints we would need to restart all the app's which share the tracepoints.
(Just trying to make a statement on pros and cons here)

   Not quite true.  If the tracepoints are statically included in the app, then the app must be recompiled and relinked whenever the tracepoints change.  Example:

static: static.o tp.o
            @echo "~~~~~~Linking sample_$@:"
            $(CC) -o sample_$@ $^ $(LDFLAGS) $(LIBDL) $(LIBUST)
            @echo "   Use './sample_$@' to run sample_$@"

static.o: sample.c tp.h
            @echo "~~~~~~Compiling $@:"
            $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE) -c -o $@ $<

tp.o: tp.c tp.h
            @echo "~~~~~~Compiling $@:"
            $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) -c -o $@ $<

   Every time you change tp.h, you must recompile tp.o and static.o and relink both into a new sample_static executable image.  If you keep the tracepoint() signatures unchanged, then you may get away with not recompiling static.o-but you must still relink.

   At the other extreme, if the app explicitly loads the tracepoint provider using dlopen, then one could conceivably send a message to all apps to dlclose the tracepoint provider shared object and dlopen a replacement one (if such an API has been programmed in).  The apps wouldn't need to stop running at all.  Of course this supposes the tracepoint() signatures do not change.  (To avoid confusing babeltrace, the traces must be collected using the buffers-pid channel option and the changeover must not occur within the same one-second time window)

> - * Does static or dynamic inclusion make difference(in terms of performance) if someone always want to run in tracing mode??

   The difference will be slight: using a dynamic link, the linker must do a little extra work when loading the tracepoint provider shared object along with the application's binary image, just because it needs to find it elsewhere. So you can expect app startup to be a little longer the first time. If the app is using a tracepoint provider shared object which happens to be already used by other running apps, the startup time actually becomes shorter because the tracepoint provider shared object is already in memory.

   Once the app is running, there should be no difference at all in performance.

> Now let me put some light on how someone would like to use lttngin huge codebases. (this is my personal opinion)
> - Normally tracepoints are made per component/daemon. And not shared across daemons/components.
> - Tracing should always be running. It should never be switched off. (unless the application is not mission critical)
> - I'm planning to always run memory(snapshot) tracing with some fixed size buffer, which can capture last n-events or n-bytes
> - Above memory tracing users can create another tracing session and dump traces to files if needed.(with their own filters and context in enable-event)

   Sounds like a plan!

> Thanks again for spending your time on these queries.
> -Anand Neeli
Daniel U. Thibault
Protection des systèmes et contremesures (PSC) | Systems Protection & Countermeasures (SPC)
Cyber sécurité pour les missions essentielles (CME) | Mission Critical Cyber Security (MCCS)
R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D Canada - Valcartier (DRDC Valcartier)
2459 route de la Bravoure
Québec QC  G3J 1X5
CANADA
Vox : (418) 844-4000 x4245
Fax : (418) 844-4538
NAC : 918V QSDJ<--ESFSECEV-TY3011--------------------------------> <http://www.travelgis.com/map.asp?addr=918V%20QSDJ<--ESFSECEV-TY3011-------------------------------->>
Gouvernement du Canada | Government of Canada
<http://www.valcartier.drdc-rddc.gc.ca/<--ESFSECEV-TY3011--------------------->>

[-- Attachment #1.2: Type: text/html, Size: 13431 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found]           ` <48CF5AC71E61DB46B70D0F388054EFFD35993659@VAL-E-02.valcartier.drdc-rddc.gc.ca>
@ 2014-04-07 14:37             ` Anand Neeli
       [not found]             ` <CAM5kDqykNCO_XVjg8bOzDLTZ06Cja2UwdS4ZkHLpJrs9GR_sqw@mail.gmail.com>
  1 sibling, 0 replies; 13+ messages in thread
From: Anand Neeli @ 2014-04-07 14:37 UTC (permalink / raw)
  To: Thibault, Daniel; +Cc: lttng-dev


[-- Attachment #1.1: Type: text/plain, Size: 4685 bytes --]

Hi Daniel,
I had spend sometime and compiled
Non-Instrumented app with static instrumented library
Non-Instrumented app with dynamic instrumented library
Instrumented app with static instrumented library
Instrumented app with dynamic instrumented library

Thanks for your help.

- It doest matter if the tracepoints are static or dynamically loaded with
the app. Once there is a change in tracepoints the app should be reloaded
(even though not compiled). Even though the tracepoints can be shared, but
changing tracepoints we would need to restart all the app's which share the
tracepoints.
(Just trying to make a statement on procs and cons here)


- * Does static or dynamic inclusion make difference(in terms of
performance) if someone always want to run in tracing mode??

Now let me put some light on how someone would like to use lttngin huge
codebases. (this is my personal opinion)
- Normally tracepoints are made per component/daemon. And not shared across
daemons/components.
- Tracing should always be running. It should never be switched off.
(unless the application is not mission critical)
- I'm planning to always run memory(snapshot) tracing with some fixed size
buffer, which can capture last n-events or n-bytes
- Above memory tracing users can create another tracing session and dump
traces to files if needed.(with their own filters and context in
enable-event)


Thanks again for spending your time on these queries.
-Anand Neeli





On Mon, Apr 7, 2014 at 6:53 PM, Thibault, Daniel <
Daniel.Thibault@drdc-rddc.gc.ca> wrote:

>     You need to define your concept of operations carefully.
>
>
>
>    An instrumented application can include its tracepoint provider in
> several ways.
>
>
>
>    One is static inclusion: the application will always be traceable, but
> any change to the tracepoints requires a recompilation of the app, plus the
> tracepoint events it produces should not be shared with any other
> application (I say 'should' because they can, but it's a bad idea to do so).
>
>
>
>    Another is dynamic inclusion with static awareness: the application
> will always be traceable, but will refuse to run if does not find the
> tracepoint provider library (typically provided by LD_PRELOAD). The
> tracepoint events can be shared with other applications.
>
>
>
>    The third is dynamic inclusion without static awareness: this operates
> as the previous, except that when the app does not find the tracepoint
> provider it runs normally but is not traceable. Turning off traceability in
> this way does give you a very small gain in performance.
>
>
>
>    The last is fully dynamic inclusion: the app is responsible for its own
> traceability because it loads and unloads its tracepoint provider itself
> (using dlopen and dlclose). This is more intrusive as the app's code needs
> to include this aspect, possibly reflected in its user interface (by a menu
> item, for instance). On the good side it does mean you get the slight
> performance gain on demand.
>
>
>
>    If the very slight loss of performance due to tracing doesn't bother
> you, your best bet is probably dynamic inclusion without static awareness
> (third option). LTTng can then be configured to capture your app's traces
> using an on-disc circular buffer (see the tracefile-size and
> tracefile-count options of the enable-channel command). When your app
> misbehaves, you suspend it, suspend tracing (lttng stop), and copy the
> trace to a working directory. You can then babeltrace it or use the Eclipse
> LTTng views to analyse the trace. This works even better if your app is run
> multiple times, because then LTTng will capture each running separately
> (see the buffers-pid and buffers-uid options of the enable-channel
> command). You only need to remember to flush the older traces once you've
> decided you don't need them anymore.
>
>
>
> Daniel U. Thibault
> Protection des systèmes et contremesures (PSC) | Systems Protection &
> Countermeasures (SPC)
> Cyber sécurité pour les missions essentielles (CME) | Mission Critical
> Cyber Security (MCCS)
> R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D
> Canada - Valcartier (DRDC Valcartier)
> 2459 route de la Bravoure
> Québec QC  G3J 1X5
> CANADA
> Vox : (418) 844-4000 x4245
> Fax : (418) 844-4538
> NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ> <*http://www.travelgis.com/map.asp?addr=918V%20QSDJ
> <http://www.travelgis.com/map.asp?addr=918V%20QSDJ>*>
> Gouvernement du Canada | Government of Canada
> <http://www.valcartier.drdc-rddc.gc.ca/>
>

[-- Attachment #1.2: Type: text/html, Size: 9081 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found]         ` <CAM5kDqySXuNqYcdjy+kgs-h5cDdiQSioumUX449Gfrcgg+HUbw@mail.gmail.com>
  2014-04-05 12:14           ` Lingyu Zhu
@ 2014-04-07 13:23           ` Thibault, Daniel
       [not found]           ` <48CF5AC71E61DB46B70D0F388054EFFD35993659@VAL-E-02.valcartier.drdc-rddc.gc.ca>
  2 siblings, 0 replies; 13+ messages in thread
From: Thibault, Daniel @ 2014-04-07 13:23 UTC (permalink / raw)
  To: Anand Neeli, Lingyu Zhu; +Cc: lttng-dev


[-- Attachment #1.1: Type: text/plain, Size: 2857 bytes --]

   You need to define your concept of operations carefully.

   An instrumented application can include its tracepoint provider in several ways.

   One is static inclusion: the application will always be traceable, but any change to the tracepoints requires a recompilation of the app, plus the tracepoint events it produces should not be shared with any other application (I say 'should' because they can, but it's a bad idea to do so).

   Another is dynamic inclusion with static awareness: the application will always be traceable, but will refuse to run if does not find the tracepoint provider library (typically provided by LD_PRELOAD). The tracepoint events can be shared with other applications.

   The third is dynamic inclusion without static awareness: this operates as the previous, except that when the app does not find the tracepoint provider it runs normally but is not traceable. Turning off traceability in this way does give you a very small gain in performance.

   The last is fully dynamic inclusion: the app is responsible for its own traceability because it loads and unloads its tracepoint provider itself (using dlopen and dlclose). This is more intrusive as the app's code needs to include this aspect, possibly reflected in its user interface (by a menu item, for instance). On the good side it does mean you get the slight performance gain on demand.

   If the very slight loss of performance due to tracing doesn't bother you, your best bet is probably dynamic inclusion without static awareness (third option). LTTng can then be configured to capture your app's traces using an on-disc circular buffer (see the tracefile-size and tracefile-count options of the enable-channel command). When your app misbehaves, you suspend it, suspend tracing (lttng stop), and copy the trace to a working directory. You can then babeltrace it or use the Eclipse LTTng views to analyse the trace. This works even better if your app is run multiple times, because then LTTng will capture each running separately (see the buffers-pid and buffers-uid options of the enable-channel command). You only need to remember to flush the older traces once you've decided you don't need them anymore.

Daniel U. Thibault
Protection des systèmes et contremesures (PSC) | Systems Protection & Countermeasures (SPC)
Cyber sécurité pour les missions essentielles (CME) | Mission Critical Cyber Security (MCCS)
R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D Canada - Valcartier (DRDC Valcartier)
2459 route de la Bravoure
Québec QC  G3J 1X5
CANADA
Vox : (418) 844-4000 x4245
Fax : (418) 844-4538
NAC : 918V QSDJ<http://www.travelgis.com/map.asp?addr=918V%20QSDJ> <http://www.travelgis.com/map.asp?addr=918V%20QSDJ>
Gouvernement du Canada | Government of Canada
<http://www.valcartier.drdc-rddc.gc.ca/>

[-- Attachment #1.2: Type: text/html, Size: 9286 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found]         ` <CAM5kDqySXuNqYcdjy+kgs-h5cDdiQSioumUX449Gfrcgg+HUbw@mail.gmail.com>
@ 2014-04-05 12:14           ` Lingyu Zhu
  2014-04-07 13:23           ` Thibault, Daniel
       [not found]           ` <48CF5AC71E61DB46B70D0F388054EFFD35993659@VAL-E-02.valcartier.drdc-rddc.gc.ca>
  2 siblings, 0 replies; 13+ messages in thread
From: Lingyu Zhu @ 2014-04-05 12:14 UTC (permalink / raw)
  To: Anand Neeli; +Cc: lttng-dev


[-- Attachment #1.1: Type: text/plain, Size: 17600 bytes --]

Hi Andnd Neeli,
if you omit TRACEPOINT_PROBE_DYNAMIC_LINKAGE , you don't have to LD_PRELOAD
the share tp library. It acts just like statically linked app. and you can
use lttng enable-event command to enable the event tracing when your app
get something wrong without reloading(restarting)  your app.

'tracing mode' is not an official term, I just made it up :-) . It involves
to the UST internal implementation. You can consider app is not in tracing
mode when you have not LD_PRELOAD tp library, and it's in tracing mode if
you LD_PRELOAD.   Of course, the app is always in tracing mode when you
statically link tp library, or you omit TRACEPOINT_PROBE_DYNAMIC_LINKAGE..


On Sat, Apr 5, 2014 at 5:56 PM, Anand Neeli <anand.neeli@gmail.com> wrote:

> Hi Lingyu Zhu,
> what do you mean by switching on or off tracing mode?
> will i be able to trace or not trace without reloading the app?
> If i dont use LD_PRELOAD with tracepoint it never traces. and for tracing
> to start i should reload the app with ld_preload tracepoints.
> We would like to see the traces only when there is a problem in the app.
> And by reloading the app to enable traces we would loose all the app
> context (in problem state).
>
> Hope i'm not missing anything here.
>
> Thanks,
> Anand Neeli
>
>
>
> On Sat, Apr 5, 2014 at 12:14 PM, Lingyu Zhu <lynuszhu@gmail.com> wrote:
>
>> If you omit defining the macro TRACEPOINT_PROBE_DYNAMIC_LINKAGE in your
>> library which you want to trace, your library will depend on the trace
>> provider shared library. And you will not bother LD_PRELOAD your tracepoint
>> provider library before launching app.
>>
>> However, by doing so you will lose control over switching on or off
>> 'tracing mode': whenever your code is called,your tracepoint will try to
>> register and tracepoint() might have more overhead if you build your
>> library like that, whereas your tracepoint won't register and tracepoint()
>> macro just cost a simple branch if you do so by normal way and skip
>> LD_PRELOAD.
>>
>>
>> On Sat, Apr 5, 2014 at 4:16 AM, Anand Neeli <anand.neeli@gmail.com>wrote:
>>
>>> Hi Daniel,
>>> Thanks for your detailed mail.
>>> I will spend time with my code and get back if i have more queries.
>>>
>>> What i'm looking at it is: adding lttng infra in our code base. I'm
>>> looking for a solution where most of the lttng build and launch parts are
>>> abstracted to the end app/library developer.
>>> That is the reason why i'm not in favor of having LD_PRELOAD while
>>> launching an app. This would need the app developer to check if included
>>> libraries has tracing support and add .so appropriately to LD_PRELOAD
>>> (which needs more education to developer on lttng and included libraries)
>>> If we can launch app(with or without instrumented library) normally and
>>> limit the complexity of linking to makefile it will be great.
>>>
>>> Please keep me posted if you have any more thoughts on this.
>>> Also, can you please send me the users guide.
>>>
>>> Thanks,
>>> Anand Neeli
>>>
>>>
>>> On Fri, Apr 4, 2014 at 8:13 PM, Thibault, Daniel <
>>> Daniel.Thibault@drdc-rddc.gc.ca> wrote:
>>>
>>>>  *De :* Anand Neeli [mailto:anand.neeli@gmail.com]
>>>> *Envoyé :* 4 avril 2014 01:45
>>>>
>>>>   > Thanks for your reply.
>>>>
>>>> > Sorry for my ignorance but how are you generating libtp.so in your
>>>> example?
>>>>
>>>>
>>>>
>>>> Non-boilerplate parts are in red.
>>>>
>>>>
>>>>
>>>> tp.c:
>>>>
>>>> #####
>>>>
>>>> /*
>>>>
>>>> * Defining macro creates the code objects of the traceprobes.
>>>>
>>>> * Must be done only once per file (this #define controls tracepoint.h
>>>> and
>>>>
>>>> * tracepoint-event.h).
>>>>
>>>> */
>>>>
>>>> #define TRACEPOINT_CREATE_PROBES
>>>>
>>>> /*
>>>>
>>>> * The header containing our TRACEPOINT_EVENTs.
>>>>
>>>> */
>>>>
>>>> #include "tp.h"
>>>>
>>>> #####
>>>>
>>>> tp.h:
>>>> #####
>>>> #undef TRACEPOINT_PROVIDER
>>>>
>>>> #define TRACEPOINT_PROVIDER sample_component
>>>>
>>>> /*
>>>>
>>>> * include file (this files's name)
>>>>
>>>> */
>>>>
>>>> #undef TRACEPOINT_INCLUDE
>>>>
>>>> #define TRACEPOINT_INCLUDE "./tp.h"
>>>>
>>>> /*
>>>>
>>>> * Add this precompiler conditional to ensure the tracepoint event
>>>> generation
>>>>
>>>> * can include this file more than once.
>>>>
>>>> */
>>>>
>>>> #if !defined(_SAMPLE_COMPONENT_PROVIDER_H) ||
>>>> defined(TRACEPOINT_HEADER_MULTI_READ)
>>>>
>>>> #define _SAMPLE_COMPONENT_PROVIDER_H
>>>>
>>>> /*
>>>>
>>>> * Add this to allow programs to call "tracepoint(...)".
>>>>
>>>> * This #include must not be within an extern "C" block; if it is,
>>>>
>>>> * C++ instrumentation will fail when SystemTap is also installed.
>>>>
>>>> * (This may have been fixed since I wrote this)
>>>>
>>>> */
>>>>
>>>> #include <lttng/tracepoint.h>
>>>>
>>>> /*
>>>>
>>>> * Add this macro and its matching element to make sure the program
>>>>
>>>> * works in C++.
>>>>
>>>> */
>>>>
>>>> #ifdef __cplusplus
>>>>
>>>> extern "C" {
>>>>
>>>> #endif /* __cplusplus */
>>>>
>>>>
>>>>
>>>> /*
>>>>
>>>> * The following tracepoint event writes a message (C string) into the
>>>>
>>>> * field "message" of the trace event "event" in the provider
>>>>
>>>> * "sample_component" in other words:
>>>>
>>>> *
>>>>
>>>> *    sample_component:event:message = text.
>>>>
>>>> */
>>>>
>>>> TRACEPOINT_EVENT(
>>>>
>>>>             /*
>>>>
>>>>             * provider name, not a variable but a string starting with
>>>> a letter
>>>>
>>>>             * and containing either letters, numbers or underscores.
>>>>
>>>>             * Needs to be the same as TRACEPOINT_PROVIDER
>>>>
>>>>             */
>>>>
>>>>             sample_component,
>>>>
>>>>             /*
>>>>
>>>>             * tracepoint name, same format as sample provider. Does not
>>>> need to be
>>>>
>>>>             * declared before. in this case the name is "event"
>>>>
>>>>             */
>>>>
>>>>             event,
>>>>
>>>>             /*
>>>>
>>>>             * TP_ARGS macro contains the arguments passed for the
>>>> tracepoint.
>>>>
>>>>             * It is in the following format:
>>>>
>>>>             *                     TP_ARGS( type1, name1, type2, name2,
>>>> ... type10, name10)
>>>>
>>>>             * where there can be from zero to ten elements.
>>>>
>>>>             * "typeN" is the datatype, such as int, struct or double **.
>>>>
>>>>             * "name" is the variable name (in "int myInt" the name
>>>> would be "myInt")
>>>>
>>>>             *                     TP_ARGS() is valid (no arguments)
>>>>
>>>>             *                     TP_ARGS( void ) is valid too
>>>>
>>>>             */
>>>>
>>>>             TP_ARGS(const char *, text),
>>>>
>>>>             /*
>>>>
>>>>             * TP_FIELDS describes how to write the fields of the trace
>>>> event.
>>>>
>>>>             * You can use the args here
>>>>
>>>>             */
>>>>
>>>>             TP_FIELDS(
>>>>
>>>>             /*
>>>>
>>>>             * The ctf_string macro takes a C string and writes it into
>>>> a field
>>>>
>>>>             * named "message"
>>>>
>>>>             */
>>>>
>>>>                         ctf_string(message, text)
>>>>
>>>>             )
>>>>
>>>> )
>>>>
>>>> /*
>>>>
>>>> * Trace loglevel, shows the level of the trace event. It can be
>>>> TRACE_EMERG,
>>>>
>>>> * TRACE_ALERT, TRACE_CRIT, TRACE_ERR, TRACE_WARNING, TRACE_INFO, etc.
>>>>
>>>> * If this is not set, TRACE_DEFAULT is assumed.
>>>>
>>>> * The first two arguments identify the tracepoint.
>>>>
>>>> * See details in <lttng/tracepoint.h> line 347
>>>>
>>>> */
>>>>
>>>> TRACEPOINT_LOGLEVEL(
>>>>
>>>>        /*
>>>>
>>>>         * The provider name, must be the same as the provider name in
>>>> the
>>>>
>>>>         * TRACEPOINT_EVENT and as TRACEPOINT_PROVIDER above.
>>>>
>>>>         */
>>>>
>>>>             sample_component,
>>>>
>>>>        /*
>>>>
>>>>         * The tracepoint name, must be the same as the tracepoint name
>>>> in the
>>>>
>>>>         * TRACEPOINT_EVENT
>>>>
>>>>         */
>>>>
>>>>             event,
>>>>
>>>>        /*
>>>>
>>>>         * The tracepoint loglevel. WARNING: Some levels are abbreviated
>>>> and
>>>>
>>>>         * others are not, please see <lttng/tracepoint.h>
>>>>
>>>>         */
>>>>
>>>>             TRACE_WARNING
>>>>
>>>> )
>>>>
>>>>  (more tracepoints…)
>>>>
>>>>
>>>>
>>>> /*
>>>>
>>>> * Add this macro and its matching element to make sure the program
>>>>
>>>> * works in C++.
>>>>
>>>> */
>>>>
>>>> #ifdef __cplusplus
>>>>
>>>> }
>>>>
>>>> #endif /* __cplusplus */
>>>>
>>>> /*
>>>>
>>>> * Add this after defining the tracepoint events to expand the macros.
>>>>
>>>> */
>>>>
>>>> #include <lttng/tracepoint-event.h>
>>>>
>>>> #endif /* _SAMPLE_COMPONENT_PROVIDER_H */
>>>>
>>>> #####
>>>>
>>>> The relevant Makefile fragments:
>>>> #####
>>>> CC = gcc
>>>> LIBUST = -llttng-ust
>>>>
>>>> LOCAL_CPPFLAGS += -I. $(AM_CPPFLAGS)
>>>> LDFLAGS += -L/usr/local/lib $(AM_LDFLAGS)
>>>> SOFLAGS = -fPIC
>>>> SOVERSION_MAJOR = 1
>>>> SOVERSION_MINOR = 0
>>>>
>>>> libtp.so: libtp.o
>>>>
>>>>             @echo "~~~~~~Packaging $@:"
>>>>
>>>>             $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR)
>>>> -Wl,-no-as-needed \
>>>>
>>>>                -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS)
>>>> $(LIBUST) $<
>>>>
>>>>             ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
>>>> $@.$(SOVERSION_MAJOR)
>>>>
>>>>             ln -sf $@.$(SOVERSION_MAJOR) $@
>>>>
>>>>
>>>>
>>>> libtp.o: tp.c tp.h
>>>>
>>>>             @echo "~~~~~~Compiling $@:"
>>>>
>>>>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(SOFLAGS) -c -o $@ $<
>>>>
>>>>
>>>> > 1) Also will this solution scale if my binary depends on lots
>>>> of libraries which are instrumented?
>>>>
>>>>
>>>>
>>>> Sure.  I’d expect linear scaling.  Each library, upon being loaded,
>>>> looks for its tracepoint provider and turns its tracepoints off if they’re
>>>> not found.
>>>>
>>>>
>>>>
>>>> > 2) i'm fine with linking statically, can we avoid LD_PRELOAD?
>>>>
>>>>
>>>>
>>>> Besides the LD_PRELOAD technique, you could also use LD_LIBRARY_PATH,
>>>> but that works only if the application statically includes the tracepoint
>>>> provider (I suppose it would likewise work for an instrumented shared
>>>> object only if it statically includes the tracepoint provider).
>>>>
>>>>
>>>>
>>>> You could also add "-Wl,-rpath,'$$ORIGIN'" to the linker call to add an
>>>> RPATH tag to the application (or shared object).  This makes it look for
>>>> its dependencies in its starting directory ($ORIGIN).  RPATH is, unlike
>>>> RUNPATH, applicable to libraries as well: a library with an RPATH tag will
>>>> look there for its dependencies; failing its own RPATH, it will use its
>>>> executable's RPATH.
>>>>
>>>>
>>>>
>>>> Finally, you can dynamically include the tracepoint provider (libtp) as
>>>> a dependency.  The application (sample_static_aware) is then statically
>>>> aware of libtp and won't run without it.  The application (sample_dynamic)
>>>> can alternately dynamically include the tracepoint provider *without*static awareness.  Here’s how it’s done:
>>>>
>>>>
>>>>
>>>> LIBDL = -ldl # On Linux
>>>>
>>>> #LIBDL = -lc # On BSD
>>>>
>>>> TP_DEFINE = -D TRACEPOINT_DEFINE
>>>>
>>>> TP_DEFINE_DYNAMIC = $(TP_DEFINE) -D TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>>>>
>>>>
>>>>
>>>> #(the inclusion of a libtp NEEDED tag requires "-no-as-needed -ltp").
>>>>
>>>> #Note that "-L. -ltp", when used, should appear before $(LDFLAGS)
>>>> $(LIBDL).
>>>>
>>>> static_aware: static.o libtp.so
>>>>
>>>>             @echo "~~~~~~Linking sample_$@:"
>>>>
>>>> #          $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS)
>>>> $(LIBDL) \
>>>>
>>>> #             -Wl,-rpath,'$$ORIGIN',--enable-new-dtags
>>>>
>>>>             $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS)
>>>> $(LIBDL)
>>>>
>>>>             @echo "   Use 'LD_PRELOAD=./libtp.so ./sample_$@' to run
>>>> sample_$@"
>>>>
>>>>
>>>>
>>>> static.o: sample.c tp.h
>>>>
>>>>             @echo "~~~~~~Compiling $@:"
>>>>
>>>>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE) -c -o $@ $<
>>>>
>>>>
>>>>
>>>> #If not preloaded, the sample application runs but won't be traceable.
>>>>
>>>> #Putting libtp in the path won't work: the sample does not look for it.
>>>>
>>>> dynamic: dynamic.o libtp.so
>>>>
>>>>             @echo "~~~~~~Linking sample_$@:"
>>>>
>>>>             $(CC) -o sample_$@ $< $(LDFLAGS) $(LIBDL)
>>>>
>>>>             @echo "   Use '[LD_PRELOAD=./libtp.so] ./sample_$@' to run
>>>> sample_$@"
>>>>
>>>>
>>>>
>>>> #Compare with the 'static.o' target.
>>>>
>>>> dynamic.o: sample.c tp.h
>>>>
>>>>             @echo "~~~~~~Compiling $@:"
>>>>
>>>>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE_DYNAMIC) \
>>>>
>>>>                -c -o $@ $<
>>>>
>>>>
>>>>
>>>>    The case where the app isn’t traced but the library it uses is
>>>> traced should be a variation on this.  I’ll try it out sometime in the near
>>>> future, but you should be able to figure it out from the above.  Here’s a
>>>> first guess (it may need $(LIBDL) alongside $(LIBUST)):
>>>>
>>>>
>>>>
>>>> libtp.so: libtp.o
>>>>
>>>>             @echo "~~~~~~Packaging $@:"
>>>>
>>>>             $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR)
>>>> -Wl,-no-as-needed -L. -ltp \
>>>>
>>>>                -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS)
>>>> $(LIBUST) $<
>>>>
>>>>             ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
>>>> $@.$(SOVERSION_MAJOR)
>>>>
>>>>             ln -sf $@.$(SOVERSION_MAJOR) $@
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> > 3) Is there any page which explains on why and how to use
>>>>
>>>> > TRACEPOINT_PROVIDER, TRACEPOINT_CREATE_PROBES, TRACEPOINT_INCLUDE,
>>>> TRACEPOINT_DEFINE, TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>>>>
>>>>
>>>>
>>>> They’re reasonably explained in the demonstration apps.  I discuss them
>>>> a little more in depth in the forthcoming LTTng Comprehensive User’s Guide
>>>> (I could send you a copy of the draft, as we’ve just begun its first review
>>>> round).
>>>>
>>>>
>>>>
>>>> > my tp.h is, are there any errors in this?
>>>>
>>>> > #############
>>>>
>>>>
>>>>
>>>> #undef TRACEPOINT_PROVIDER
>>>>
>>>>
>>>>
>>>> > #define TRACEPOINT_PROVIDER sample_component
>>>>
>>>> >
>>>>
>>>> > #undef TRACEPOINT_INCLUDE
>>>>
>>>> > #define TRACEPOINT_INCLUDE "./tp.h"
>>>>
>>>> >
>>>>
>>>> > #if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
>>>>
>>>> > #define _TP_H
>>>>
>>>>
>>>>
>>>> (Ideally, use _SAMPLE_COMPONENT_PROVIDER_H instead of _TP_H)
>>>>
>>>>
>>>>
>>>> > #include <lttng/tracepoint.h>
>>>>
>>>>
>>>>
>>>> #ifdef __cplusplus
>>>>
>>>> extern "C" {
>>>>
>>>> #endif /* __cplusplus */
>>>>
>>>>
>>>>
>>>> > TRACEPOINT_EVENT(
>>>>
>>>> >        sample_component,
>>>>
>>>> >        event,
>>>>
>>>> >        TP_ARGS(char *, text),
>>>>
>>>>
>>>>
>>>> (the compiler may be happier with const char * instead)
>>>>
>>>>
>>>>
>>>> >        TP_FIELDS(
>>>>
>>>> >                ctf_string(message, text)
>>>>
>>>> >        )
>>>>
>>>> >)
>>>>
>>>> > TRACEPOINT_LOGLEVEL(
>>>>
>>>> >        sample_component,
>>>>
>>>> >        event,
>>>>
>>>> >        TRACE_WARNING)
>>>>
>>>>
>>>>
>>>> #ifdef __cplusplus
>>>>
>>>> }
>>>>
>>>> #endif /* __cplusplus */
>>>>
>>>>
>>>>
>>>> > #endif /* _TP_H */
>>>>
>>>> > #include <lttng/tracepoint-event.h>
>>>>
>>>>
>>>>
>>>> (move #include <lttng/tracepoint-event.h> inside of the #if
>>>> !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ))
>>>>
>>>>
>>>>
>>>> > #############
>>>>
>>>> >
>>>>
>>>> > Thanks,
>>>>
>>>> > Anand Neeli
>>>>
>>>>
>>>>
>>>>    One key change I made to my sample applications is to remove the
>>>> “#define TRACEPOINT_DEFINE” that precedes the “#include "tp.h"” line.  I
>>>> prefer to control that #define using a compiler -D option.  It makes the
>>>> makefile clearer and resolves the problem of making sure there is just one
>>>> module that turns that #define on.
>>>>
>>>>
>>>>
>>>>    Hope this helps.
>>>>
>>>>
>>>>
>>>> Daniel U. Thibault
>>>> Protection des systèmes et contremesures (PSC) | Systems Protection &
>>>> Countermeasures (SPC)
>>>> Cyber sécurité pour les missions essentielles (CME) | Mission Critical
>>>> Cyber Security (MCCS)
>>>> R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence
>>>> R&D Canada - Valcartier (DRDC Valcartier)
>>>> 2459 route de la Bravoure
>>>> Québec QC  G3J 1X5
>>>> CANADA
>>>> Vox : (418) 844-4000 x4245
>>>> Fax : (418) 844-4538
>>>> NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ<http://--ESFSECEV-TY3011-------------------------------->
>>>> >
>>>> Gouvernement du Canada | Government of Canada
>>>> <http://www.valcartier.drdc-rddc.gc.ca/<http://--ESFSECEV-TY3011--------------------->
>>>> >
>>>>
>>>
>>>
>>> _______________________________________________
>>> lttng-dev mailing list
>>> lttng-dev@lists.lttng.org
>>> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
>>>
>>>
>>
>

[-- Attachment #1.2: Type: text/html, Size: 48485 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found]       ` <CACFGcbbmW0mc3GHa9VYBQLiS6zrm1gQB8bkYMBFadnvM7QKeeQ@mail.gmail.com>
@ 2014-04-05  9:56         ` Anand Neeli
       [not found]         ` <CAM5kDqySXuNqYcdjy+kgs-h5cDdiQSioumUX449Gfrcgg+HUbw@mail.gmail.com>
  1 sibling, 0 replies; 13+ messages in thread
From: Anand Neeli @ 2014-04-05  9:56 UTC (permalink / raw)
  To: Lingyu Zhu; +Cc: lttng-dev, Thibault, Daniel


[-- Attachment #1.1: Type: text/plain, Size: 16122 bytes --]

Hi Lingyu Zhu,
what do you mean by switching on or off tracing mode?
will i be able to trace or not trace without reloading the app?
If i dont use LD_PRELOAD with tracepoint it never traces. and for tracing
to start i should reload the app with ld_preload tracepoints.
We would like to see the traces only when there is a problem in the app.
And by reloading the app to enable traces we would loose all the app
context (in problem state).

Hope i'm not missing anything here.

Thanks,
Anand Neeli



On Sat, Apr 5, 2014 at 12:14 PM, Lingyu Zhu <lynuszhu@gmail.com> wrote:

> If you omit defining the macro TRACEPOINT_PROBE_DYNAMIC_LINKAGE in your
> library which you want to trace, your library will depend on the trace
> provider shared library. And you will not bother LD_PRELOAD your tracepoint
> provider library before launching app.
>
> However, by doing so you will lose control over switching on or off
> 'tracing mode': whenever your code is called,your tracepoint will try to
> register and tracepoint() might have more overhead if you build your
> library like that, whereas your tracepoint won't register and tracepoint()
> macro just cost a simple branch if you do so by normal way and skip
> LD_PRELOAD.
>
>
> On Sat, Apr 5, 2014 at 4:16 AM, Anand Neeli <anand.neeli@gmail.com> wrote:
>
>> Hi Daniel,
>> Thanks for your detailed mail.
>> I will spend time with my code and get back if i have more queries.
>>
>> What i'm looking at it is: adding lttng infra in our code base. I'm
>> looking for a solution where most of the lttng build and launch parts are
>> abstracted to the end app/library developer.
>> That is the reason why i'm not in favor of having LD_PRELOAD while
>> launching an app. This would need the app developer to check if included
>> libraries has tracing support and add .so appropriately to LD_PRELOAD
>> (which needs more education to developer on lttng and included libraries)
>> If we can launch app(with or without instrumented library) normally and
>> limit the complexity of linking to makefile it will be great.
>>
>> Please keep me posted if you have any more thoughts on this.
>> Also, can you please send me the users guide.
>>
>> Thanks,
>> Anand Neeli
>>
>>
>> On Fri, Apr 4, 2014 at 8:13 PM, Thibault, Daniel <
>> Daniel.Thibault@drdc-rddc.gc.ca> wrote:
>>
>>>  *De :* Anand Neeli [mailto:anand.neeli@gmail.com]
>>> *Envoyé :* 4 avril 2014 01:45
>>>
>>>   > Thanks for your reply.
>>>
>>> > Sorry for my ignorance but how are you generating libtp.so in your
>>> example?
>>>
>>>
>>>
>>> Non-boilerplate parts are in red.
>>>
>>>
>>>
>>> tp.c:
>>>
>>> #####
>>>
>>> /*
>>>
>>> * Defining macro creates the code objects of the traceprobes.
>>>
>>> * Must be done only once per file (this #define controls tracepoint.h and
>>>
>>> * tracepoint-event.h).
>>>
>>> */
>>>
>>> #define TRACEPOINT_CREATE_PROBES
>>>
>>> /*
>>>
>>> * The header containing our TRACEPOINT_EVENTs.
>>>
>>> */
>>>
>>> #include "tp.h"
>>>
>>> #####
>>>
>>> tp.h:
>>> #####
>>> #undef TRACEPOINT_PROVIDER
>>>
>>> #define TRACEPOINT_PROVIDER sample_component
>>>
>>> /*
>>>
>>> * include file (this files's name)
>>>
>>> */
>>>
>>> #undef TRACEPOINT_INCLUDE
>>>
>>> #define TRACEPOINT_INCLUDE "./tp.h"
>>>
>>> /*
>>>
>>> * Add this precompiler conditional to ensure the tracepoint event
>>> generation
>>>
>>> * can include this file more than once.
>>>
>>> */
>>>
>>> #if !defined(_SAMPLE_COMPONENT_PROVIDER_H) ||
>>> defined(TRACEPOINT_HEADER_MULTI_READ)
>>>
>>> #define _SAMPLE_COMPONENT_PROVIDER_H
>>>
>>> /*
>>>
>>> * Add this to allow programs to call "tracepoint(...)".
>>>
>>> * This #include must not be within an extern "C" block; if it is,
>>>
>>> * C++ instrumentation will fail when SystemTap is also installed.
>>>
>>> * (This may have been fixed since I wrote this)
>>>
>>> */
>>>
>>> #include <lttng/tracepoint.h>
>>>
>>> /*
>>>
>>> * Add this macro and its matching element to make sure the program
>>>
>>> * works in C++.
>>>
>>> */
>>>
>>> #ifdef __cplusplus
>>>
>>> extern "C" {
>>>
>>> #endif /* __cplusplus */
>>>
>>>
>>>
>>> /*
>>>
>>> * The following tracepoint event writes a message (C string) into the
>>>
>>> * field "message" of the trace event "event" in the provider
>>>
>>> * "sample_component" in other words:
>>>
>>> *
>>>
>>> *    sample_component:event:message = text.
>>>
>>> */
>>>
>>> TRACEPOINT_EVENT(
>>>
>>>             /*
>>>
>>>             * provider name, not a variable but a string starting with a
>>> letter
>>>
>>>             * and containing either letters, numbers or underscores.
>>>
>>>             * Needs to be the same as TRACEPOINT_PROVIDER
>>>
>>>             */
>>>
>>>             sample_component,
>>>
>>>             /*
>>>
>>>             * tracepoint name, same format as sample provider. Does not
>>> need to be
>>>
>>>             * declared before. in this case the name is "event"
>>>
>>>             */
>>>
>>>             event,
>>>
>>>             /*
>>>
>>>             * TP_ARGS macro contains the arguments passed for the
>>> tracepoint.
>>>
>>>             * It is in the following format:
>>>
>>>             *                     TP_ARGS( type1, name1, type2, name2,
>>> ... type10, name10)
>>>
>>>             * where there can be from zero to ten elements.
>>>
>>>             * "typeN" is the datatype, such as int, struct or double **.
>>>
>>>             * "name" is the variable name (in "int myInt" the name would
>>> be "myInt")
>>>
>>>             *                     TP_ARGS() is valid (no arguments)
>>>
>>>             *                     TP_ARGS( void ) is valid too
>>>
>>>             */
>>>
>>>             TP_ARGS(const char *, text),
>>>
>>>             /*
>>>
>>>             * TP_FIELDS describes how to write the fields of the trace
>>> event.
>>>
>>>             * You can use the args here
>>>
>>>             */
>>>
>>>             TP_FIELDS(
>>>
>>>             /*
>>>
>>>             * The ctf_string macro takes a C string and writes it into a
>>> field
>>>
>>>             * named "message"
>>>
>>>             */
>>>
>>>                         ctf_string(message, text)
>>>
>>>             )
>>>
>>> )
>>>
>>> /*
>>>
>>> * Trace loglevel, shows the level of the trace event. It can be
>>> TRACE_EMERG,
>>>
>>> * TRACE_ALERT, TRACE_CRIT, TRACE_ERR, TRACE_WARNING, TRACE_INFO, etc.
>>>
>>> * If this is not set, TRACE_DEFAULT is assumed.
>>>
>>> * The first two arguments identify the tracepoint.
>>>
>>> * See details in <lttng/tracepoint.h> line 347
>>>
>>> */
>>>
>>> TRACEPOINT_LOGLEVEL(
>>>
>>>        /*
>>>
>>>         * The provider name, must be the same as the provider name in the
>>>
>>>         * TRACEPOINT_EVENT and as TRACEPOINT_PROVIDER above.
>>>
>>>         */
>>>
>>>             sample_component,
>>>
>>>        /*
>>>
>>>         * The tracepoint name, must be the same as the tracepoint name
>>> in the
>>>
>>>         * TRACEPOINT_EVENT
>>>
>>>         */
>>>
>>>             event,
>>>
>>>        /*
>>>
>>>         * The tracepoint loglevel. WARNING: Some levels are abbreviated
>>> and
>>>
>>>         * others are not, please see <lttng/tracepoint.h>
>>>
>>>         */
>>>
>>>             TRACE_WARNING
>>>
>>> )
>>>
>>>  (more tracepoints...)
>>>
>>>
>>>
>>> /*
>>>
>>> * Add this macro and its matching element to make sure the program
>>>
>>> * works in C++.
>>>
>>> */
>>>
>>> #ifdef __cplusplus
>>>
>>> }
>>>
>>> #endif /* __cplusplus */
>>>
>>> /*
>>>
>>> * Add this after defining the tracepoint events to expand the macros.
>>>
>>> */
>>>
>>> #include <lttng/tracepoint-event.h>
>>>
>>> #endif /* _SAMPLE_COMPONENT_PROVIDER_H */
>>>
>>> #####
>>>
>>> The relevant Makefile fragments:
>>> #####
>>> CC = gcc
>>> LIBUST = -llttng-ust
>>>
>>> LOCAL_CPPFLAGS += -I. $(AM_CPPFLAGS)
>>> LDFLAGS += -L/usr/local/lib $(AM_LDFLAGS)
>>> SOFLAGS = -fPIC
>>> SOVERSION_MAJOR = 1
>>> SOVERSION_MINOR = 0
>>>
>>> libtp.so: libtp.o
>>>
>>>             @echo "~~~~~~Packaging $@:"
>>>
>>>             $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR)
>>> -Wl,-no-as-needed \
>>>
>>>                -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS)
>>> $(LIBUST) $<
>>>
>>>             ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
>>> $@.$(SOVERSION_MAJOR)
>>>
>>>             ln -sf $@.$(SOVERSION_MAJOR) $@
>>>
>>>
>>>
>>> libtp.o: tp.c tp.h
>>>
>>>             @echo "~~~~~~Compiling $@:"
>>>
>>>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(SOFLAGS) -c -o $@ $<
>>>
>>>
>>> > 1) Also will this solution scale if my binary depends on lots
>>> of libraries which are instrumented?
>>>
>>>
>>>
>>> Sure.  I'd expect linear scaling.  Each library, upon being loaded,
>>> looks for its tracepoint provider and turns its tracepoints off if they're
>>> not found.
>>>
>>>
>>>
>>> > 2) i'm fine with linking statically, can we avoid LD_PRELOAD?
>>>
>>>
>>>
>>> Besides the LD_PRELOAD technique, you could also use LD_LIBRARY_PATH,
>>> but that works only if the application statically includes the tracepoint
>>> provider (I suppose it would likewise work for an instrumented shared
>>> object only if it statically includes the tracepoint provider).
>>>
>>>
>>>
>>> You could also add "-Wl,-rpath,'$$ORIGIN'" to the linker call to add an
>>> RPATH tag to the application (or shared object).  This makes it look for
>>> its dependencies in its starting directory ($ORIGIN).  RPATH is, unlike
>>> RUNPATH, applicable to libraries as well: a library with an RPATH tag will
>>> look there for its dependencies; failing its own RPATH, it will use its
>>> executable's RPATH.
>>>
>>>
>>>
>>> Finally, you can dynamically include the tracepoint provider (libtp) as
>>> a dependency.  The application (sample_static_aware) is then statically
>>> aware of libtp and won't run without it.  The application (sample_dynamic)
>>> can alternately dynamically include the tracepoint provider *without*static awareness.  Here's how it's done:
>>>
>>>
>>>
>>> LIBDL = -ldl # On Linux
>>>
>>> #LIBDL = -lc # On BSD
>>>
>>> TP_DEFINE = -D TRACEPOINT_DEFINE
>>>
>>> TP_DEFINE_DYNAMIC = $(TP_DEFINE) -D TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>>>
>>>
>>>
>>> #(the inclusion of a libtp NEEDED tag requires "-no-as-needed -ltp").
>>>
>>> #Note that "-L. -ltp", when used, should appear before $(LDFLAGS)
>>> $(LIBDL).
>>>
>>> static_aware: static.o libtp.so
>>>
>>>             @echo "~~~~~~Linking sample_$@:"
>>>
>>> #          $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS)
>>> $(LIBDL) \
>>>
>>> #             -Wl,-rpath,'$$ORIGIN',--enable-new-dtags
>>>
>>>             $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS)
>>> $(LIBDL)
>>>
>>>             @echo "   Use 'LD_PRELOAD=./libtp.so ./sample_$@' to run
>>> sample_$@"
>>>
>>>
>>>
>>> static.o: sample.c tp.h
>>>
>>>             @echo "~~~~~~Compiling $@:"
>>>
>>>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE) -c -o $@ $<
>>>
>>>
>>>
>>> #If not preloaded, the sample application runs but won't be traceable.
>>>
>>> #Putting libtp in the path won't work: the sample does not look for it.
>>>
>>> dynamic: dynamic.o libtp.so
>>>
>>>             @echo "~~~~~~Linking sample_$@:"
>>>
>>>             $(CC) -o sample_$@ $< $(LDFLAGS) $(LIBDL)
>>>
>>>             @echo "   Use '[LD_PRELOAD=./libtp.so] ./sample_$@' to run
>>> sample_$@"
>>>
>>>
>>>
>>> #Compare with the 'static.o' target.
>>>
>>> dynamic.o: sample.c tp.h
>>>
>>>             @echo "~~~~~~Compiling $@:"
>>>
>>>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE_DYNAMIC) \
>>>
>>>                -c -o $@ $<
>>>
>>>
>>>
>>>    The case where the app isn't traced but the library it uses is traced
>>> should be a variation on this.  I'll try it out sometime in the near
>>> future, but you should be able to figure it out from the above.  Here's a
>>> first guess (it may need $(LIBDL) alongside $(LIBUST)):
>>>
>>>
>>>
>>> libtp.so: libtp.o
>>>
>>>             @echo "~~~~~~Packaging $@:"
>>>
>>>             $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR)
>>> -Wl,-no-as-needed -L. -ltp \
>>>
>>>                -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS)
>>> $(LIBUST) $<
>>>
>>>             ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
>>> $@.$(SOVERSION_MAJOR)
>>>
>>>             ln -sf $@.$(SOVERSION_MAJOR) $@
>>>
>>>
>>>
>>>
>>>
>>> > 3) Is there any page which explains on why and how to use
>>>
>>> > TRACEPOINT_PROVIDER, TRACEPOINT_CREATE_PROBES, TRACEPOINT_INCLUDE,
>>> TRACEPOINT_DEFINE, TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>>>
>>>
>>>
>>> They're reasonably explained in the demonstration apps.  I discuss them
>>> a little more in depth in the forthcoming LTTng Comprehensive User's Guide
>>> (I could send you a copy of the draft, as we've just begun its first review
>>> round).
>>>
>>>
>>>
>>> > my tp.h is, are there any errors in this?
>>>
>>> > #############
>>>
>>>
>>>
>>> #undef TRACEPOINT_PROVIDER
>>>
>>>
>>>
>>> > #define TRACEPOINT_PROVIDER sample_component
>>>
>>> >
>>>
>>> > #undef TRACEPOINT_INCLUDE
>>>
>>> > #define TRACEPOINT_INCLUDE "./tp.h"
>>>
>>> >
>>>
>>> > #if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
>>>
>>> > #define _TP_H
>>>
>>>
>>>
>>> (Ideally, use _SAMPLE_COMPONENT_PROVIDER_H instead of _TP_H)
>>>
>>>
>>>
>>> > #include <lttng/tracepoint.h>
>>>
>>>
>>>
>>> #ifdef __cplusplus
>>>
>>> extern "C" {
>>>
>>> #endif /* __cplusplus */
>>>
>>>
>>>
>>> > TRACEPOINT_EVENT(
>>>
>>> >        sample_component,
>>>
>>> >        event,
>>>
>>> >        TP_ARGS(char *, text),
>>>
>>>
>>>
>>> (the compiler may be happier with const char * instead)
>>>
>>>
>>>
>>> >        TP_FIELDS(
>>>
>>> >                ctf_string(message, text)
>>>
>>> >        )
>>>
>>> >)
>>>
>>> > TRACEPOINT_LOGLEVEL(
>>>
>>> >        sample_component,
>>>
>>> >        event,
>>>
>>> >        TRACE_WARNING)
>>>
>>>
>>>
>>> #ifdef __cplusplus
>>>
>>> }
>>>
>>> #endif /* __cplusplus */
>>>
>>>
>>>
>>> > #endif /* _TP_H */
>>>
>>> > #include <lttng/tracepoint-event.h>
>>>
>>>
>>>
>>> (move #include <lttng/tracepoint-event.h> inside of the #if
>>> !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ))
>>>
>>>
>>>
>>> > #############
>>>
>>> >
>>>
>>> > Thanks,
>>>
>>> > Anand Neeli
>>>
>>>
>>>
>>>    One key change I made to my sample applications is to remove the
>>> "#define TRACEPOINT_DEFINE" that precedes the "#include "tp.h"" line.  I
>>> prefer to control that #define using a compiler -D option.  It makes the
>>> makefile clearer and resolves the problem of making sure there is just one
>>> module that turns that #define on.
>>>
>>>
>>>
>>>    Hope this helps.
>>>
>>>
>>>
>>> Daniel U. Thibault
>>> Protection des systèmes et contremesures (PSC) | Systems Protection &
>>> Countermeasures (SPC)
>>> Cyber sécurité pour les missions essentielles (CME) | Mission Critical
>>> Cyber Security (MCCS)
>>> R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence
>>> R&D Canada - Valcartier (DRDC Valcartier)
>>> 2459 route de la Bravoure
>>> Québec QC  G3J 1X5
>>> CANADA
>>> Vox : (418) 844-4000 x4245
>>> Fax : (418) 844-4538
>>> NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ<http://--ESFSECEV-TY3011-------------------------------->
>>> >
>>> Gouvernement du Canada | Government of Canada
>>> <http://www.valcartier.drdc-rddc.gc.ca/<http://--ESFSECEV-TY3011--------------------->
>>> >
>>>
>>
>>
>> _______________________________________________
>> lttng-dev mailing list
>> lttng-dev@lists.lttng.org
>> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
>>
>>
>

[-- Attachment #1.2: Type: text/html, Size: 51126 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found]     ` <CAM5kDqyCTjKLWhR5XXT9DvXHaniOnJy0SPSDOMPw3eCSD7Z6Uw@mail.gmail.com>
  2014-04-04 20:33       ` Thibault, Daniel
@ 2014-04-05  6:44       ` Lingyu Zhu
       [not found]       ` <CACFGcbbmW0mc3GHa9VYBQLiS6zrm1gQB8bkYMBFadnvM7QKeeQ@mail.gmail.com>
  2 siblings, 0 replies; 13+ messages in thread
From: Lingyu Zhu @ 2014-04-05  6:44 UTC (permalink / raw)
  To: Anand Neeli; +Cc: lttng-dev, Thibault, Daniel


[-- Attachment #1.1: Type: text/plain, Size: 14924 bytes --]

If you omit defining the macro TRACEPOINT_PROBE_DYNAMIC_LINKAGE in your
library which you want to trace, your library will depend on the trace
provider shared library. And you will not bother LD_PRELOAD your tracepoint
provider library before launching app.

However, by doing so you will lose control over switching on or off
'tracing mode': whenever your code is called,your tracepoint will try to
register and tracepoint() might have more overhead if you build your
library like that, whereas your tracepoint won't register and tracepoint()
macro just cost a simple branch if you do so by normal way and skip
LD_PRELOAD.


On Sat, Apr 5, 2014 at 4:16 AM, Anand Neeli <anand.neeli@gmail.com> wrote:

> Hi Daniel,
> Thanks for your detailed mail.
> I will spend time with my code and get back if i have more queries.
>
> What i'm looking at it is: adding lttng infra in our code base. I'm
> looking for a solution where most of the lttng build and launch parts are
> abstracted to the end app/library developer.
> That is the reason why i'm not in favor of having LD_PRELOAD while
> launching an app. This would need the app developer to check if included
> libraries has tracing support and add .so appropriately to LD_PRELOAD
> (which needs more education to developer on lttng and included libraries)
> If we can launch app(with or without instrumented library) normally and
> limit the complexity of linking to makefile it will be great.
>
> Please keep me posted if you have any more thoughts on this.
> Also, can you please send me the users guide.
>
> Thanks,
> Anand Neeli
>
>
> On Fri, Apr 4, 2014 at 8:13 PM, Thibault, Daniel <
> Daniel.Thibault@drdc-rddc.gc.ca> wrote:
>
>>  *De :* Anand Neeli [mailto:anand.neeli@gmail.com]
>> *Envoyé :* 4 avril 2014 01:45
>>
>>   > Thanks for your reply.
>>
>> > Sorry for my ignorance but how are you generating libtp.so in your
>> example?
>>
>>
>>
>> Non-boilerplate parts are in red.
>>
>>
>>
>> tp.c:
>>
>> #####
>>
>> /*
>>
>> * Defining macro creates the code objects of the traceprobes.
>>
>> * Must be done only once per file (this #define controls tracepoint.h and
>>
>> * tracepoint-event.h).
>>
>> */
>>
>> #define TRACEPOINT_CREATE_PROBES
>>
>> /*
>>
>> * The header containing our TRACEPOINT_EVENTs.
>>
>> */
>>
>> #include "tp.h"
>>
>> #####
>>
>> tp.h:
>> #####
>> #undef TRACEPOINT_PROVIDER
>>
>> #define TRACEPOINT_PROVIDER sample_component
>>
>> /*
>>
>> * include file (this files's name)
>>
>> */
>>
>> #undef TRACEPOINT_INCLUDE
>>
>> #define TRACEPOINT_INCLUDE "./tp.h"
>>
>> /*
>>
>> * Add this precompiler conditional to ensure the tracepoint event
>> generation
>>
>> * can include this file more than once.
>>
>> */
>>
>> #if !defined(_SAMPLE_COMPONENT_PROVIDER_H) ||
>> defined(TRACEPOINT_HEADER_MULTI_READ)
>>
>> #define _SAMPLE_COMPONENT_PROVIDER_H
>>
>> /*
>>
>> * Add this to allow programs to call "tracepoint(...)".
>>
>> * This #include must not be within an extern "C" block; if it is,
>>
>> * C++ instrumentation will fail when SystemTap is also installed.
>>
>> * (This may have been fixed since I wrote this)
>>
>> */
>>
>> #include <lttng/tracepoint.h>
>>
>> /*
>>
>> * Add this macro and its matching element to make sure the program
>>
>> * works in C++.
>>
>> */
>>
>> #ifdef __cplusplus
>>
>> extern "C" {
>>
>> #endif /* __cplusplus */
>>
>>
>>
>> /*
>>
>> * The following tracepoint event writes a message (C string) into the
>>
>> * field "message" of the trace event "event" in the provider
>>
>> * "sample_component" in other words:
>>
>> *
>>
>> *    sample_component:event:message = text.
>>
>> */
>>
>> TRACEPOINT_EVENT(
>>
>>             /*
>>
>>             * provider name, not a variable but a string starting with a
>> letter
>>
>>             * and containing either letters, numbers or underscores.
>>
>>             * Needs to be the same as TRACEPOINT_PROVIDER
>>
>>             */
>>
>>             sample_component,
>>
>>             /*
>>
>>             * tracepoint name, same format as sample provider. Does not
>> need to be
>>
>>             * declared before. in this case the name is "event"
>>
>>             */
>>
>>             event,
>>
>>             /*
>>
>>             * TP_ARGS macro contains the arguments passed for the
>> tracepoint.
>>
>>             * It is in the following format:
>>
>>             *                     TP_ARGS( type1, name1, type2, name2,
>> ... type10, name10)
>>
>>             * where there can be from zero to ten elements.
>>
>>             * "typeN" is the datatype, such as int, struct or double **.
>>
>>             * "name" is the variable name (in "int myInt" the name would
>> be "myInt")
>>
>>             *                     TP_ARGS() is valid (no arguments)
>>
>>             *                     TP_ARGS( void ) is valid too
>>
>>             */
>>
>>             TP_ARGS(const char *, text),
>>
>>             /*
>>
>>             * TP_FIELDS describes how to write the fields of the trace
>> event.
>>
>>             * You can use the args here
>>
>>             */
>>
>>             TP_FIELDS(
>>
>>             /*
>>
>>             * The ctf_string macro takes a C string and writes it into a
>> field
>>
>>             * named "message"
>>
>>             */
>>
>>                         ctf_string(message, text)
>>
>>             )
>>
>> )
>>
>> /*
>>
>> * Trace loglevel, shows the level of the trace event. It can be
>> TRACE_EMERG,
>>
>> * TRACE_ALERT, TRACE_CRIT, TRACE_ERR, TRACE_WARNING, TRACE_INFO, etc.
>>
>> * If this is not set, TRACE_DEFAULT is assumed.
>>
>> * The first two arguments identify the tracepoint.
>>
>> * See details in <lttng/tracepoint.h> line 347
>>
>> */
>>
>> TRACEPOINT_LOGLEVEL(
>>
>>        /*
>>
>>         * The provider name, must be the same as the provider name in the
>>
>>         * TRACEPOINT_EVENT and as TRACEPOINT_PROVIDER above.
>>
>>         */
>>
>>             sample_component,
>>
>>        /*
>>
>>         * The tracepoint name, must be the same as the tracepoint name in
>> the
>>
>>         * TRACEPOINT_EVENT
>>
>>         */
>>
>>             event,
>>
>>        /*
>>
>>         * The tracepoint loglevel. WARNING: Some levels are abbreviated
>> and
>>
>>         * others are not, please see <lttng/tracepoint.h>
>>
>>         */
>>
>>             TRACE_WARNING
>>
>> )
>>
>>  (more tracepoints…)
>>
>>
>>
>> /*
>>
>> * Add this macro and its matching element to make sure the program
>>
>> * works in C++.
>>
>> */
>>
>> #ifdef __cplusplus
>>
>> }
>>
>> #endif /* __cplusplus */
>>
>> /*
>>
>> * Add this after defining the tracepoint events to expand the macros.
>>
>> */
>>
>> #include <lttng/tracepoint-event.h>
>>
>> #endif /* _SAMPLE_COMPONENT_PROVIDER_H */
>>
>> #####
>>
>> The relevant Makefile fragments:
>> #####
>> CC = gcc
>> LIBUST = -llttng-ust
>>
>> LOCAL_CPPFLAGS += -I. $(AM_CPPFLAGS)
>> LDFLAGS += -L/usr/local/lib $(AM_LDFLAGS)
>> SOFLAGS = -fPIC
>> SOVERSION_MAJOR = 1
>> SOVERSION_MINOR = 0
>>
>> libtp.so: libtp.o
>>
>>             @echo "~~~~~~Packaging $@:"
>>
>>             $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR)
>> -Wl,-no-as-needed \
>>
>>                -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS)
>> $(LIBUST) $<
>>
>>             ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
>> $@.$(SOVERSION_MAJOR)
>>
>>             ln -sf $@.$(SOVERSION_MAJOR) $@
>>
>>
>>
>> libtp.o: tp.c tp.h
>>
>>             @echo "~~~~~~Compiling $@:"
>>
>>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(SOFLAGS) -c -o $@ $<
>>
>>
>> > 1) Also will this solution scale if my binary depends on lots
>> of libraries which are instrumented?
>>
>>
>>
>> Sure.  I’d expect linear scaling.  Each library, upon being loaded, looks
>> for its tracepoint provider and turns its tracepoints off if they’re not
>> found.
>>
>>
>>
>> > 2) i'm fine with linking statically, can we avoid LD_PRELOAD?
>>
>>
>>
>> Besides the LD_PRELOAD technique, you could also use LD_LIBRARY_PATH, but
>> that works only if the application statically includes the tracepoint
>> provider (I suppose it would likewise work for an instrumented shared
>> object only if it statically includes the tracepoint provider).
>>
>>
>>
>> You could also add "-Wl,-rpath,'$$ORIGIN'" to the linker call to add an
>> RPATH tag to the application (or shared object).  This makes it look for
>> its dependencies in its starting directory ($ORIGIN).  RPATH is, unlike
>> RUNPATH, applicable to libraries as well: a library with an RPATH tag will
>> look there for its dependencies; failing its own RPATH, it will use its
>> executable's RPATH.
>>
>>
>>
>> Finally, you can dynamically include the tracepoint provider (libtp) as a
>> dependency.  The application (sample_static_aware) is then statically aware
>> of libtp and won't run without it.  The application (sample_dynamic) can
>> alternately dynamically include the tracepoint provider *without* static
>> awareness.  Here’s how it’s done:
>>
>>
>>
>> LIBDL = -ldl # On Linux
>>
>> #LIBDL = -lc # On BSD
>>
>> TP_DEFINE = -D TRACEPOINT_DEFINE
>>
>> TP_DEFINE_DYNAMIC = $(TP_DEFINE) -D TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>>
>>
>>
>> #(the inclusion of a libtp NEEDED tag requires "-no-as-needed -ltp").
>>
>> #Note that "-L. -ltp", when used, should appear before $(LDFLAGS)
>> $(LIBDL).
>>
>> static_aware: static.o libtp.so
>>
>>             @echo "~~~~~~Linking sample_$@:"
>>
>> #          $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS)
>> $(LIBDL) \
>>
>> #             -Wl,-rpath,'$$ORIGIN',--enable-new-dtags
>>
>>             $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS)
>> $(LIBDL)
>>
>>             @echo "   Use 'LD_PRELOAD=./libtp.so ./sample_$@' to run
>> sample_$@"
>>
>>
>>
>> static.o: sample.c tp.h
>>
>>             @echo "~~~~~~Compiling $@:"
>>
>>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE) -c -o $@ $<
>>
>>
>>
>> #If not preloaded, the sample application runs but won't be traceable.
>>
>> #Putting libtp in the path won't work: the sample does not look for it.
>>
>> dynamic: dynamic.o libtp.so
>>
>>             @echo "~~~~~~Linking sample_$@:"
>>
>>             $(CC) -o sample_$@ $< $(LDFLAGS) $(LIBDL)
>>
>>             @echo "   Use '[LD_PRELOAD=./libtp.so] ./sample_$@' to run
>> sample_$@"
>>
>>
>>
>> #Compare with the 'static.o' target.
>>
>> dynamic.o: sample.c tp.h
>>
>>             @echo "~~~~~~Compiling $@:"
>>
>>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE_DYNAMIC) \
>>
>>                -c -o $@ $<
>>
>>
>>
>>    The case where the app isn’t traced but the library it uses is traced
>> should be a variation on this.  I’ll try it out sometime in the near
>> future, but you should be able to figure it out from the above.  Here’s a
>> first guess (it may need $(LIBDL) alongside $(LIBUST)):
>>
>>
>>
>> libtp.so: libtp.o
>>
>>             @echo "~~~~~~Packaging $@:"
>>
>>             $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR)
>> -Wl,-no-as-needed -L. -ltp \
>>
>>                -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS)
>> $(LIBUST) $<
>>
>>             ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
>> $@.$(SOVERSION_MAJOR)
>>
>>             ln -sf $@.$(SOVERSION_MAJOR) $@
>>
>>
>>
>>
>>
>> > 3) Is there any page which explains on why and how to use
>>
>> > TRACEPOINT_PROVIDER, TRACEPOINT_CREATE_PROBES, TRACEPOINT_INCLUDE,
>> TRACEPOINT_DEFINE, TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>>
>>
>>
>> They’re reasonably explained in the demonstration apps.  I discuss them a
>> little more in depth in the forthcoming LTTng Comprehensive User’s Guide (I
>> could send you a copy of the draft, as we’ve just begun its first review
>> round).
>>
>>
>>
>> > my tp.h is, are there any errors in this?
>>
>> > #############
>>
>>
>>
>> #undef TRACEPOINT_PROVIDER
>>
>>
>>
>> > #define TRACEPOINT_PROVIDER sample_component
>>
>> >
>>
>> > #undef TRACEPOINT_INCLUDE
>>
>> > #define TRACEPOINT_INCLUDE "./tp.h"
>>
>> >
>>
>> > #if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
>>
>> > #define _TP_H
>>
>>
>>
>> (Ideally, use _SAMPLE_COMPONENT_PROVIDER_H instead of _TP_H)
>>
>>
>>
>> > #include <lttng/tracepoint.h>
>>
>>
>>
>> #ifdef __cplusplus
>>
>> extern "C" {
>>
>> #endif /* __cplusplus */
>>
>>
>>
>> > TRACEPOINT_EVENT(
>>
>> >        sample_component,
>>
>> >        event,
>>
>> >        TP_ARGS(char *, text),
>>
>>
>>
>> (the compiler may be happier with const char * instead)
>>
>>
>>
>> >        TP_FIELDS(
>>
>> >                ctf_string(message, text)
>>
>> >        )
>>
>> >)
>>
>> > TRACEPOINT_LOGLEVEL(
>>
>> >        sample_component,
>>
>> >        event,
>>
>> >        TRACE_WARNING)
>>
>>
>>
>> #ifdef __cplusplus
>>
>> }
>>
>> #endif /* __cplusplus */
>>
>>
>>
>> > #endif /* _TP_H */
>>
>> > #include <lttng/tracepoint-event.h>
>>
>>
>>
>> (move #include <lttng/tracepoint-event.h> inside of the #if
>> !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ))
>>
>>
>>
>> > #############
>>
>> >
>>
>> > Thanks,
>>
>> > Anand Neeli
>>
>>
>>
>>    One key change I made to my sample applications is to remove the
>> “#define TRACEPOINT_DEFINE” that precedes the “#include "tp.h"” line.  I
>> prefer to control that #define using a compiler -D option.  It makes the
>> makefile clearer and resolves the problem of making sure there is just one
>> module that turns that #define on.
>>
>>
>>
>>    Hope this helps.
>>
>>
>>
>> Daniel U. Thibault
>> Protection des systèmes et contremesures (PSC) | Systems Protection &
>> Countermeasures (SPC)
>> Cyber sécurité pour les missions essentielles (CME) | Mission Critical
>> Cyber Security (MCCS)
>> R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D
>> Canada - Valcartier (DRDC Valcartier)
>> 2459 route de la Bravoure
>> Québec QC  G3J 1X5
>> CANADA
>> Vox : (418) 844-4000 x4245
>> Fax : (418) 844-4538
>> NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ<http://--ESFSECEV-TY3011-------------------------------->
>> >
>> Gouvernement du Canada | Government of Canada
>> <http://www.valcartier.drdc-rddc.gc.ca/<http://--ESFSECEV-TY3011--------------------->
>> >
>>
>
>
> _______________________________________________
> lttng-dev mailing list
> lttng-dev@lists.lttng.org
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
>
>

[-- Attachment #1.2: Type: text/html, Size: 46162 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found]     ` <CAM5kDqyCTjKLWhR5XXT9DvXHaniOnJy0SPSDOMPw3eCSD7Z6Uw@mail.gmail.com>
@ 2014-04-04 20:33       ` Thibault, Daniel
  2014-04-05  6:44       ` Lingyu Zhu
       [not found]       ` <CACFGcbbmW0mc3GHa9VYBQLiS6zrm1gQB8bkYMBFadnvM7QKeeQ@mail.gmail.com>
  2 siblings, 0 replies; 13+ messages in thread
From: Thibault, Daniel @ 2014-04-04 20:33 UTC (permalink / raw)
  To: Anand Neeli; +Cc: lttng-dev


[-- Attachment #1.1: Type: text/plain, Size: 2586 bytes --]


De : Anand Neeli [mailto:anand.neeli@gmail.com]
Envoyé : 4 avril 2014 16:17

What i'm looking at it is: adding lttng infra in our code base. I'm looking for a solution where most of the lttng build and launch parts are abstracted to the end app/library developer.
That is the reason why i'm not in favor of having LD_PRELOAD while launching an app. This would need the app developer to check if included libraries has tracing support and add .so appropriately to LD_PRELOAD (which needs more education to developer on lttng and included libraries)
If we can launch app(with or without instrumented library) normally and limit the complexity of linking to makefile it will be great.

Please keep me posted if you have any more thoughts on this.
Also, can you please send me the users guide.

Anand Neeli
________________________________
   The idea behind using LD_PRELOAD is to have tracing switchable on and off without needing to recompile or relink the application.  If you make the app statically aware of the tracepoint providers, it won't run (won't load) without them.  Of course, if you're comfortable with that, it's okay.
   Another approach is to have tracing controlled by an app option.  This requires the app to explicitly load and unload the tracepoint provider using dlopen() and dlclose().
   Things are also a little different if all you're instrumenting are the libraries the apps are using.  You might be able to get away with using the rpath tag and then just moving the tracepoint provider in and out of scope (by copying or renaming the tracepoint provider shared object).  This would be a rather kludgy global setting (unless the directory where the libraries lie is user-specific) and would also not work to turn off tracing while the libraries are in use (because the tracepoint provider would refuse to be unloaded).
   I'll send the PDFs separately.
Daniel U. Thibault
Protection des systèmes et contremesures (PSC) | Systems Protection & Countermeasures (SPC)
Cyber sécurité pour les missions essentielles (CME) | Mission Critical Cyber Security (MCCS)
R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D Canada - Valcartier (DRDC Valcartier)
2459 route de la Bravoure
Québec QC  G3J 1X5
CANADA
Vox : (418) 844-4000 x4245
Fax : (418) 844-4538
NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ<--ESFSECEV-TY3011--------------------------------------->>
Gouvernement du Canada | Government of Canada
<http://www.valcartier.drdc-rddc.gc.ca/<--ESFSECEV-TY3011---------------------------->>


[-- Attachment #1.2: Type: text/html, Size: 7275 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found]   ` <48CF5AC71E61DB46B70D0F388054EFFD3599315B@VAL-E-02.valcartier.drdc-rddc.gc.ca>
@ 2014-04-04 20:16     ` Anand Neeli
       [not found]     ` <CAM5kDqyCTjKLWhR5XXT9DvXHaniOnJy0SPSDOMPw3eCSD7Z6Uw@mail.gmail.com>
  1 sibling, 0 replies; 13+ messages in thread
From: Anand Neeli @ 2014-04-04 20:16 UTC (permalink / raw)
  To: Thibault, Daniel; +Cc: lttng-dev


[-- Attachment #1.1: Type: text/plain, Size: 13360 bytes --]

Hi Daniel,
Thanks for your detailed mail.
I will spend time with my code and get back if i have more queries.

What i'm looking at it is: adding lttng infra in our code base. I'm looking
for a solution where most of the lttng build and launch parts are
abstracted to the end app/library developer.
That is the reason why i'm not in favor of having LD_PRELOAD while
launching an app. This would need the app developer to check if included
libraries has tracing support and add .so appropriately to LD_PRELOAD
(which needs more education to developer on lttng and included libraries)
If we can launch app(with or without instrumented library) normally and
limit the complexity of linking to makefile it will be great.

Please keep me posted if you have any more thoughts on this.
Also, can you please send me the users guide.

Thanks,
Anand Neeli


On Fri, Apr 4, 2014 at 8:13 PM, Thibault, Daniel <
Daniel.Thibault@drdc-rddc.gc.ca> wrote:

>  *De :* Anand Neeli [mailto:anand.neeli@gmail.com]
> *Envoyé :* 4 avril 2014 01:45
>
>   > Thanks for your reply.
>
> > Sorry for my ignorance but how are you generating libtp.so in your
> example?
>
>
>
> Non-boilerplate parts are in red.
>
>
>
> tp.c:
>
> #####
>
> /*
>
> * Defining macro creates the code objects of the traceprobes.
>
> * Must be done only once per file (this #define controls tracepoint.h and
>
> * tracepoint-event.h).
>
> */
>
> #define TRACEPOINT_CREATE_PROBES
>
> /*
>
> * The header containing our TRACEPOINT_EVENTs.
>
> */
>
> #include "tp.h"
>
> #####
>
> tp.h:
> #####
> #undef TRACEPOINT_PROVIDER
>
> #define TRACEPOINT_PROVIDER sample_component
>
> /*
>
> * include file (this files's name)
>
> */
>
> #undef TRACEPOINT_INCLUDE
>
> #define TRACEPOINT_INCLUDE "./tp.h"
>
> /*
>
> * Add this precompiler conditional to ensure the tracepoint event
> generation
>
> * can include this file more than once.
>
> */
>
> #if !defined(_SAMPLE_COMPONENT_PROVIDER_H) ||
> defined(TRACEPOINT_HEADER_MULTI_READ)
>
> #define _SAMPLE_COMPONENT_PROVIDER_H
>
> /*
>
> * Add this to allow programs to call "tracepoint(...)".
>
> * This #include must not be within an extern "C" block; if it is,
>
> * C++ instrumentation will fail when SystemTap is also installed.
>
> * (This may have been fixed since I wrote this)
>
> */
>
> #include <lttng/tracepoint.h>
>
> /*
>
> * Add this macro and its matching element to make sure the program
>
> * works in C++.
>
> */
>
> #ifdef __cplusplus
>
> extern "C" {
>
> #endif /* __cplusplus */
>
>
>
> /*
>
> * The following tracepoint event writes a message (C string) into the
>
> * field "message" of the trace event "event" in the provider
>
> * "sample_component" in other words:
>
> *
>
> *    sample_component:event:message = text.
>
> */
>
> TRACEPOINT_EVENT(
>
>             /*
>
>             * provider name, not a variable but a string starting with a
> letter
>
>             * and containing either letters, numbers or underscores.
>
>             * Needs to be the same as TRACEPOINT_PROVIDER
>
>             */
>
>             sample_component,
>
>             /*
>
>             * tracepoint name, same format as sample provider. Does not
> need to be
>
>             * declared before. in this case the name is "event"
>
>             */
>
>             event,
>
>             /*
>
>             * TP_ARGS macro contains the arguments passed for the
> tracepoint.
>
>             * It is in the following format:
>
>             *                     TP_ARGS( type1, name1, type2, name2, ...
> type10, name10)
>
>             * where there can be from zero to ten elements.
>
>             * "typeN" is the datatype, such as int, struct or double **.
>
>             * "name" is the variable name (in "int myInt" the name would
> be "myInt")
>
>             *                     TP_ARGS() is valid (no arguments)
>
>             *                     TP_ARGS( void ) is valid too
>
>             */
>
>             TP_ARGS(const char *, text),
>
>             /*
>
>             * TP_FIELDS describes how to write the fields of the trace
> event.
>
>             * You can use the args here
>
>             */
>
>             TP_FIELDS(
>
>             /*
>
>             * The ctf_string macro takes a C string and writes it into a
> field
>
>             * named "message"
>
>             */
>
>                         ctf_string(message, text)
>
>             )
>
> )
>
> /*
>
> * Trace loglevel, shows the level of the trace event. It can be
> TRACE_EMERG,
>
> * TRACE_ALERT, TRACE_CRIT, TRACE_ERR, TRACE_WARNING, TRACE_INFO, etc.
>
> * If this is not set, TRACE_DEFAULT is assumed.
>
> * The first two arguments identify the tracepoint.
>
> * See details in <lttng/tracepoint.h> line 347
>
> */
>
> TRACEPOINT_LOGLEVEL(
>
>        /*
>
>         * The provider name, must be the same as the provider name in the
>
>         * TRACEPOINT_EVENT and as TRACEPOINT_PROVIDER above.
>
>         */
>
>             sample_component,
>
>        /*
>
>         * The tracepoint name, must be the same as the tracepoint name in
> the
>
>         * TRACEPOINT_EVENT
>
>         */
>
>             event,
>
>        /*
>
>         * The tracepoint loglevel. WARNING: Some levels are abbreviated and
>
>         * others are not, please see <lttng/tracepoint.h>
>
>         */
>
>             TRACE_WARNING
>
> )
>
>  (more tracepoints...)
>
>
>
> /*
>
> * Add this macro and its matching element to make sure the program
>
> * works in C++.
>
> */
>
> #ifdef __cplusplus
>
> }
>
> #endif /* __cplusplus */
>
> /*
>
> * Add this after defining the tracepoint events to expand the macros.
>
> */
>
> #include <lttng/tracepoint-event.h>
>
> #endif /* _SAMPLE_COMPONENT_PROVIDER_H */
>
> #####
>
> The relevant Makefile fragments:
> #####
> CC = gcc
> LIBUST = -llttng-ust
>
> LOCAL_CPPFLAGS += -I. $(AM_CPPFLAGS)
> LDFLAGS += -L/usr/local/lib $(AM_LDFLAGS)
> SOFLAGS = -fPIC
> SOVERSION_MAJOR = 1
> SOVERSION_MINOR = 0
>
> libtp.so: libtp.o
>
>             @echo "~~~~~~Packaging $@:"
>
>             $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR)
> -Wl,-no-as-needed \
>
>                -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS)
> $(LIBUST) $<
>
>             ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
> $@.$(SOVERSION_MAJOR)
>
>             ln -sf $@.$(SOVERSION_MAJOR) $@
>
>
>
> libtp.o: tp.c tp.h
>
>             @echo "~~~~~~Compiling $@:"
>
>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(SOFLAGS) -c -o $@ $<
>
>
> > 1) Also will this solution scale if my binary depends on lots
> of libraries which are instrumented?
>
>
>
> Sure.  I'd expect linear scaling.  Each library, upon being loaded, looks
> for its tracepoint provider and turns its tracepoints off if they're not
> found.
>
>
>
> > 2) i'm fine with linking statically, can we avoid LD_PRELOAD?
>
>
>
> Besides the LD_PRELOAD technique, you could also use LD_LIBRARY_PATH, but
> that works only if the application statically includes the tracepoint
> provider (I suppose it would likewise work for an instrumented shared
> object only if it statically includes the tracepoint provider).
>
>
>
> You could also add "-Wl,-rpath,'$$ORIGIN'" to the linker call to add an
> RPATH tag to the application (or shared object).  This makes it look for
> its dependencies in its starting directory ($ORIGIN).  RPATH is, unlike
> RUNPATH, applicable to libraries as well: a library with an RPATH tag will
> look there for its dependencies; failing its own RPATH, it will use its
> executable's RPATH.
>
>
>
> Finally, you can dynamically include the tracepoint provider (libtp) as a
> dependency.  The application (sample_static_aware) is then statically aware
> of libtp and won't run without it.  The application (sample_dynamic) can
> alternately dynamically include the tracepoint provider *without* static
> awareness.  Here's how it's done:
>
>
>
> LIBDL = -ldl # On Linux
>
> #LIBDL = -lc # On BSD
>
> TP_DEFINE = -D TRACEPOINT_DEFINE
>
> TP_DEFINE_DYNAMIC = $(TP_DEFINE) -D TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>
>
>
> #(the inclusion of a libtp NEEDED tag requires "-no-as-needed -ltp").
>
> #Note that "-L. -ltp", when used, should appear before $(LDFLAGS) $(LIBDL).
>
> static_aware: static.o libtp.so
>
>             @echo "~~~~~~Linking sample_$@:"
>
> #          $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS)
> $(LIBDL) \
>
> #             -Wl,-rpath,'$$ORIGIN',--enable-new-dtags
>
>             $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS)
> $(LIBDL)
>
>             @echo "   Use 'LD_PRELOAD=./libtp.so ./sample_$@' to run
> sample_$@"
>
>
>
> static.o: sample.c tp.h
>
>             @echo "~~~~~~Compiling $@:"
>
>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE) -c -o $@ $<
>
>
>
> #If not preloaded, the sample application runs but won't be traceable.
>
> #Putting libtp in the path won't work: the sample does not look for it.
>
> dynamic: dynamic.o libtp.so
>
>             @echo "~~~~~~Linking sample_$@:"
>
>             $(CC) -o sample_$@ $< $(LDFLAGS) $(LIBDL)
>
>             @echo "   Use '[LD_PRELOAD=./libtp.so] ./sample_$@' to run
> sample_$@"
>
>
>
> #Compare with the 'static.o' target.
>
> dynamic.o: sample.c tp.h
>
>             @echo "~~~~~~Compiling $@:"
>
>             $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE_DYNAMIC) \
>
>                -c -o $@ $<
>
>
>
>    The case where the app isn't traced but the library it uses is traced
> should be a variation on this.  I'll try it out sometime in the near
> future, but you should be able to figure it out from the above.  Here's a
> first guess (it may need $(LIBDL) alongside $(LIBUST)):
>
>
>
> libtp.so: libtp.o
>
>             @echo "~~~~~~Packaging $@:"
>
>             $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR)
> -Wl,-no-as-needed -L. -ltp \
>
>                -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS)
> $(LIBUST) $<
>
>             ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
> $@.$(SOVERSION_MAJOR)
>
>             ln -sf $@.$(SOVERSION_MAJOR) $@
>
>
>
>
>
> > 3) Is there any page which explains on why and how to use
>
> > TRACEPOINT_PROVIDER, TRACEPOINT_CREATE_PROBES, TRACEPOINT_INCLUDE,
> TRACEPOINT_DEFINE, TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>
>
>
> They're reasonably explained in the demonstration apps.  I discuss them a
> little more in depth in the forthcoming LTTng Comprehensive User's Guide (I
> could send you a copy of the draft, as we've just begun its first review
> round).
>
>
>
> > my tp.h is, are there any errors in this?
>
> > #############
>
>
>
> #undef TRACEPOINT_PROVIDER
>
>
>
> > #define TRACEPOINT_PROVIDER sample_component
>
> >
>
> > #undef TRACEPOINT_INCLUDE
>
> > #define TRACEPOINT_INCLUDE "./tp.h"
>
> >
>
> > #if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
>
> > #define _TP_H
>
>
>
> (Ideally, use _SAMPLE_COMPONENT_PROVIDER_H instead of _TP_H)
>
>
>
> > #include <lttng/tracepoint.h>
>
>
>
> #ifdef __cplusplus
>
> extern "C" {
>
> #endif /* __cplusplus */
>
>
>
> > TRACEPOINT_EVENT(
>
> >        sample_component,
>
> >        event,
>
> >        TP_ARGS(char *, text),
>
>
>
> (the compiler may be happier with const char * instead)
>
>
>
> >        TP_FIELDS(
>
> >                ctf_string(message, text)
>
> >        )
>
> >)
>
> > TRACEPOINT_LOGLEVEL(
>
> >        sample_component,
>
> >        event,
>
> >        TRACE_WARNING)
>
>
>
> #ifdef __cplusplus
>
> }
>
> #endif /* __cplusplus */
>
>
>
> > #endif /* _TP_H */
>
> > #include <lttng/tracepoint-event.h>
>
>
>
> (move #include <lttng/tracepoint-event.h> inside of the #if
> !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ))
>
>
>
> > #############
>
> >
>
> > Thanks,
>
> > Anand Neeli
>
>
>
>    One key change I made to my sample applications is to remove the
> "#define TRACEPOINT_DEFINE" that precedes the "#include "tp.h"" line.  I
> prefer to control that #define using a compiler -D option.  It makes the
> makefile clearer and resolves the problem of making sure there is just one
> module that turns that #define on.
>
>
>
>    Hope this helps.
>
>
>
> Daniel U. Thibault
> Protection des systèmes et contremesures (PSC) | Systems Protection &
> Countermeasures (SPC)
> Cyber sécurité pour les missions essentielles (CME) | Mission Critical
> Cyber Security (MCCS)
> R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D
> Canada - Valcartier (DRDC Valcartier)
> 2459 route de la Bravoure
> Québec QC  G3J 1X5
> CANADA
> Vox : (418) 844-4000 x4245
> Fax : (418) 844-4538
> NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ<http://--ESFSECEV-TY3011-------------------------------->
> >
> Gouvernement du Canada | Government of Canada
> <http://www.valcartier.drdc-rddc.gc.ca/<http://--ESFSECEV-TY3011--------------------->
> >
>

[-- Attachment #1.2: Type: text/html, Size: 48417 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found] ` <CAM5kDqy62zjzLddVkRvg94jAxSCSN0uFqxmJL7RwN6XN31x0Jw@mail.gmail.com>
  2014-04-04 14:43   ` Thibault, Daniel
@ 2014-04-04 14:46   ` Jérémie Galarneau
       [not found]   ` <48CF5AC71E61DB46B70D0F388054EFFD3599315B@VAL-E-02.valcartier.drdc-rddc.gc.ca>
  2 siblings, 0 replies; 13+ messages in thread
From: Jérémie Galarneau @ 2014-04-04 14:46 UTC (permalink / raw)
  To: Anand Neeli; +Cc: lttng-dev, Thibault, Daniel

On Fri, Apr 4, 2014 at 1:44 AM, Anand Neeli <anand.neeli@gmail.com> wrote:
> Hi Daniel,
> Thanks for your reply.
> sorry for my ignorance but how are you generating libtp.so in your example?
>
> 1) Also will this solution scale if my binary depends on lots of libraries
> which are instrumented?
>

It should have no impact on scalability.

> 2) i'm fine with linking statically, can we avoid LD_PRELOAD?
>

Absolutely, you can link the providers in your application directly.
The advantage of using LD_PRELOAD is to make sure your application has
no dependency on lttng-ust.so.

Please refer to the "BUILDING/LINKING THE TRACEPOINT PROVIDER" section
in the LTTNG-UST(3) man page.

The lttng-ust/doc/examples/ folder also contains Makefiles to show you
how to link tracepoints providers to your application either
statically or dynamically.

> 3) Is there any page which explains on why and how to use
> TRACEPOINT_PROVIDER, TRACEPOINT_CREATE_PROBES, TRACEPOINT_INCLUDE,
> TRACEPOINT_DEFINE, TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>

Not really. Hopefully I'll make this clear without delving in
implementation details...

TRACEPOINT_PROVIDER must be defined to the name of your tracepoint provider.

TRACEPOINT_INCLUDE must provide a path to the current include file.

TRACEPOINT_PROBE_DYNAMIC_LINKAGE is pretty self explanatory. It will
make sure that no unresolved symbols are emited by lttng/tracepoint.h.
This way the tracee can be built without having to resolve a symbol
defined in the provider.

TRACEPOINT_DEFINE, as noted in the lttng-ust manpage, should be
defined before you include the tracepoint headers in the .c file where
they'll be used.

TRACEPOINT_CREATE_PROBES will be expanded to everything that is needed
in your provider object.

Again, taking a look at the examples should help you make sense of how
to instrument an application.

Regards,
Jérémie

>
> my tp.h is, are there any errors in this?
> #############
> #define TRACEPOINT_PROVIDER sample_component
>
> #undef TRACEPOINT_INCLUDE
> #define TRACEPOINT_INCLUDE "./tp.h"
>
> #if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
> #define _TP_H
>
> #include <lttng/tracepoint.h>
>
> TRACEPOINT_EVENT(
>         sample_component,
>         event,
>         TP_ARGS(char *, text),
>         TP_FIELDS(
>                 ctf_string(message, text)
>         )
> )
> TRACEPOINT_LOGLEVEL(
>         sample_component,
>         event,
>         TRACE_WARNING)
>
> #endif /* _TP_H */
> #include <lttng/tracepoint-event.h>
> #############
>
>
>
> Thanks,
> Anand Neeli
>
>
> On Thu, Apr 3, 2014 at 9:35 PM, Thibault, Daniel
> <Daniel.Thibault@drdc-rddc.gc.ca> wrote:
>>
>> ----------------------------------------------------------------------
>> Date: Thu, 3 Apr 2014 16:55:38 +0530
>> From: Anand Neeli <anand.neeli@gmail.com>
>> To: "lttng-dev@lists.lttng.org" <lttng-dev@lists.lttng.org>
>>
>> > I have a library which is instrumented and tracepoints are added. And I
>> > have 2 binary's (or daemons) which try to include this library. (one
>> > binary
>> > has instrumented code with tracepoints and other binary doesn't use
>> > tracing)
>> >
>> > I found that i need to instrument the daemon which includes the
>> > instrumented library for the code to compile.
>> >
>> > Can't I have a daemon (without tracing functionality) which can include
>> > an
>> > instrumented library (i don't want to use tracing functionality in this
>> > case)
>> >
>> > I'm only able to build if both library and daemon which includes it are
>> > instrumented.
>> >
>> > Can anyone please give me more details on how to do this?
>> > This is useful for huge code bases where you can selectively add tracing
>> > support to few libraries or daemons.
>> >
>> > Anand Neeli
>>
>>    It can be done.  An uninstrumented app can rely on an instrumented
>> shared object; whether the latter produces lttng events then depends on
>> whether or not the tracepoint provider shared object is loaded when the app
>> is invoked (using LD_PRELOAD).
>>
>>    Here is sample_neeli.c:
>> #####
>> #include <stdio.h> //For printf
>> #include <unistd.h>
>>
>> #include "cobject.h"
>> int main(int argc, char **argv)
>> {
>>         int i = 0;
>>         char themessage[20]; //Can hold up to "Hello World 9999999\0"
>>
>>         fprintf(stderr, "sample_neeli starting\n");
>>         for (i = 0; i < 10000; i++) {
>>                 //We either prepare themessage in this module, or rely on
>> an
>>                 //external shared object
>>                 cobject_message(themessage, i);
>>                 usleep(1);
>>         }
>>         fprintf(stderr, "sample_neeli done\n");
>>         return 0;
>> }
>> #####
>> cobject.c:
>> #####
>> #include <stdio.h> //For printf
>> #include <unistd.h>
>>
>> #include "tp.h"
>>
>> void cobject_message(char *themessage, int i)
>> {
>>         tracepoint(sample_component, event, "cobject_message");
>>         sprintf(themessage, "CObject %u", i);
>> }
>> #####
>> cobject.h:
>> #####
>> extern void cobject_message(char *themessage, int i);
>> #####
>> The tracepoint provider code should be easy to guess.
>>
>> The relevant Makefile fragments:
>> #####
>> CC = gcc
>> LIBDL = -ldl # On Linux
>> #LIBDL = -lc # On BSD
>> LOCAL_CPPFLAGS += -I. $(AM_CPPFLAGS)
>> LDFLAGS += -L/usr/local/lib $(AM_LDFLAGS)
>> SOFLAGS = -fPIC
>> TP_DEFINE = -D TRACEPOINT_DEFINE
>> TP_DEFINE_DYNAMIC = $(TP_DEFINE) -D TRACEPOINT_PROBE_DYNAMIC_LINKAGE
>> SOVERSION_MAJOR = 1
>> SOVERSION_MINOR = 0
>>
>> libcobject.so: libcobject.o
>>         @echo "~~~~~~Packaging $@:"
>>         $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR) -Wl,-no-as-needed
>> \
>>            -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $^
>>         ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
>> $@.$(SOVERSION_MAJOR)
>>         ln -sf $@.$(SOVERSION_MAJOR) $@
>>
>> libcobject.o: cobject.c cobject.h tp.h
>>         @echo "~~~~~~Compiling $@:"
>>         $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(SOFLAGS)
>> $(TP_DEFINE_DYNAMIC) \
>>            -c -o $@ $<
>>
>> neeli_dynamic_lib:: neeli_dynamic_lib.o
>>         @echo "~~~~~~Linking sample_$@:"
>>         $(CC) -Wl,-no-as-needed -o $@ -L. -lcobject $^ $(LDFLAGS) \
>>            $(LIBDL) -Wl,-rpath,'$$ORIGIN',--enable-new-dtags
>>         @echo "   Use '[LD_PRELOAD=./libtp.so] ./$@' to run $@"
>>
>> neeli_dynamic_lib.o: sample_neeli.c cobject.h
>>         @echo "~~~~~~Compiling $@:"
>>         $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) -c -o $@ $<
>> #####
>>
>>    Running './neeli_dynamic_lib' yields no events.  Running
>> 'LD_PRELOAD=./libtp.so ./neeli_dynamic_lib' yields the libcobject.so events.
>>
>> Daniel U. Thibault
>> Protection des systèmes et contremesures (PSC) | Systems Protection &
>> Countermeasures (SPC)
>> Cyber sécurité pour les missions essentielles (CME) | Mission Critical
>> Cyber Security (MCCS)
>> R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D
>> Canada - Valcartier (DRDC Valcartier)
>> 2459 route de la Bravoure
>> Québec QC  G3J 1X5
>> CANADA
>> Vox : (418) 844-4000 x4245
>> Fax : (418) 844-4538
>> NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ>
>> Gouvernement du Canada | Government of Canada
>> <http://www.valcartier.drdc-rddc.gc.ca/>
>
>
>
> _______________________________________________
> lttng-dev mailing list
> lttng-dev@lists.lttng.org
> http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev
>



-- 
Jérémie Galarneau
EfficiOS Inc.
http://www.efficios.com

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found] ` <CAM5kDqy62zjzLddVkRvg94jAxSCSN0uFqxmJL7RwN6XN31x0Jw@mail.gmail.com>
@ 2014-04-04 14:43   ` Thibault, Daniel
  2014-04-04 14:46   ` Jérémie Galarneau
       [not found]   ` <48CF5AC71E61DB46B70D0F388054EFFD3599315B@VAL-E-02.valcartier.drdc-rddc.gc.ca>
  2 siblings, 0 replies; 13+ messages in thread
From: Thibault, Daniel @ 2014-04-04 14:43 UTC (permalink / raw)
  To: Anand Neeli; +Cc: lttng-dev


[-- Attachment #1.1: Type: text/plain, Size: 10936 bytes --]

De : Anand Neeli [mailto:anand.neeli@gmail.com]
Envoyé : 4 avril 2014 01:45

> Thanks for your reply.
> Sorry for my ignorance but how are you generating libtp.so in your example?

Non-boilerplate parts are in red.

tp.c:
#####
/*
* Defining macro creates the code objects of the traceprobes.
* Must be done only once per file (this #define controls tracepoint.h and
* tracepoint-event.h).
*/
#define TRACEPOINT_CREATE_PROBES
/*
* The header containing our TRACEPOINT_EVENTs.
*/
#include "tp.h"
#####
tp.h:
#####
#undef TRACEPOINT_PROVIDER
#define TRACEPOINT_PROVIDER sample_component
/*
* include file (this files's name)
*/
#undef TRACEPOINT_INCLUDE
#define TRACEPOINT_INCLUDE "./tp.h"
/*
* Add this precompiler conditional to ensure the tracepoint event generation
* can include this file more than once.
*/
#if !defined(_SAMPLE_COMPONENT_PROVIDER_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define _SAMPLE_COMPONENT_PROVIDER_H
/*
* Add this to allow programs to call "tracepoint(...)".
* This #include must not be within an extern "C" block; if it is,
* C++ instrumentation will fail when SystemTap is also installed.
* (This may have been fixed since I wrote this)
*/
#include <lttng/tracepoint.h>
/*
* Add this macro and its matching element to make sure the program
* works in C++.
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/*
* The following tracepoint event writes a message (C string) into the
* field "message" of the trace event "event" in the provider
* "sample_component" in other words:
*
*    sample_component:event:message = text.
*/
TRACEPOINT_EVENT(
            /*
            * provider name, not a variable but a string starting with a letter
            * and containing either letters, numbers or underscores.
            * Needs to be the same as TRACEPOINT_PROVIDER
            */
            sample_component,
            /*
            * tracepoint name, same format as sample provider. Does not need to be
            * declared before. in this case the name is "event"
            */
            event,
            /*
            * TP_ARGS macro contains the arguments passed for the tracepoint.
            * It is in the following format:
            *                     TP_ARGS( type1, name1, type2, name2, ... type10, name10)
            * where there can be from zero to ten elements.
            * "typeN" is the datatype, such as int, struct or double **.
            * "name" is the variable name (in "int myInt" the name would be "myInt")
            *                     TP_ARGS() is valid (no arguments)
            *                     TP_ARGS( void ) is valid too
            */
            TP_ARGS(const char *, text),
            /*
            * TP_FIELDS describes how to write the fields of the trace event.
            * You can use the args here
            */
            TP_FIELDS(
            /*
            * The ctf_string macro takes a C string and writes it into a field
            * named "message"
            */
                        ctf_string(message, text)
            )
)
/*
* Trace loglevel, shows the level of the trace event. It can be TRACE_EMERG,
* TRACE_ALERT, TRACE_CRIT, TRACE_ERR, TRACE_WARNING, TRACE_INFO, etc.
* If this is not set, TRACE_DEFAULT is assumed.
* The first two arguments identify the tracepoint.
* See details in <lttng/tracepoint.h> line 347
*/
TRACEPOINT_LOGLEVEL(
       /*
        * The provider name, must be the same as the provider name in the
        * TRACEPOINT_EVENT and as TRACEPOINT_PROVIDER above.
        */
            sample_component,
       /*
        * The tracepoint name, must be the same as the tracepoint name in the
        * TRACEPOINT_EVENT
        */
            event,
       /*
        * The tracepoint loglevel. WARNING: Some levels are abbreviated and
        * others are not, please see <lttng/tracepoint.h>
        */
            TRACE_WARNING
)
(more tracepoints...)

/*
* Add this macro and its matching element to make sure the program
* works in C++.
*/
#ifdef __cplusplus
}
#endif /* __cplusplus */
/*
* Add this after defining the tracepoint events to expand the macros.
*/
#include <lttng/tracepoint-event.h>
#endif /* _SAMPLE_COMPONENT_PROVIDER_H */
#####
The relevant Makefile fragments:
#####
CC = gcc
LIBUST = -llttng-ust
LOCAL_CPPFLAGS += -I. $(AM_CPPFLAGS)
LDFLAGS += -L/usr/local/lib $(AM_LDFLAGS)
SOFLAGS = -fPIC
SOVERSION_MAJOR = 1
SOVERSION_MINOR = 0

libtp.so: libtp.o
            @echo "~~~~~~Packaging $@:"
            $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR) -Wl,-no-as-needed \
               -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS) $(LIBUST) $<
            ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $@.$(SOVERSION_MAJOR)
            ln -sf $@.$(SOVERSION_MAJOR) $@

libtp.o: tp.c tp.h
            @echo "~~~~~~Compiling $@:"
            $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(SOFLAGS) -c -o $@ $<

> 1) Also will this solution scale if my binary depends on lots of libraries which are instrumented?

Sure.  I'd expect linear scaling.  Each library, upon being loaded, looks for its tracepoint provider and turns its tracepoints off if they're not found.

> 2) i'm fine with linking statically, can we avoid LD_PRELOAD?

Besides the LD_PRELOAD technique, you could also use LD_LIBRARY_PATH, but that works only if the application statically includes the tracepoint provider (I suppose it would likewise work for an instrumented shared object only if it statically includes the tracepoint provider).

You could also add "-Wl,-rpath,'$$ORIGIN'" to the linker call to add an RPATH tag to the application (or shared object).  This makes it look for its dependencies in its starting directory ($ORIGIN).  RPATH is, unlike RUNPATH, applicable to libraries as well: a library with an RPATH tag will look there for its dependencies; failing its own RPATH, it will use its executable's RPATH.

Finally, you can dynamically include the tracepoint provider (libtp) as a dependency.  The application (sample_static_aware) is then statically aware of libtp and won't run without it.  The application (sample_dynamic) can alternately dynamically include the tracepoint provider without static awareness.  Here's how it's done:

LIBDL = -ldl # On Linux
#LIBDL = -lc # On BSD
TP_DEFINE = -D TRACEPOINT_DEFINE
TP_DEFINE_DYNAMIC = $(TP_DEFINE) -D TRACEPOINT_PROBE_DYNAMIC_LINKAGE

#(the inclusion of a libtp NEEDED tag requires "-no-as-needed -ltp").
#Note that "-L. -ltp", when used, should appear before $(LDFLAGS) $(LIBDL).
static_aware: static.o libtp.so
            @echo "~~~~~~Linking sample_$@:"
#          $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS) $(LIBDL) \
#             -Wl,-rpath,'$$ORIGIN',--enable-new-dtags
            $(CC) -Wl,-no-as-needed -o sample_$@ -L. -ltp $< $(LDFLAGS) $(LIBDL)
            @echo "   Use 'LD_PRELOAD=./libtp.so ./sample_$@' to run sample_$@"

static.o: sample.c tp.h
            @echo "~~~~~~Compiling $@:"
            $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE) -c -o $@ $<

#If not preloaded, the sample application runs but won't be traceable.
#Putting libtp in the path won't work: the sample does not look for it.
dynamic: dynamic.o libtp.so
            @echo "~~~~~~Linking sample_$@:"
            $(CC) -o sample_$@ $< $(LDFLAGS) $(LIBDL)
            @echo "   Use '[LD_PRELOAD=./libtp.so] ./sample_$@' to run sample_$@"

#Compare with the 'static.o' target.
dynamic.o: sample.c tp.h
            @echo "~~~~~~Compiling $@:"
            $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(TP_DEFINE_DYNAMIC) \
               -c -o $@ $<

   The case where the app isn't traced but the library it uses is traced should be a variation on this.  I'll try it out sometime in the near future, but you should be able to figure it out from the above.  Here's a first guess (it may need $(LIBDL) alongside $(LIBUST)):

libtp.so: libtp.o
            @echo "~~~~~~Packaging $@:"
            $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR) -Wl,-no-as-needed -L. -ltp \
               -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $(LDFLAGS) $(LIBUST) $<
            ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $@.$(SOVERSION_MAJOR)
            ln -sf $@.$(SOVERSION_MAJOR) $@


> 3) Is there any page which explains on why and how to use
> TRACEPOINT_PROVIDER, TRACEPOINT_CREATE_PROBES, TRACEPOINT_INCLUDE, TRACEPOINT_DEFINE, TRACEPOINT_PROBE_DYNAMIC_LINKAGE

They're reasonably explained in the demonstration apps.  I discuss them a little more in depth in the forthcoming LTTng Comprehensive User's Guide (I could send you a copy of the draft, as we've just begun its first review round).

> my tp.h is, are there any errors in this?
> #############

#undef TRACEPOINT_PROVIDER

> #define TRACEPOINT_PROVIDER sample_component
>
> #undef TRACEPOINT_INCLUDE
> #define TRACEPOINT_INCLUDE "./tp.h"
>
> #if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
> #define _TP_H

(Ideally, use _SAMPLE_COMPONENT_PROVIDER_H instead of _TP_H)

> #include <lttng/tracepoint.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

> TRACEPOINT_EVENT(
>        sample_component,
>        event,
>        TP_ARGS(char *, text),

(the compiler may be happier with const char * instead)

>        TP_FIELDS(
>                ctf_string(message, text)
>        )
>)
> TRACEPOINT_LOGLEVEL(
>        sample_component,
>        event,
>        TRACE_WARNING)

#ifdef __cplusplus
}
#endif /* __cplusplus */

> #endif /* _TP_H */
> #include <lttng/tracepoint-event.h>

(move #include <lttng/tracepoint-event.h> inside of the #if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ))

> #############
>
> Thanks,
> Anand Neeli

   One key change I made to my sample applications is to remove the "#define TRACEPOINT_DEFINE" that precedes the "#include "tp.h"" line.  I prefer to control that #define using a compiler -D option.  It makes the makefile clearer and resolves the problem of making sure there is just one module that turns that #define on.

   Hope this helps.

Daniel U. Thibault
Protection des systèmes et contremesures (PSC) | Systems Protection & Countermeasures (SPC)
Cyber sécurité pour les missions essentielles (CME) | Mission Critical Cyber Security (MCCS)
R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D Canada - Valcartier (DRDC Valcartier)
2459 route de la Bravoure
Québec QC  G3J 1X5
CANADA
Vox : (418) 844-4000 x4245
Fax : (418) 844-4538
NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ<--ESFSECEV-TY3011-------------------------------->>
Gouvernement du Canada | Government of Canada
<http://www.valcartier.drdc-rddc.gc.ca/<--ESFSECEV-TY3011--------------------->>

[-- Attachment #1.2: Type: text/html, Size: 48028 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: instrumenting shared library
       [not found] <48CF5AC71E61DB46B70D0F388054EFFD35992F74@VAL-E-02.valcartier.drdc-rddc.gc.ca>
@ 2014-04-04  5:44 ` Anand Neeli
       [not found] ` <CAM5kDqy62zjzLddVkRvg94jAxSCSN0uFqxmJL7RwN6XN31x0Jw@mail.gmail.com>
  1 sibling, 0 replies; 13+ messages in thread
From: Anand Neeli @ 2014-04-04  5:44 UTC (permalink / raw)
  To: Thibault, Daniel; +Cc: lttng-dev


[-- Attachment #1.1: Type: text/plain, Size: 5788 bytes --]

Hi Daniel,
Thanks for your reply.
sorry for my ignorance but how are you generating libtp.so in your example?

1) Also will this solution scale if my binary depends on lots of libraries
which are instrumented?

2) i'm fine with linking statically, can we avoid LD_PRELOAD?

3) Is there any page which explains on why and how to use
TRACEPOINT_PROVIDER, TRACEPOINT_CREATE_PROBES, TRACEPOINT_INCLUDE,
TRACEPOINT_DEFINE, TRACEPOINT_PROBE_DYNAMIC_LINKAGE


my tp.h is, are there any errors in this?
#############
#define TRACEPOINT_PROVIDER sample_component

#undef TRACEPOINT_INCLUDE
#define TRACEPOINT_INCLUDE "./tp.h"

#if !defined(_TP_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
#define _TP_H

#include <lttng/tracepoint.h>

TRACEPOINT_EVENT(
        sample_component,
        event,
        TP_ARGS(char *, text),
        TP_FIELDS(
                ctf_string(message, text)
        )
)
TRACEPOINT_LOGLEVEL(
        sample_component,
        event,
        TRACE_WARNING)

#endif /* _TP_H */
#include <lttng/tracepoint-event.h>
#############



Thanks,
Anand Neeli


On Thu, Apr 3, 2014 at 9:35 PM, Thibault, Daniel <
Daniel.Thibault@drdc-rddc.gc.ca> wrote:

> ----------------------------------------------------------------------
> Date: Thu, 3 Apr 2014 16:55:38 +0530
> From: Anand Neeli <anand.neeli@gmail.com>
> To: "lttng-dev@lists.lttng.org" <lttng-dev@lists.lttng.org>
>
> > I have a library which is instrumented and tracepoints are added. And I
> > have 2 binary's (or daemons) which try to include this library. (one
> binary
> > has instrumented code with tracepoints and other binary doesn't use
> > tracing)
> >
> > I found that i need to instrument the daemon which includes the
> > instrumented library for the code to compile.
> >
> > Can't I have a daemon (without tracing functionality) which can include
> an
> > instrumented library (i don't want to use tracing functionality in this
> > case)
> >
> > I'm only able to build if both library and daemon which includes it are
> > instrumented.
> >
> > Can anyone please give me more details on how to do this?
> > This is useful for huge code bases where you can selectively add tracing
> > support to few libraries or daemons.
> >
> > Anand Neeli
>
>    It can be done.  An uninstrumented app can rely on an instrumented
> shared object; whether the latter produces lttng events then depends on
> whether or not the tracepoint provider shared object is loaded when the app
> is invoked (using LD_PRELOAD).
>
>    Here is sample_neeli.c:
> #####
> #include <stdio.h> //For printf
> #include <unistd.h>
>
> #include "cobject.h"
> int main(int argc, char **argv)
> {
>         int i = 0;
>         char themessage[20]; //Can hold up to "Hello World 9999999\0"
>
>         fprintf(stderr, "sample_neeli starting\n");
>         for (i = 0; i < 10000; i++) {
>                 //We either prepare themessage in this module, or rely on
> an
>                 //external shared object
>                 cobject_message(themessage, i);
>                 usleep(1);
>         }
>         fprintf(stderr, "sample_neeli done\n");
>         return 0;
> }
> #####
> cobject.c:
> #####
> #include <stdio.h> //For printf
> #include <unistd.h>
>
> #include "tp.h"
>
> void cobject_message(char *themessage, int i)
> {
>         tracepoint(sample_component, event, "cobject_message");
>         sprintf(themessage, "CObject %u", i);
> }
> #####
> cobject.h:
> #####
> extern void cobject_message(char *themessage, int i);
> #####
> The tracepoint provider code should be easy to guess.
>
> The relevant Makefile fragments:
> #####
> CC = gcc
> LIBDL = -ldl # On Linux
> #LIBDL = -lc # On BSD
> LOCAL_CPPFLAGS += -I. $(AM_CPPFLAGS)
> LDFLAGS += -L/usr/local/lib $(AM_LDFLAGS)
> SOFLAGS = -fPIC
> TP_DEFINE = -D TRACEPOINT_DEFINE
> TP_DEFINE_DYNAMIC = $(TP_DEFINE) -D TRACEPOINT_PROBE_DYNAMIC_LINKAGE
> SOVERSION_MAJOR = 1
> SOVERSION_MINOR = 0
>
> libcobject.so: libcobject.o
>         @echo "~~~~~~Packaging $@:"
>         $(CC) -shared -Wl,-soname,$@.$(SOVERSION_MAJOR) -Wl,-no-as-needed \
>            -o $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR) $^
>         ln -sf $@.$(SOVERSION_MAJOR).$(SOVERSION_MINOR)
> $@.$(SOVERSION_MAJOR)
>         ln -sf $@.$(SOVERSION_MAJOR) $@
>
> libcobject.o: cobject.c cobject.h tp.h
>         @echo "~~~~~~Compiling $@:"
>         $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) $(SOFLAGS)
> $(TP_DEFINE_DYNAMIC) \
>            -c -o $@ $<
>
> neeli_dynamic_lib:: neeli_dynamic_lib.o
>         @echo "~~~~~~Linking sample_$@:"
>         $(CC) -Wl,-no-as-needed -o $@ -L. -lcobject $^ $(LDFLAGS) \
>            $(LIBDL) -Wl,-rpath,'$$ORIGIN',--enable-new-dtags
>         @echo "   Use '[LD_PRELOAD=./libtp.so] ./$@' to run $@"
>
> neeli_dynamic_lib.o: sample_neeli.c cobject.h
>         @echo "~~~~~~Compiling $@:"
>         $(CC) $(CPPFLAGS) $(LOCAL_CPPFLAGS) -c -o $@ $<
> #####
>
>    Running './neeli_dynamic_lib' yields no events.  Running
> 'LD_PRELOAD=./libtp.so ./neeli_dynamic_lib' yields the libcobject.so events.
>
> Daniel U. Thibault
> Protection des systèmes et contremesures (PSC) | Systems Protection &
> Countermeasures (SPC)
> Cyber sécurité pour les missions essentielles (CME) | Mission Critical
> Cyber Security (MCCS)
> R & D pour la défense Canada - Valcartier (RDDC Valcartier) | Defence R&D
> Canada - Valcartier (DRDC Valcartier)
> 2459 route de la Bravoure
> Québec QC  G3J 1X5
> CANADA
> Vox : (418) 844-4000 x4245
> Fax : (418) 844-4538
> NAC : 918V QSDJ <http://www.travelgis.com/map.asp?addr=918V%20QSDJ>
> Gouvernement du Canada | Government of Canada
> <http://www.valcartier.drdc-rddc.gc.ca/>
>

[-- Attachment #1.2: Type: text/html, Size: 8398 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

* instrumenting shared library
@ 2014-04-03 11:25 Anand Neeli
  0 siblings, 0 replies; 13+ messages in thread
From: Anand Neeli @ 2014-04-03 11:25 UTC (permalink / raw)
  To: lttng-dev


[-- Attachment #1.1: Type: text/plain, Size: 854 bytes --]

Hi,

I have a library which is instrumented and tracepoints are added. And i
have 2 binary's(or daemons) which try to include this library.(one binary
has instrumented code with tracepoints and other binary doesn't use
tracing)
I found that i need to instrument the daemon which includes the
instrumented library for the code to compile.

Cant i have a daemon(without tracing functionality) which can include a
instrumented library (i don't want to use tracing functionality in this
case)
I'm only able to build if both library and daemon which includes it are
instrumented.

Can anyone please give me more details on how to do this?
this is useful for huge code bases where you can selectively add tracing
support to few librarys or daemons.


Hope i have written clearly, please ask me more if you are not able to
follow my query.

Thanks,
Anand Neeli

[-- Attachment #1.2: Type: text/html, Size: 1103 bytes --]

[-- Attachment #2: Type: text/plain, Size: 155 bytes --]

_______________________________________________
lttng-dev mailing list
lttng-dev@lists.lttng.org
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2014-04-07 15:27 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-03 16:05 instrumenting shared library Thibault, Daniel
     [not found] <48CF5AC71E61DB46B70D0F388054EFFD35992F74@VAL-E-02.valcartier.drdc-rddc.gc.ca>
2014-04-04  5:44 ` Anand Neeli
     [not found] ` <CAM5kDqy62zjzLddVkRvg94jAxSCSN0uFqxmJL7RwN6XN31x0Jw@mail.gmail.com>
2014-04-04 14:43   ` Thibault, Daniel
2014-04-04 14:46   ` Jérémie Galarneau
     [not found]   ` <48CF5AC71E61DB46B70D0F388054EFFD3599315B@VAL-E-02.valcartier.drdc-rddc.gc.ca>
2014-04-04 20:16     ` Anand Neeli
     [not found]     ` <CAM5kDqyCTjKLWhR5XXT9DvXHaniOnJy0SPSDOMPw3eCSD7Z6Uw@mail.gmail.com>
2014-04-04 20:33       ` Thibault, Daniel
2014-04-05  6:44       ` Lingyu Zhu
     [not found]       ` <CACFGcbbmW0mc3GHa9VYBQLiS6zrm1gQB8bkYMBFadnvM7QKeeQ@mail.gmail.com>
2014-04-05  9:56         ` Anand Neeli
     [not found]         ` <CAM5kDqySXuNqYcdjy+kgs-h5cDdiQSioumUX449Gfrcgg+HUbw@mail.gmail.com>
2014-04-05 12:14           ` Lingyu Zhu
2014-04-07 13:23           ` Thibault, Daniel
     [not found]           ` <48CF5AC71E61DB46B70D0F388054EFFD35993659@VAL-E-02.valcartier.drdc-rddc.gc.ca>
2014-04-07 14:37             ` Anand Neeli
     [not found]             ` <CAM5kDqykNCO_XVjg8bOzDLTZ06Cja2UwdS4ZkHLpJrs9GR_sqw@mail.gmail.com>
2014-04-07 15:27               ` Thibault, Daniel
  -- strict thread matches above, loose matches on Subject: below --
2014-04-03 11:25 Anand Neeli

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.