|
|
@ -71,16 +71,23 @@ static void unload(ErlNifEnv *env, void *priv_data) { |
|
|
|
|
|
|
|
// enabled(TraceTag, TracerState, Tracee) |
|
|
|
static ERL_NIF_TERM enabled(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { |
|
|
|
int arity; |
|
|
|
const ERL_NIF_TERM *tuple; |
|
|
|
ErlNifPid tracer_pid; |
|
|
|
/* Only generate trace for when tracer != tracee */ |
|
|
|
// enif_fprintf(stdout, "IMY************enabled 000:"); |
|
|
|
// for (int i = 0; i <= argc - 1; i++) { |
|
|
|
// if (i != 10) { |
|
|
|
// enif_fprintf(stdout, " %d %T", i, argv[i]); |
|
|
|
// } |
|
|
|
// } |
|
|
|
// enif_fprintf(stdout, "\n"); |
|
|
|
|
|
|
|
if (!enif_get_tuple(env, argv[1], &arity, &tuple)) { |
|
|
|
return atom_remove; |
|
|
|
if (enif_is_identical(argv[1], argv[2])) { |
|
|
|
return atom_discard; |
|
|
|
} |
|
|
|
|
|
|
|
ErlNifPid tracer_pid; |
|
|
|
|
|
|
|
// Disable the trace when one of the tracers is not a local process. |
|
|
|
if (!enif_get_local_pid(env, tuple[0], &tracer_pid)) |
|
|
|
if (!enif_get_local_pid(env, argv[1], &tracer_pid)) |
|
|
|
return atom_remove; |
|
|
|
|
|
|
|
// Disable the trace when one of the tracers is not alive. |
|
|
@ -91,22 +98,38 @@ static ERL_NIF_TERM enabled(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) |
|
|
|
} |
|
|
|
|
|
|
|
static ERL_NIF_TERM enabled_call(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { |
|
|
|
// We always want both call and return_to. |
|
|
|
// We want both call and return_to when tracer != tracee. |
|
|
|
// enif_fprintf(stdout, "IMY************enabled_call 000:"); |
|
|
|
// for (int i = 0; i <= argc - 1; i++) { |
|
|
|
// if (i != 10) { |
|
|
|
// enif_fprintf(stdout, " %d %T", i, argv[i]); |
|
|
|
// } |
|
|
|
// } |
|
|
|
// enif_fprintf(stdout, "\n"); |
|
|
|
|
|
|
|
if (enif_is_identical(argv[1], argv[2])) { |
|
|
|
return atom_discard; |
|
|
|
} |
|
|
|
|
|
|
|
return atom_trace; |
|
|
|
} |
|
|
|
|
|
|
|
static ERL_NIF_TERM enabled_procs(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { |
|
|
|
int arity; |
|
|
|
const ERL_NIF_TERM *tuple; |
|
|
|
// int arity; |
|
|
|
// const ERL_NIF_TERM *tuple; |
|
|
|
|
|
|
|
if (!enif_get_tuple(env, argv[1], &arity, &tuple)) { |
|
|
|
return atom_remove; |
|
|
|
} |
|
|
|
// if (!enif_get_tuple(env, argv[1], &arity, &tuple)) { |
|
|
|
// return atom_remove; |
|
|
|
// } |
|
|
|
|
|
|
|
// We only want the spawn and exit events when 'profile' mode |
|
|
|
// is enabled. Technically we only care about exits for callgrind, |
|
|
|
// but spawn is cheap to keep and useful for message profilers. |
|
|
|
if (enif_is_identical(atom_profile, tuple[1]) && !(enif_is_identical(atom_spawn, argv[0]) || enif_is_identical(atom_exit, argv[0]))) { |
|
|
|
// // We only want the spawn and exit events when 'profile' mode |
|
|
|
// // is enabled. Technically we only care about exits for callgrind, |
|
|
|
// // but spawn is cheap to keep and useful for message profilers. |
|
|
|
// if (enif_is_identical(atom_profile, tuple[1]) && !(enif_is_identical(atom_spawn, argv[0]) || enif_is_identical(atom_exit, argv[0]))) { |
|
|
|
// return atom_discard; |
|
|
|
// } |
|
|
|
|
|
|
|
if (enif_is_identical(argv[1], argv[2])) { |
|
|
|
return atom_discard; |
|
|
|
} |
|
|
|
|
|
|
@ -114,22 +137,34 @@ static ERL_NIF_TERM enabled_procs(ErlNifEnv *env, int argc, const ERL_NIF_TERM a |
|
|
|
} |
|
|
|
|
|
|
|
static ERL_NIF_TERM enabled_send(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { |
|
|
|
// We always want both send and send_to_non_existing_process. |
|
|
|
// We want both send and send_to_non_existing_process when tracer != tracee. |
|
|
|
if (enif_is_identical(argv[1], argv[2])) { |
|
|
|
return atom_discard; |
|
|
|
} |
|
|
|
return atom_trace; |
|
|
|
} |
|
|
|
|
|
|
|
static ERL_NIF_TERM enabled_receive(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { |
|
|
|
// We always want receive. |
|
|
|
// We want receive when tracer != tracee. |
|
|
|
if (enif_is_identical(argv[1], argv[2])) { |
|
|
|
return atom_discard; |
|
|
|
} |
|
|
|
return atom_trace; |
|
|
|
} |
|
|
|
|
|
|
|
static ERL_NIF_TERM enabled_running_procs(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { |
|
|
|
// We always want both in and out. |
|
|
|
// We want both in and out tracer != tracee. |
|
|
|
if (enif_is_identical(argv[1], argv[2])) { |
|
|
|
return atom_discard; |
|
|
|
} |
|
|
|
return atom_trace; |
|
|
|
} |
|
|
|
|
|
|
|
static ERL_NIF_TERM enabled_garbage_collection(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { |
|
|
|
// We always want both gc_minor_start, gc_max_heap_size, and gc_minor_end. |
|
|
|
// We want both gc_minor_start, gc_max_heap_size, and gc_minor_end tracer != tracee. |
|
|
|
if (enif_is_identical(argv[1], argv[2])) { |
|
|
|
return atom_discard; |
|
|
|
} |
|
|
|
return atom_trace; |
|
|
|
} |
|
|
|
|
|
|
@ -144,16 +179,11 @@ static ERL_NIF_TERM trace(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { |
|
|
|
// } |
|
|
|
// enif_fprintf(stdout, "\n"); |
|
|
|
|
|
|
|
int arity, has_extra, has_mspec; |
|
|
|
const ERL_NIF_TERM *tuple; |
|
|
|
int has_extra, has_mspec; |
|
|
|
ErlNifPid tracer_pid; |
|
|
|
|
|
|
|
if (!enif_get_tuple(env, argv[1], &arity, &tuple)) { |
|
|
|
return atom_ok; |
|
|
|
} |
|
|
|
|
|
|
|
// Disable the trace when one of the tracers is not a local process. |
|
|
|
if (!enif_get_local_pid(env, tuple[0], &tracer_pid)) |
|
|
|
if (!enif_get_local_pid(env, argv[1], &tracer_pid)) |
|
|
|
return atom_ok; |
|
|
|
|
|
|
|
ERL_NIF_TERM ts, extra, mspec, msg; |
|
|
|