diff options
| -rw-r--r-- | lib/runtime_tools/c_src/dyntrace.c | 128 | ||||
| -rw-r--r-- | lib/runtime_tools/c_src/dyntrace_lttng.h | 106 | 
2 files changed, 162 insertions, 72 deletions
| diff --git a/lib/runtime_tools/c_src/dyntrace.c b/lib/runtime_tools/c_src/dyntrace.c index e0309e53e3..6344f6ed90 100644 --- a/lib/runtime_tools/c_src/dyntrace.c +++ b/lib/runtime_tools/c_src/dyntrace.c @@ -29,7 +29,13 @@  #include "sys.h"  #include "dtrace-wrapper.h"  #if defined(USE_DYNAMIC_TRACE) && (defined(USE_DTRACE) || defined(USE_SYSTEMTAP)) -#define HAVE_USE_DTRACE 1 +#  define HAVE_USE_DTRACE 1 +#endif +#if defined(USE_LTTNG) +#  define HAVE_USE_LTTNG 1 +#  define TRACEPOINT_DEFINE +#  define TRACEPOINT_CREATE_PROBES +#  include "dyntrace_lttng.h"  #endif  void dtrace_nifenv_str(ErlNifEnv *env, char *process_buf); @@ -94,6 +100,12 @@ static ERL_NIF_TERM atom_trace;  static ERL_NIF_TERM atom_remove;  static ERL_NIF_TERM atom_discard; +/* gc atoms */ + +static ERL_NIF_TERM atom_gc_start; +static ERL_NIF_TERM atom_gc_end; + +  static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)  {      atom_true = enif_make_atom(env,"true"); @@ -107,6 +119,9 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)      atom_remove = enif_make_atom(env,"remove");      atom_discard = enif_make_atom(env,"discard"); +    atom_gc_start = enif_make_atom(env,"gc_start"); +    atom_gc_end = enif_make_atom(env,"gc_end"); +      return 0;  } @@ -160,25 +175,21 @@ static ERL_NIF_TERM enabled(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])      }      return atom_trace; -#else +#elif HAVE_USE_LTTNG +    /*      int i;      erts_fprintf(stderr, "enabled:\r\n");      for (i = 0; i < argc; i++) {          erts_fprintf(stderr, "  %T\r\n", argv[i]);      } +    */      return atom_trace; -    return atom_remove;  #endif +    return atom_remove;  }  static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])  { -    int i; -    erts_fprintf(stderr, "trace:\r\n"); -    for (i = 0; i < argc; i++) { -        erts_fprintf(stderr, "  %T\r\n", argv[i]); -    } -  #ifdef HAVE_USE_DTRACE  #define BUFF_SIZE 1024      size_t sz = BUFF_SIZE; @@ -219,57 +230,33 @@ static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])          erlang_trace(p, event, state, arg1, arg2);      } -#endif -    return atom_ok; -} -static ERL_NIF_TERM trace_garbage_collection(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ -#ifdef HARDDEBUG +#elif HAVE_USE_LTTNG      int i;      erts_fprintf(stderr, "trace:\r\n");      for (i = 0; i < argc; i++) {          erts_fprintf(stderr, "  %T\r\n", argv[i]);      }  #endif +    return atom_ok; +} +static ERL_NIF_TERM trace_garbage_collection(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{  #ifdef HAVE_USE_DTRACE -#define BUFF_SIZE 1024 -    size_t sz = BUFF_SIZE; -    char buff[BUFF_SIZE]; -    ASSERT(argc == 6); - -    if (argv[0] == atom_seq_trace) { -        if (erlang_trace_seq_enabled()) { -            char *label = buff, -                *seq_info = buff + BUFF_SIZE/4; -            erts_snprintf(label, 1*BUFF_SIZE/4, "%T", argv[2]); -            erts_snprintf(seq_info, 3*BUFF_SIZE/4, "%T", argv[3]); -            erlang_trace_seq(label, seq_info); -        } -    } else { -        char *event, p[DTRACE_TERM_BUF_SIZE], state, arg1, arg2, arg3; - -        event = buff + BUFF_SIZE - sz; -        sz -= enif_get_atom(env, argv[0], event, sz, ERL_NIF_LATIN1); - -        state = buff + BUFF_SIZE - sz; -        sz -= erts_snprintf(state, sz, "%T", argv[1]); - -        if (enif_is_pid(argv[2]) || enif_is_port(argv[2])) -            dtrace_pid_str(argv[2], p); -        else -            p = NULL; - -        arg1 = buff + BUFF_SIZE - sz; -        sz -= erts_snprintf(arg1, sz, "%T", argv[3]); - -        if (argc == 6) { -            arg2 = buff + BUFF_SIZE - sz; -            sz -= erts_snprintf(arg2, sz, "%T", argv[4]); -        } else -            args2 = NULL; +#elif HAVE_USE_LTTNG +    lttng_decl_procbuf(pid); -        erlang_trace(p, event, state, arg1, arg2); +    lttng_pid_to_str(argv[2], pid); +    if (argv[0] == atom_gc_start) { +        LTTNG2(gc_minor_start, pid, 0); +    } else if (argv[0] == atom_gc_end) { +        LTTNG2(gc_minor_end, pid, 0); +    } else { +        int i; +        erts_fprintf(stderr, "trace send:\r\n"); +        for (i = 0; i < argc; i++) { +            erts_fprintf(stderr, "  %T\r\n", argv[i]); +        }      }  #endif      return atom_ok; @@ -278,13 +265,6 @@ static ERL_NIF_TERM trace_garbage_collection(ErlNifEnv* env, int argc, const ERL  static ERL_NIF_TERM trace_receive(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])  { -#ifdef HARDDEBUG -    int i; -    erts_fprintf(stderr, "trace:\r\n"); -    for (i = 0; i < argc; i++) { -        erts_fprintf(stderr, "  %T\r\n", argv[i]); -    } -#endif  #ifdef HAVE_USE_DTRACE  #define BUFF_SIZE 1024      size_t sz = BUFF_SIZE; @@ -325,6 +305,12 @@ static ERL_NIF_TERM trace_receive(ErlNifEnv* env, int argc, const ERL_NIF_TERM a          erlang_trace(p, event, state, arg1, arg2);      } +#elif HAVE_USE_LTTNG +    int i; +    erts_fprintf(stderr, "trace:\r\n"); +    for (i = 0; i < argc; i++) { +        erts_fprintf(stderr, "  %T\r\n", argv[i]); +    }  #endif      return atom_ok;  } @@ -332,13 +318,6 @@ static ERL_NIF_TERM trace_receive(ErlNifEnv* env, int argc, const ERL_NIF_TERM a  static ERL_NIF_TERM trace_send(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])  { -#ifdef HARDDEBUG -    int i; -    erts_fprintf(stderr, "trace:\r\n"); -    for (i = 0; i < argc; i++) { -        erts_fprintf(stderr, "  %T\r\n", argv[i]); -    } -#endif  #ifdef HAVE_USE_DTRACE  #define BUFF_SIZE 1024      size_t sz = BUFF_SIZE; @@ -379,19 +358,18 @@ static ERL_NIF_TERM trace_send(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv          erlang_trace(p, event, state, arg1, arg2);      } -#endif -    return atom_ok; -} - -static ERL_NIF_TERM trace_procs(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) -{ -#ifdef HARDDEBUG +#elif HAVE_USE_LTTNG      int i;      erts_fprintf(stderr, "trace:\r\n");      for (i = 0; i < argc; i++) {          erts_fprintf(stderr, "  %T\r\n", argv[i]);      }  #endif +    return atom_ok; +} + +static ERL_NIF_TERM trace_procs(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{  #ifdef HAVE_USE_DTRACE  #define BUFF_SIZE 1024      size_t sz = BUFF_SIZE; @@ -432,6 +410,12 @@ static ERL_NIF_TERM trace_procs(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg          erlang_trace(p, event, state, arg1, arg2);      } +#elif HAVE_USE_LTTNG +    int i; +    erts_fprintf(stderr, "trace:\r\n"); +    for (i = 0; i < argc; i++) { +        erts_fprintf(stderr, "  %T\r\n", argv[i]); +    }  #endif      return atom_ok;  } diff --git a/lib/runtime_tools/c_src/dyntrace_lttng.h b/lib/runtime_tools/c_src/dyntrace_lttng.h new file mode 100644 index 0000000000..e4482675bf --- /dev/null +++ b/lib/runtime_tools/c_src/dyntrace_lttng.h @@ -0,0 +1,106 @@ +/* + * %CopyrightBegin% + * + * Copyright Ericsson AB 2016. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + *     http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * %CopyrightEnd% + */ + +#undef TRACEPOINT_PROVIDER +#define TRACEPOINT_PROVIDER com_ericsson_dyntrace + +#if !defined(DYNTRACE_LTTNG_H) || defined(TRACEPOINT_HEADER_MULTI_READ) +#define DYNTRACE_LTTNG_H + +#include <lttng/tracepoint.h> + +/* include a special LTTNG_DO for do_tracepoint ? */ +#define LTTNG1(Name, Arg1) \ +    tracepoint(com_ericsson_dyntrace, Name, (Arg1)) + +#define LTTNG2(Name, Arg1, Arg2) \ +    tracepoint(com_ericsson_dyntrace, Name, (Arg1), (Arg2)) + +#define LTTNG3(Name, Arg1, Arg2, Arg3) \ +    tracepoint(com_ericsson_dyntrace, Name, (Arg1), (Arg2), (Arg3)) + +#define LTTNG4(Name, Arg1, Arg2, Arg3, Arg4) \ +    tracepoint(com_ericsson_dyntrace, Name, (Arg1), (Arg2), (Arg3), (Arg4)) + +#define LTTNG5(Name, Arg1, Arg2, Arg3, Arg4, Arg5) \ +    tracepoint(com_ericsson_dyntrace, Name, (Arg1), (Arg2), (Arg3), (Arg4), (Arg5)) + + +/* Process Memory */ + +TRACEPOINT_EVENT( +    com_ericsson_dyntrace, +    gc_minor_start, +    TP_ARGS( +        char*, p, +        int, need +    ), +    TP_FIELDS( +        ctf_string(pid, p) +        ctf_integer(int, need, need) +    ) +) + +TRACEPOINT_EVENT( +    com_ericsson_dyntrace, +    gc_minor_end, +    TP_ARGS( +        char*, p, +        int, reclaimed +    ), +    TP_FIELDS( +        ctf_string(pid, p) +        ctf_integer(int, reclaimed, reclaimed) +    ) +) + +TRACEPOINT_EVENT( +    com_ericsson_dyntrace, +    gc_major_start, +    TP_ARGS( +        char*, p, +        int, need +    ), +    TP_FIELDS( +        ctf_string(pid, p) +        ctf_integer(int, need, need) +    ) +) + +TRACEPOINT_EVENT( +    com_ericsson_dyntrace, +    gc_major_end, +    TP_ARGS( +        char*, p, +        int, reclaimed +    ), +    TP_FIELDS( +        ctf_string(pid, p) +        ctf_integer(int, reclaimed, reclaimed) +    ) +) + +#endif /* DYNTRACE_LTTNG_H */ + +#undef TRACEPOINT_INCLUDE +#define TRACEPOINT_INCLUDE "./dyntrace_lttng.h" + +/* This part must be outside protection */ +#include <lttng/tracepoint-event.h> | 
