Skip to content

Commit

Permalink
test: use global_snab_kc_pid
Browse files Browse the repository at this point in the history
fix lock_order_violation when run with debug emu type
````
    at beam/erl_lock_check.c:1225
    at beam/erl_threads.h:1991
````
  • Loading branch information
qzhuyan committed Oct 24, 2024
1 parent 5e57dad commit fc939ba
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 72 deletions.
10 changes: 9 additions & 1 deletion c_src/quicer_nif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1142,6 +1142,10 @@ on_load(ErlNifEnv *env,

init_atoms(env);

#if defined(QUICER_USE_SNK)
enif_set_pid_undefined(&GLOBAL_SNAB_KC_PID);
#endif

// TP must run after init_atoms as atoms are used in TP
TP_NIF_3(start, &MsQuic, 0);
if (!enif_get_uint(env, loadinfo, &load_vsn))
Expand Down Expand Up @@ -1738,7 +1742,11 @@ static ErlNifFunc nif_funcs[] = {
{ "get_stream_owner", 1, get_stream_owner1, 0},
{ "get_listener_owner", 1, get_listener_owner1, 0},
/* for testing */
{ "mock_buffer_sig", 3, mock_buffer_sig, 0}
{ "mock_buffer_sig", 3, mock_buffer_sig, 0},
#ifdef QUICER_USE_SNK
{ "set_snab_kc_pid", 1, set_snab_kc_pid, 0},
{ "get_snab_kc_pid", 0, get_snab_kc_pid, 0},
#endif
// clang-format on
};

Expand Down
107 changes: 66 additions & 41 deletions c_src/quicer_tp.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
#define TRACEPOINT_CREATE_PROBES
#define TRACEPOINT_DEFINE
#include "quicer_tp.h"
#include "assert.h"

extern uint64_t CxPlatTimeUs64(void);
// Compiler attributes
#define __unused_parm__ __attribute__((unused))

// Global pid for snabbkaffe collector
ErlNifPid GLOBAL_SNAB_KC_PID;

// help macro to copy atom to env for debug emulator assertions
#define ATOM_IN_ENV(X) enif_make_copy(env, ATOM_##X)

// This is a helper function to set the pid of the snabbkaffe collector
// because enif_whereis_pid in resource dtor violates beam lock orderings.
ERL_NIF_TERM
set_snab_kc_pid(ErlNifEnv *env,
__unused_parm__ int argc,
const ERL_NIF_TERM argv[])
{
assert(argc == 1);
if (!enif_get_local_pid(env, argv[0], &GLOBAL_SNAB_KC_PID))
{
return ERROR_TUPLE_2(ATOM_BADARG);
}
return ATOM_OK;
}

ERL_NIF_TERM
get_snab_kc_pid(ErlNifEnv *env,
__unused_parm__ int argc,
__unused_parm__ const ERL_NIF_TERM argv[])
{
assert(argc == 0);
return enif_make_pid(env, &GLOBAL_SNAB_KC_PID);
}

void
tp_snk(ErlNifEnv *env,
const char *ctx,
Expand All @@ -15,45 +45,40 @@ tp_snk(ErlNifEnv *env,
uint64_t rid,
uint64_t mark)
{
ErlNifPid pid;
if (enif_whereis_pid(env, ATOM_SNABBKAFFE_COLLECTOR, &pid))
{
ERL_NIF_TERM snk_event;
ERL_NIF_TERM snk_event_key_array[7]
= { ATOM_IN_ENV(SNK_KIND), ATOM_IN_ENV(CONTEXT),
ATOM_IN_ENV(FUNCTION), ATOM_IN_ENV(TAG),
ATOM_IN_ENV(RESOURCE_ID), ATOM_IN_ENV(MARK),
ATOM_IN_ENV(SNK_META) };

ERL_NIF_TERM snk_evt_meta;
ERL_NIF_TERM snk_evt_meta_key_array[1] = { ATOM_IN_ENV(TIME) };
ERL_NIF_TERM snk_evt_meta_val_array[1]
= { enif_make_uint64(env, CxPlatTimeUs64()) };

// shall never fail
enif_make_map_from_arrays(env,
snk_evt_meta_key_array,
snk_evt_meta_val_array,
1,
&snk_evt_meta);

ERL_NIF_TERM snk_event_val_array[7] = {
ATOM_IN_ENV(DEBUG), // snk_kind
enif_make_string(env, ctx, ERL_NIF_LATIN1), // context
enif_make_string(env, fun, ERL_NIF_LATIN1), // fun
enif_make_string(env, tag, ERL_NIF_LATIN1), // tag
enif_make_uint64(env, rid), // rid
enif_make_uint64(env, mark), // mark
snk_evt_meta // snk_meta
};

enif_make_map_from_arrays(
env, snk_event_key_array, snk_event_val_array, 7, &snk_event);

ERL_NIF_TERM report = enif_make_tuple2(
env,
ATOM_IN_ENV(GEN_CAST),
enif_make_tuple2(env, ATOM_IN_ENV(TRACE), snk_event));
enif_send(NULL, &pid, NULL, report);
}
ErlNifPid *pid = &GLOBAL_SNAB_KC_PID;

ERL_NIF_TERM snk_event;
ERL_NIF_TERM snk_event_key_array[7]
= { ATOM_IN_ENV(SNK_KIND), ATOM_IN_ENV(CONTEXT),
ATOM_IN_ENV(FUNCTION), ATOM_IN_ENV(TAG),
ATOM_IN_ENV(RESOURCE_ID), ATOM_IN_ENV(MARK),
ATOM_IN_ENV(SNK_META) };

ERL_NIF_TERM snk_evt_meta;
ERL_NIF_TERM snk_evt_meta_key_array[1] = { ATOM_IN_ENV(TIME) };
ERL_NIF_TERM snk_evt_meta_val_array[1]
= { enif_make_uint64(env, CxPlatTimeUs64()) };

// shall never fail
enif_make_map_from_arrays(
env, snk_evt_meta_key_array, snk_evt_meta_val_array, 1, &snk_evt_meta);

ERL_NIF_TERM snk_event_val_array[7] = {
ATOM_IN_ENV(DEBUG), // snk_kind
enif_make_string(env, ctx, ERL_NIF_LATIN1), // context
enif_make_string(env, fun, ERL_NIF_LATIN1), // fun
enif_make_string(env, tag, ERL_NIF_LATIN1), // tag
enif_make_uint64(env, rid), // rid
enif_make_uint64(env, mark), // mark
snk_evt_meta // snk_meta
};

enif_make_map_from_arrays(
env, snk_event_key_array, snk_event_val_array, 7, &snk_event);

ERL_NIF_TERM report
= enif_make_tuple2(env,
ATOM_IN_ENV(GEN_CAST),
enif_make_tuple2(env, ATOM_IN_ENV(TRACE), snk_event));
enif_send(NULL, pid, NULL, report);
}
6 changes: 6 additions & 0 deletions c_src/quicer_tp.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ TRACEPOINT_EVENT(
/* END of ifdef QUICER_USE_LTTNG */

#elif defined(QUICER_USE_SNK)
extern ErlNifPid GLOBAL_SNAB_KC_PID;

#define TP_NIF_3(TAG, RID, ARG) \
tp_snk(env, "nif", __func__, #TAG, (uint64_t)RID, ARG)
Expand All @@ -66,6 +67,11 @@ void tp_snk(ErlNifEnv *env,
const char *tag,
uint64_t rid,
uint64_t mark);

ERL_NIF_TERM
set_snab_kc_pid(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM
get_snab_kc_pid(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
/* END of ifdef QUICER_USE_SNK */
#else /* NO TP is defined */

Expand Down
12 changes: 11 additions & 1 deletion src/quicer_nif.erl
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,9 @@
get_conn_owner/1,
get_stream_owner/1,
get_listener_owner/1,
mock_buffer_sig/3
mock_buffer_sig/3,
set_snab_kc_pid/1,
get_snab_kc_pid/0
]).

-export([abi_version/0]).
Expand Down Expand Up @@ -405,6 +407,14 @@ flush_stream_buffered_sigs(_H) ->
mock_buffer_sig(_StreamHandle, _OrigOwner, _Msg) ->
erlang:nif_error(nif_library_not_loaded).

-spec set_snab_kc_pid(pid()) -> ok | {error, badarg}.
set_snab_kc_pid(_Pid) ->
erlang:nif_error(nif_library_not_loaded).

-spec get_snab_kc_pid() -> pid().
get_snab_kc_pid() ->
erlang:nif_error(nif_library_not_loaded).

%% Internals
-spec locate_lib(file:name(), file:name()) ->
{ok, file:filename()} | {error, not_found}.
Expand Down
Loading

0 comments on commit fc939ba

Please sign in to comment.