1 /* Copyright (C) 2009 Pierre-Marc Fournier
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <sys/types.h>
23 #include <sys/socket.h>
29 #include <urcu/uatomic_arch.h>
31 #include <ust/marker.h>
32 #include <ust/tracectl.h>
37 #include "marker-control.h"
41 #define USTSIGNAL SIGIO
43 #define MAX_MSG_SIZE (100)
45 #define MSG_REGISTER_NOTIF 2
47 char consumer_stack
[10000];
49 /* This should only be accessed by the constructor, before the creation
50 * of the listener, and then only by the listener.
54 struct list_head blocked_consumers
= LIST_HEAD_INIT(blocked_consumers
);
56 static struct ustcomm_app ustcomm_app
;
58 struct tracecmd
{ /* no padding */
63 /* volatile because shared between the listener and the main thread */
64 volatile sig_atomic_t buffers_to_export
= 0;
67 /* size: the size of all the fields except size itself */
70 /* Only the necessary part of the payload is transferred. It
71 * may even be none of it.
76 struct consumer_channel
{
78 struct ltt_channel_struct
*chan
;
81 struct blocked_consumer
{
86 /* args to ustcomm_send_reply */
87 struct ustcomm_server server
;
88 struct ustcomm_source src
;
90 /* args to ust_buffers_get_subbuf */
91 struct ust_buffer
*buf
;
93 struct list_head list
;
96 static long long make_pidunique(void)
101 gettimeofday(&tv
, NULL
);
105 retval
|= tv
.tv_usec
;
110 static void print_markers(FILE *fp
)
112 struct marker_iter iter
;
115 marker_iter_reset(&iter
);
116 marker_iter_start(&iter
);
119 fprintf(fp
, "marker: %s/%s %d \"%s\" %p\n", iter
.marker
->channel
, iter
.marker
->name
, (int)imv_read(iter
.marker
->state
), iter
.marker
->format
, iter
.marker
->location
);
120 marker_iter_next(&iter
);
125 static int init_socket(void);
131 struct trctl_msg msg
;
133 /* FIXME: fd_notif should probably be protected by a spinlock */
138 msg
.type
= MSG_NOTIF
;
139 msg
.size
= sizeof(msg
.type
);
141 /* FIXME: don't block here */
142 result
= write(fd_notif
, &msg
, msg
.size
+sizeof(msg
.size
));
149 /* Ask the daemon to collect a trace called trace_name and being
150 * produced by this pid.
152 * The trace must be at least allocated. (It can also be started.)
153 * This is because _ltt_trace_find is used.
156 static void inform_consumer_daemon(const char *trace_name
)
159 struct ust_trace
*trace
;
160 pid_t pid
= getpid();
165 trace
= _ltt_trace_find(trace_name
);
167 WARN("inform_consumer_daemon: could not find trace \"%s\"; it is probably already destroyed", trace_name
);
171 for(i
=0; i
< trace
->nr_channels
; i
++) {
172 /* iterate on all cpus */
173 for(j
=0; j
<trace
->channels
[i
].n_cpus
; j
++) {
175 asprintf(&buf
, "%s_%d", trace
->channels
[i
].channel_name
, j
);
176 result
= ustcomm_request_consumer(pid
, buf
);
178 WARN("Failed to request collection for channel %s. Is the daemon available?", trace
->channels
[i
].channel_name
);
179 /* continue even if fail */
190 void process_blocked_consumers(void)
194 struct blocked_consumer
*bc
;
199 list_for_each_entry(bc
, &blocked_consumers
, list
) {
203 fds
= (struct pollfd
*) malloc(n_fds
* sizeof(struct pollfd
));
205 ERR("malloc returned NULL");
209 list_for_each_entry(bc
, &blocked_consumers
, list
) {
210 fds
[idx
].fd
= bc
->fd_producer
;
211 fds
[idx
].events
= POLLIN
;
212 bc
->tmp_poll_idx
= idx
;
216 while((result
= poll(fds
, n_fds
, 0)) == -1 && errno
== EINTR
)
223 list_for_each_entry(bc
, &blocked_consumers
, list
) {
224 if(fds
[bc
->tmp_poll_idx
].revents
) {
225 long consumed_old
= 0;
228 result
= read(bc
->fd_producer
, &inbuf
, 1);
236 close(bc
->fd_producer
);
240 result
= ustcomm_send_reply(&bc
->server
, "END", &bc
->src
);
242 ERR("ustcomm_send_reply failed");
249 result
= ust_buffers_get_subbuf(bc
->buf
, &consumed_old
);
250 if(result
== -EAGAIN
) {
251 WARN("missed buffer?");
254 else if(result
< 0) {
255 DBG("ust_buffers_get_subbuf: error: %s", strerror(-result
));
257 asprintf(&reply
, "%s %ld", "OK", consumed_old
);
258 result
= ustcomm_send_reply(&bc
->server
, reply
, &bc
->src
);
260 ERR("ustcomm_send_reply failed");
272 void seperate_channel_cpu(const char *channel_and_cpu
, char **channel
, int *cpu
)
276 sep
= rindex(channel_and_cpu
, '_');
279 sep
= channel_and_cpu
+ strlen(channel_and_cpu
);
285 asprintf(channel
, "%.*s", (int)(sep
-channel_and_cpu
), channel_and_cpu
);
288 static int do_cmd_get_shmid(const char *recvbuf
, struct ustcomm_source
*src
)
291 struct ust_trace
*trace
;
292 char trace_name
[] = "auto";
294 char *channel_and_cpu
;
302 channel_and_cpu
= nth_token(recvbuf
, 1);
303 if(channel_and_cpu
== NULL
) {
304 ERR("cannot parse channel");
308 seperate_channel_cpu(channel_and_cpu
, &ch_name
, &ch_cpu
);
310 ERR("problem parsing channel name");
311 goto free_short_chan_name
;
315 trace
= _ltt_trace_find(trace_name
);
319 ERR("cannot find trace!");
321 goto free_short_chan_name
;
324 for(i
=0; i
<trace
->nr_channels
; i
++) {
325 struct ust_channel
*channel
= &trace
->channels
[i
];
326 struct ust_buffer
*buf
= channel
->buf
[ch_cpu
];
328 if(!strcmp(trace
->channels
[i
].channel_name
, ch_name
)) {
331 // DBG("the shmid for the requested channel is %d", buf->shmid);
332 // DBG("the shmid for its buffer structure is %d", channel->buf_struct_shmids);
333 asprintf(&reply
, "%d %d", buf
->shmid
, channel
->buf_struct_shmids
[ch_cpu
]);
335 result
= ustcomm_send_reply(&ustcomm_app
.server
, reply
, src
);
337 ERR("ustcomm_send_reply failed");
340 goto free_short_chan_name
;
351 ERR("channel not found (%s)", channel_and_cpu
);
354 free_short_chan_name
:
361 static int do_cmd_get_n_subbufs(const char *recvbuf
, struct ustcomm_source
*src
)
364 struct ust_trace
*trace
;
365 char trace_name
[] = "auto";
367 char *channel_and_cpu
;
373 DBG("get_n_subbufs");
375 channel_and_cpu
= nth_token(recvbuf
, 1);
376 if(channel_and_cpu
== NULL
) {
377 ERR("cannot parse channel");
381 seperate_channel_cpu(channel_and_cpu
, &ch_name
, &ch_cpu
);
383 ERR("problem parsing channel name");
384 goto free_short_chan_name
;
388 trace
= _ltt_trace_find(trace_name
);
392 ERR("cannot find trace!");
394 goto free_short_chan_name
;
397 for(i
=0; i
<trace
->nr_channels
; i
++) {
398 struct ust_channel
*channel
= &trace
->channels
[i
];
400 if(!strcmp(trace
->channels
[i
].channel_name
, ch_name
)) {
403 DBG("the n_subbufs for the requested channel is %d", channel
->subbuf_cnt
);
404 asprintf(&reply
, "%d", channel
->subbuf_cnt
);
406 result
= ustcomm_send_reply(&ustcomm_app
.server
, reply
, src
);
408 ERR("ustcomm_send_reply failed");
411 goto free_short_chan_name
;
420 ERR("unable to find channel");
423 free_short_chan_name
:
430 static int do_cmd_get_subbuf_size(const char *recvbuf
, struct ustcomm_source
*src
)
433 struct ust_trace
*trace
;
434 char trace_name
[] = "auto";
436 char *channel_and_cpu
;
442 DBG("get_subbuf_size");
444 channel_and_cpu
= nth_token(recvbuf
, 1);
445 if(channel_and_cpu
== NULL
) {
446 ERR("cannot parse channel");
450 seperate_channel_cpu(channel_and_cpu
, &ch_name
, &ch_cpu
);
452 ERR("problem parsing channel name");
453 goto free_short_chan_name
;
457 trace
= _ltt_trace_find(trace_name
);
461 ERR("cannot find trace!");
463 goto free_short_chan_name
;
466 for(i
=0; i
<trace
->nr_channels
; i
++) {
467 struct ust_channel
*channel
= &trace
->channels
[i
];
469 if(!strcmp(trace
->channels
[i
].channel_name
, ch_name
)) {
472 DBG("the subbuf_size for the requested channel is %zd", channel
->subbuf_size
);
473 asprintf(&reply
, "%zd", channel
->subbuf_size
);
475 result
= ustcomm_send_reply(&ustcomm_app
.server
, reply
, src
);
477 ERR("ustcomm_send_reply failed");
480 goto free_short_chan_name
;
489 ERR("unable to find channel");
492 free_short_chan_name
:
499 static unsigned int poweroftwo(unsigned int x
)
501 unsigned int power2
= 1;
502 unsigned int hardcoded
= 2147483648; /* FIX max 2^31 */
507 while (power2
< x
&& power2
< hardcoded
)
513 static int do_cmd_set_subbuf_size(const char *recvbuf
, struct ustcomm_source
*src
)
515 char *channel_slash_size
;
516 char ch_name
[256]="";
517 unsigned int size
, power
;
519 struct ust_trace
*trace
;
520 char trace_name
[] = "auto";
524 DBG("set_subbuf_size");
526 channel_slash_size
= nth_token(recvbuf
, 1);
527 sscanf(channel_slash_size
, "%255[^/]/%u", ch_name
, &size
);
529 if(ch_name
== NULL
) {
530 ERR("cannot parse channel");
534 power
= poweroftwo(size
);
536 WARN("using the next 2^n = %u\n", power
);
539 trace
= _ltt_trace_find_setup(trace_name
);
541 ERR("cannot find trace!");
546 for(i
= 0; i
< trace
->nr_channels
; i
++) {
547 struct ust_channel
*channel
= &trace
->channels
[i
];
549 if(!strcmp(trace
->channels
[i
].channel_name
, ch_name
)) {
551 channel
->subbuf_size
= power
;
552 DBG("the set_subbuf_size for the requested channel is %zd", channel
->subbuf_size
);
559 ERR("unable to find channel");
567 static int do_cmd_set_subbuf_num(const char *recvbuf
, struct ustcomm_source
*src
)
569 char *channel_slash_num
;
570 char ch_name
[256]="";
573 struct ust_trace
*trace
;
574 char trace_name
[] = "auto";
578 DBG("set_subbuf_num");
580 channel_slash_num
= nth_token(recvbuf
, 1);
581 sscanf(channel_slash_num
, "%255[^/]/%u", ch_name
, &num
);
583 if(ch_name
== NULL
) {
584 ERR("cannot parse channel");
588 ERR("subbuffer count should be greater than 2");
593 trace
= _ltt_trace_find_setup(trace_name
);
595 ERR("cannot find trace!");
600 for(i
= 0; i
< trace
->nr_channels
; i
++) {
601 struct ust_channel
*channel
= &trace
->channels
[i
];
603 if(!strcmp(trace
->channels
[i
].channel_name
, ch_name
)) {
605 channel
->subbuf_cnt
= num
;
606 DBG("the set_subbuf_cnt for the requested channel is %zd", channel
->subbuf_cnt
);
613 ERR("unable to find channel");
621 static int do_cmd_get_subbuffer(const char *recvbuf
, struct ustcomm_source
*src
)
624 struct ust_trace
*trace
;
625 char trace_name
[] = "auto";
627 char *channel_and_cpu
;
634 channel_and_cpu
= nth_token(recvbuf
, 1);
635 if(channel_and_cpu
== NULL
) {
636 ERR("cannot parse channel");
640 seperate_channel_cpu(channel_and_cpu
, &ch_name
, &ch_cpu
);
642 ERR("problem parsing channel name");
643 goto free_short_chan_name
;
647 trace
= _ltt_trace_find(trace_name
);
652 WARN("Cannot find trace. It was likely destroyed by the user.");
653 result
= ustcomm_send_reply(&ustcomm_app
.server
, "NOTFOUND", src
);
655 ERR("ustcomm_send_reply failed");
663 for(i
=0; i
<trace
->nr_channels
; i
++) {
664 struct ust_channel
*channel
= &trace
->channels
[i
];
666 if(!strcmp(trace
->channels
[i
].channel_name
, ch_name
)) {
667 struct ust_buffer
*buf
= channel
->buf
[ch_cpu
];
668 struct blocked_consumer
*bc
;
672 bc
= (struct blocked_consumer
*) malloc(sizeof(struct blocked_consumer
));
674 ERR("malloc returned NULL");
677 bc
->fd_consumer
= src
->fd
;
678 bc
->fd_producer
= buf
->data_ready_fd_read
;
681 bc
->server
= ustcomm_app
.server
;
683 list_add(&bc
->list
, &blocked_consumers
);
685 /* Being here is the proof the daemon has mapped the buffer in its
686 * memory. We may now decrement buffers_to_export.
688 if(uatomic_read(&buf
->consumed
) == 0) {
689 DBG("decrementing buffers_to_export");
697 ERR("unable to find channel");
703 free_short_chan_name
:
710 static int do_cmd_put_subbuffer(const char *recvbuf
, struct ustcomm_source
*src
)
713 struct ust_trace
*trace
;
714 char trace_name
[] = "auto";
716 char *channel_and_cpu
;
722 char *consumed_old_str
;
728 channel_and_cpu
= strdup_malloc(nth_token(recvbuf
, 1));
729 if(channel_and_cpu
== NULL
) {
730 ERR("cannot parse channel");
735 consumed_old_str
= strdup_malloc(nth_token(recvbuf
, 2));
736 if(consumed_old_str
== NULL
) {
737 ERR("cannot parse consumed_old");
739 goto free_channel_and_cpu
;
741 consumed_old
= strtol(consumed_old_str
, &endptr
, 10);
742 if(*endptr
!= '\0') {
743 ERR("invalid value for consumed_old");
745 goto free_consumed_old_str
;
748 seperate_channel_cpu(channel_and_cpu
, &ch_name
, &ch_cpu
);
750 ERR("problem parsing channel name");
752 goto free_short_chan_name
;
756 trace
= _ltt_trace_find(trace_name
);
759 WARN("Cannot find trace. It was likely destroyed by the user.");
760 result
= ustcomm_send_reply(&ustcomm_app
.server
, "NOTFOUND", src
);
762 ERR("ustcomm_send_reply failed");
770 for(i
=0; i
<trace
->nr_channels
; i
++) {
771 struct ust_channel
*channel
= &trace
->channels
[i
];
773 if(!strcmp(trace
->channels
[i
].channel_name
, ch_name
)) {
774 struct ust_buffer
*buf
= channel
->buf
[ch_cpu
];
778 result
= ust_buffers_put_subbuf(buf
, consumed_old
);
780 WARN("ust_buffers_put_subbuf: error (subbuf=%s)", channel_and_cpu
);
781 asprintf(&reply
, "%s", "ERROR");
784 DBG("ust_buffers_put_subbuf: success (subbuf=%s)", channel_and_cpu
);
785 asprintf(&reply
, "%s", "OK");
788 result
= ustcomm_send_reply(&ustcomm_app
.server
, reply
, src
);
790 ERR("ustcomm_send_reply failed");
801 ERR("unable to find channel");
806 free_short_chan_name
:
808 free_consumed_old_str
:
809 free(consumed_old_str
);
810 free_channel_and_cpu
:
811 free(channel_and_cpu
);
817 void *listener_main(void *p
)
824 char trace_name
[] = "auto";
825 char trace_type
[] = "ustrelay";
828 struct ustcomm_source src
;
830 process_blocked_consumers();
832 result
= ustcomm_app_recv_message(&ustcomm_app
, &recvbuf
, &src
, 5);
834 WARN("error in ustcomm_app_recv_message");
837 else if(result
== 0) {
842 DBG("received a message! it's: %s", recvbuf
);
843 len
= strlen(recvbuf
);
845 if(!strcmp(recvbuf
, "print_markers")) {
846 print_markers(stderr
);
848 else if(!strcmp(recvbuf
, "list_markers")) {
853 fp
= open_memstream(&ptr
, &size
);
857 result
= ustcomm_send_reply(&ustcomm_app
.server
, ptr
, &src
);
861 else if(!strcmp(recvbuf
, "start")) {
862 /* start is an operation that setups the trace, allocates it and starts it */
863 result
= ltt_trace_setup(trace_name
);
865 ERR("ltt_trace_setup failed");
869 result
= ltt_trace_set_type(trace_name
, trace_type
);
871 ERR("ltt_trace_set_type failed");
875 result
= ltt_trace_alloc(trace_name
);
877 ERR("ltt_trace_alloc failed");
881 inform_consumer_daemon(trace_name
);
883 result
= ltt_trace_start(trace_name
);
885 ERR("ltt_trace_start failed");
889 else if(!strcmp(recvbuf
, "trace_setup")) {
892 result
= ltt_trace_setup(trace_name
);
894 ERR("ltt_trace_setup failed");
898 result
= ltt_trace_set_type(trace_name
, trace_type
);
900 ERR("ltt_trace_set_type failed");
904 else if(!strcmp(recvbuf
, "trace_alloc")) {
907 result
= ltt_trace_alloc(trace_name
);
909 ERR("ltt_trace_alloc failed");
912 inform_consumer_daemon(trace_name
);
914 else if(!strcmp(recvbuf
, "trace_create")) {
917 result
= ltt_trace_setup(trace_name
);
919 ERR("ltt_trace_setup failed");
923 result
= ltt_trace_set_type(trace_name
, trace_type
);
925 ERR("ltt_trace_set_type failed");
929 else if(!strcmp(recvbuf
, "trace_start")) {
932 result
= ltt_trace_alloc(trace_name
);
934 ERR("ltt_trace_alloc failed");
938 inform_consumer_daemon(trace_name
);
941 result
= ltt_trace_start(trace_name
);
943 ERR("ltt_trace_start failed");
947 else if(!strcmp(recvbuf
, "trace_stop")) {
950 result
= ltt_trace_stop(trace_name
);
952 ERR("ltt_trace_stop failed");
956 else if(!strcmp(recvbuf
, "trace_destroy")) {
958 DBG("trace destroy");
960 result
= ltt_trace_destroy(trace_name
, 0);
962 ERR("ltt_trace_destroy failed");
966 else if(nth_token_is(recvbuf
, "get_shmid", 0) == 1) {
967 do_cmd_get_shmid(recvbuf
, &src
);
969 else if(nth_token_is(recvbuf
, "get_n_subbufs", 0) == 1) {
970 do_cmd_get_n_subbufs(recvbuf
, &src
);
972 else if(nth_token_is(recvbuf
, "get_subbuf_size", 0) == 1) {
973 do_cmd_get_subbuf_size(recvbuf
, &src
);
975 else if(nth_token_is(recvbuf
, "load_probe_lib", 0) == 1) {
978 libfile
= nth_token(recvbuf
, 1);
980 DBG("load_probe_lib loading %s", libfile
);
984 else if(nth_token_is(recvbuf
, "get_subbuffer", 0) == 1) {
985 do_cmd_get_subbuffer(recvbuf
, &src
);
987 else if(nth_token_is(recvbuf
, "put_subbuffer", 0) == 1) {
988 do_cmd_put_subbuffer(recvbuf
, &src
);
990 else if(nth_token_is(recvbuf
, "set_subbuf_size", 0) == 1) {
991 do_cmd_set_subbuf_size(recvbuf
, &src
);
993 else if(nth_token_is(recvbuf
, "set_subbuf_num", 0) == 1) {
994 do_cmd_set_subbuf_num(recvbuf
, &src
);
996 else if(nth_token_is(recvbuf
, "enable_marker", 0) == 1) {
997 char *channel_slash_name
= nth_token(recvbuf
, 1);
998 char channel_name
[256]="";
999 char marker_name
[256]="";
1001 result
= sscanf(channel_slash_name
, "%255[^/]/%255s", channel_name
, marker_name
);
1003 if(channel_name
== NULL
|| marker_name
== NULL
) {
1004 WARN("invalid marker name");
1008 result
= ltt_marker_connect(channel_name
, marker_name
, "default");
1010 WARN("could not enable marker; channel=%s, name=%s", channel_name
, marker_name
);
1013 else if(nth_token_is(recvbuf
, "disable_marker", 0) == 1) {
1014 char *channel_slash_name
= nth_token(recvbuf
, 1);
1018 result
= sscanf(channel_slash_name
, "%a[^/]/%as", &channel_name
, &marker_name
);
1020 if(marker_name
== NULL
) {
1023 result
= ltt_marker_disconnect(channel_name
, marker_name
, "default");
1025 WARN("could not disable marker; channel=%s, name=%s", channel_name
, marker_name
);
1028 else if(nth_token_is(recvbuf
, "get_pidunique", 0) == 1) {
1031 asprintf(&reply
, "%lld", pidunique
);
1033 result
= ustcomm_send_reply(&ustcomm_app
.server
, reply
, &src
);
1035 ERR("listener: get_pidunique: ustcomm_send_reply failed");
1041 // else if(nth_token_is(recvbuf, "get_notifications", 0) == 1) {
1042 // struct ust_trace *trace;
1043 // char trace_name[] = "auto";
1045 // char *channel_name;
1047 // DBG("get_notifications");
1049 // channel_name = strdup_malloc(nth_token(recvbuf, 1));
1050 // if(channel_name == NULL) {
1051 // ERR("put_subbuf_size: cannot parse channel");
1055 // ltt_lock_traces();
1056 // trace = _ltt_trace_find(trace_name);
1057 // ltt_unlock_traces();
1059 // if(trace == NULL) {
1060 // ERR("cannot find trace!");
1061 // return (void *)1;
1064 // for(i=0; i<trace->nr_channels; i++) {
1065 // struct rchan *rchan = trace->channels[i].trans_channel_data;
1068 // if(!strcmp(trace->channels[i].channel_name, channel_name)) {
1069 // struct rchan_buf *rbuf = rchan->buf;
1070 // struct ltt_channel_buf_struct *lttbuf = trace->channels[i].buf;
1072 // result = fd = ustcomm_app_detach_client(&ustcomm_app, &src);
1073 // if(result == -1) {
1074 // ERR("ustcomm_app_detach_client failed");
1078 // lttbuf->wake_consumer_arg = (void *) fd;
1082 // lttbuf->call_wake_consumer = 1;
1088 // free(channel_name);
1091 ERR("unable to parse message: %s", recvbuf
);
1099 volatile sig_atomic_t have_listener
= 0;
1101 void create_listener(void)
1104 static char listener_stack
[16384];
1111 WARN("not creating listener because we already had one");
1116 result
= clone((int (*)(void *)) listener_main
, listener_stack
+sizeof(listener_stack
)-1, CLONE_FS
| CLONE_FILES
| CLONE_VM
| CLONE_SIGHAND
| CLONE_THREAD
, NULL
);
1123 pthread_create(&thread
, NULL
, listener_main
, NULL
);
1129 static int init_socket(void)
1131 return ustcomm_init_app(getpid(), &ustcomm_app
);
1134 #define AUTOPROBE_DISABLED 0
1135 #define AUTOPROBE_ENABLE_ALL 1
1136 #define AUTOPROBE_ENABLE_REGEX 2
1137 static int autoprobe_method
= AUTOPROBE_DISABLED
;
1138 static regex_t autoprobe_regex
;
1140 static void auto_probe_connect(struct marker
*m
)
1144 char* concat_name
= NULL
;
1145 const char *probe_name
= "default";
1147 if(autoprobe_method
== AUTOPROBE_DISABLED
) {
1150 else if(autoprobe_method
== AUTOPROBE_ENABLE_REGEX
) {
1151 result
= asprintf(&concat_name
, "%s/%s", m
->channel
, m
->name
);
1153 ERR("auto_probe_connect: asprintf failed (marker %s/%s)",
1154 m
->channel
, m
->name
);
1157 if (regexec(&autoprobe_regex
, concat_name
, 0, NULL
, 0)) {
1164 result
= ltt_marker_connect(m
->channel
, m
->name
, probe_name
);
1165 if(result
&& result
!= -EEXIST
)
1166 ERR("ltt_marker_connect (marker = %s/%s, errno = %d)", m
->channel
, m
->name
, -result
);
1168 DBG("auto connected marker %s (addr: %p) %s to probe default", m
->channel
, m
, m
->name
);
1172 static void __attribute__((constructor
)) init()
1175 char* autoprobe_val
= NULL
;
1177 /* Assign the pidunique, to be able to differentiate the processes with same
1178 * pid, (before and after an exec).
1180 pidunique
= make_pidunique();
1182 DBG("Tracectl constructor");
1184 result
= init_socket();
1186 ERR("init_socket error");
1192 autoprobe_val
= getenv("UST_AUTOPROBE");
1194 struct marker_iter iter
;
1196 DBG("Autoprobe enabled.");
1198 /* Ensure markers are initialized */
1201 /* Ensure marker control is initialized, for the probe */
1202 init_marker_control();
1204 /* first, set the callback that will connect the
1205 * probe on new markers
1207 if(autoprobe_val
[0] == '/') {
1208 result
= regcomp(&autoprobe_regex
, autoprobe_val
+1, 0);
1212 regerror(result
, &autoprobe_regex
, regexerr
, sizeof(regexerr
));
1213 ERR("cannot parse regex %s (%s), will ignore UST_AUTOPROBE", autoprobe_val
, regexerr
);
1214 /* don't crash the application just for this */
1217 autoprobe_method
= AUTOPROBE_ENABLE_REGEX
;
1221 /* just enable all instrumentation */
1222 autoprobe_method
= AUTOPROBE_ENABLE_ALL
;
1225 marker_set_new_marker_cb(auto_probe_connect
);
1227 /* Now, connect the probes that were already registered. */
1228 marker_iter_reset(&iter
);
1229 marker_iter_start(&iter
);
1231 DBG("now iterating on markers already registered");
1232 while(iter
.marker
) {
1233 DBG("now iterating on marker %s", iter
.marker
->name
);
1234 auto_probe_connect(iter
.marker
);
1235 marker_iter_next(&iter
);
1239 if(getenv("UST_TRACE")) {
1240 char trace_name
[] = "auto";
1241 char trace_type
[] = "ustrelay";
1243 DBG("starting early tracing");
1245 /* Ensure marker control is initialized */
1246 init_marker_control();
1248 /* Ensure markers are initialized */
1251 /* Ensure buffers are initialized, for the transport to be available.
1252 * We are about to set a trace type and it will fail without this.
1254 init_ustrelay_transport();
1256 /* FIXME: When starting early tracing (here), depending on the
1257 * order of constructors, it is very well possible some marker
1258 * sections are not yet registered. Because of this, some
1259 * channels may not be registered. Yet, we are about to ask the
1260 * daemon to collect the channels. Channels which are not yet
1261 * registered will not be collected.
1263 * Currently, in LTTng, there is no way to add a channel after
1264 * trace start. The reason for this is that it induces complex
1265 * concurrency issues on the trace structures, which can only
1266 * be resolved using RCU. This has not been done yet. As a
1267 * workaround, we are forcing the registration of the "ust"
1268 * channel here. This is the only channel (apart from metadata)
1269 * that can be reliably used in early tracing.
1271 * Non-early tracing does not have this problem and can use
1272 * arbitrary channel names.
1274 ltt_channels_register("ust");
1276 result
= ltt_trace_setup(trace_name
);
1278 ERR("ltt_trace_setup failed");
1282 result
= ltt_trace_set_type(trace_name
, trace_type
);
1284 ERR("ltt_trace_set_type failed");
1288 result
= ltt_trace_alloc(trace_name
);
1290 ERR("ltt_trace_alloc failed");
1294 result
= ltt_trace_start(trace_name
);
1296 ERR("ltt_trace_start failed");
1300 /* Do this after the trace is started in order to avoid creating confusion
1301 * if the trace fails to start. */
1302 inform_consumer_daemon(trace_name
);
1308 /* should decrementally destroy stuff if error */
1312 /* This is only called if we terminate normally, not with an unhandled signal,
1313 * so we cannot rely on it. However, for now, LTTV requires that the header of
1314 * the last sub-buffer contain a valid end time for the trace. This is done
1315 * automatically only when the trace is properly stopped.
1317 * If the traced program crashed, it is always possible to manually add the
1318 * right value in the header, or to open the trace in text mode.
1320 * FIXME: Fix LTTV so it doesn't need this.
1323 static void destroy_traces(void)
1327 /* if trace running, finish it */
1329 DBG("destructor stopping traces");
1331 result
= ltt_trace_stop("auto");
1333 ERR("ltt_trace_stop error");
1336 result
= ltt_trace_destroy("auto", 0);
1338 ERR("ltt_trace_destroy error");
1342 static int trace_recording(void)
1345 struct ust_trace
*trace
;
1349 list_for_each_entry(trace
, <t_traces
.head
, list
) {
1356 ltt_unlock_traces();
1362 static int have_consumer(void)
1364 return !list_empty(&blocked_consumers
);
1368 int restarting_usleep(useconds_t usecs
)
1374 tv
.tv_nsec
= usecs
* 1000;
1377 result
= nanosleep(&tv
, &tv
);
1378 } while(result
== -1 && errno
== EINTR
);
1383 /* This destructor keeps the process alive for a few seconds in order
1384 * to leave time to ustd to connect to its buffers. This is necessary
1385 * for programs whose execution is very short. It is also useful in all
1386 * programs when tracing is started close to the end of the program
1389 * FIXME: For now, this only works for the first trace created in a
1393 static void __attribute__((destructor
)) keepalive()
1395 if(trace_recording() && buffers_to_export
) {
1397 DBG("Keeping process alive for consumer daemon...");
1398 while(buffers_to_export
) {
1399 const int interv
= 200000;
1400 restarting_usleep(interv
);
1403 if(total
>= 3000000) {
1404 WARN("non-consumed buffers remaining after wait limit; not waiting anymore");
1408 DBG("Finally dying...");
1413 ustcomm_fini_app(&ustcomm_app
);
1416 void ust_potential_exec(void)
1418 trace_mark(ust
, potential_exec
, MARK_NOARGS
);
1425 /* Notify ust that there was a fork. This needs to be called inside
1426 * the new process, anytime a process whose memory is not shared with
1427 * the parent is created. If this function is not called, the events
1428 * of the new process will not be collected.
1430 * Signals should be disabled before the fork and reenabled only after
1431 * this call in order to guarantee tracing is not started before ust_fork()
1432 * sanitizes the new process.
1435 static void ust_fork(void)
1437 struct blocked_consumer
*bc
;
1438 struct blocked_consumer
*deletable_bc
= NULL
;
1441 /* FIXME: technically, the locks could have been taken before the fork */
1442 DBG("ust: forking");
1444 /* break lock if necessary */
1445 ltt_unlock_traces();
1447 ltt_trace_stop("auto");
1448 ltt_trace_destroy("auto", 1);
1449 /* Delete all active connections */
1450 ustcomm_close_all_connections(&ustcomm_app
.server
);
1452 /* Delete all blocked consumers */
1453 list_for_each_entry(bc
, &blocked_consumers
, list
) {
1454 close(bc
->fd_producer
);
1455 close(bc
->fd_consumer
);
1458 list_del(&bc
->list
);
1461 ustcomm_free_app(&ustcomm_app
);
1463 buffers_to_export
= 0;
1467 ltt_trace_setup("auto");
1468 result
= ltt_trace_set_type("auto", "ustrelay");
1470 ERR("ltt_trace_set_type failed");
1474 ltt_trace_alloc("auto");
1475 ltt_trace_start("auto");
1476 inform_consumer_daemon("auto");
1479 void ust_before_fork(ust_fork_info_t
*fork_info
)
1481 /* Disable signals. This is to avoid that the child
1482 * intervenes before it is properly setup for tracing. It is
1483 * safer to disable all signals, because then we know we are not
1484 * breaking anything by restoring the original mask.
1490 - only do this if tracing is active
1493 /* Disable signals */
1494 sigfillset(&all_sigs
);
1495 result
= sigprocmask(SIG_BLOCK
, &all_sigs
, &fork_info
->orig_sigs
);
1497 PERROR("sigprocmask");
1502 /* Don't call this function directly in a traced program */
1503 static void ust_after_fork_common(ust_fork_info_t
*fork_info
)
1507 /* Restore signals */
1508 result
= sigprocmask(SIG_SETMASK
, &fork_info
->orig_sigs
, NULL
);
1510 PERROR("sigprocmask");
1515 void ust_after_fork_parent(ust_fork_info_t
*fork_info
)
1517 /* Reenable signals */
1518 ust_after_fork_common(fork_info
);
1521 void ust_after_fork_child(ust_fork_info_t
*fork_info
)
1523 /* First sanitize the child */
1526 /* Then reenable interrupts */
1527 ust_after_fork_common(fork_info
);