Skip to content

Commit

Permalink
Fix the -xctfpath option
Browse files Browse the repository at this point in the history
The -xctfpath option was (along with all other options) being processed
after dtrace_open().  But the implementation of dtrace_open() included
the instantiation of providers and probes that triggers the loading of
the CTF archive.  As such, this option had no effect.

Instantiation of providers and probes has been moved to a new function:
dtrace_init().  This function is called after all command line options
have been processed, ensuring that -xctfpath sets the pathname to the
CTF archive before it is loaded.

If the CTF rchive specified with -xctfpath (or the default one) is not
valid, a core dump would result.  Nick Alcock submitted a patch that
solved 70% of that problen by properly checking the return value of
ctf_lookup_by_name() during program linking and flagging EDT_NOCTF if
there is an issue.  This has been incorporated into this patch.

In addition, link failure resulted in the constructed DIFO to be free'd
but upon termination, dtrace was walking the identifier hash and freeing
all DIFO and we ended up freeing the same DIFO twice.  This is fixed here
also.

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Reviewed-by: Eugene Loh <eugene.loh@oracle.com>
  • Loading branch information
kvanhees committed Jul 27, 2022
1 parent 9c76750 commit ac2b606
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 30 deletions.
7 changes: 7 additions & 0 deletions cmd/dtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1322,6 +1322,13 @@ main(int argc, char *argv[])
}
}

/*
* Now we are ready to initialize libdtrace based on the chosen
* options.
*/
if (dtrace_init(g_dtp) < 0)
dfatal("failed to initialize libdtrace");

/*
* In our fourth pass we finish g_cmdv[] by calling dc_func to convert
* each string or file specification into a compiled program structure.
Expand Down
19 changes: 14 additions & 5 deletions libdtrace/dt_cc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2385,10 +2385,14 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
case DT_CONST_TASK_REAL_PARENT:
case DT_CONST_TASK_COMM: {
ctf_file_t *cfp = dtp->dt_shared_ctf;
ctf_id_t type = ctf_lookup_by_name(cfp, "struct task_struct");
ctf_id_t type;
ctf_membinfo_t ctm;
int rc = 0;

if (!cfp)
return dt_set_errno(dtp, EDT_NOCTF);

type = ctf_lookup_by_name(cfp, "struct task_struct");
if (type == CTF_ERR)
goto err_ctf;

Expand All @@ -2413,10 +2417,14 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
}
case DT_CONST_MUTEX_OWNER: {
ctf_file_t *cfp = dtp->dt_shared_ctf;
ctf_id_t type = ctf_lookup_by_name(cfp, "struct mutex");
ctf_id_t type;
ctf_membinfo_t ctm;
ctf_id_t rc = CTF_ERR;

if (!cfp)
return dt_set_errno(dtp, EDT_NOCTF);

type = ctf_lookup_by_name(cfp, "struct mutex");
if (type == CTF_ERR)
goto err_ctf;

Expand All @@ -2443,6 +2451,9 @@ dt_link_construct(dtrace_hdl_t *dtp, const dt_probe_t *prp, dtrace_difo_t *dp,
ctf_id_t rc = CTF_ERR;
uint64_t total_offset;

if (!cfp)
return dt_set_errno(dtp, EDT_NOCTF);

type = ctf_lookup_by_name(cfp, "rwlock_t");
if (type == CTF_ERR)
goto err_ctf;
Expand Down Expand Up @@ -2676,10 +2687,8 @@ dt_program_construct(dtrace_hdl_t *dtp, dt_probe_t *prp, uint_t cflags,

DT_DISASM_PROG(dtp, cflags, dp, stderr, idp, prp->desc);

if (dt_link(dtp, prp, dp, idp) != 0) {
dt_difo_free(dtp, dp);
if (dt_link(dtp, prp, dp, idp) != 0)
return NULL;
}

DT_DISASM_PROG_LINKED(dtp, cflags, dp, stderr, idp, prp->desc);

Expand Down
56 changes: 32 additions & 24 deletions libdtrace/dt_open.c
Original file line number Diff line number Diff line change
Expand Up @@ -1113,30 +1113,6 @@ dt_vopen(int version, int flags, int *errp,
if (dt_pfdict_create(dtp) == -1)
return set_open_errno(dtp, errp, dtp->dt_errno);

/*
* Initialize the BPF library handling.
*/
dt_dlib_init(dtp);

/*
* Initialize consume handling, e.g. storage of uncommitted speculations.
*/
if (dt_consume_init(dtp) < 0)
return set_open_errno(dtp, errp, dtp->dt_errno);

/*
* Initialize the collection of probes that is made available by the
* known providers.
*/
dt_probe_init(dtp);
for (i = 0; i < ARRAY_SIZE(dt_providers); i++) {
int n;

n = dt_providers[i]->populate(dtp);
dt_dprintf("loaded %d probes for %s\n", n,
dt_providers[i]->name);
}

/*
* Load hard-wired inlines into the definition cache by calling the
* compiler on the raw definition string defined above.
Expand Down Expand Up @@ -1182,6 +1158,38 @@ dtrace_vopen(int version, int flags, int *errp,
return dt_vopen(version, flags, errp, vector, arg);
}

int
dtrace_init(dtrace_hdl_t *dtp)
{
int i;

/*
* Initialize the BPF library handling.
*/
dt_dlib_init(dtp);

/*
* Initialize consume handling.
*/
if (dt_consume_init(dtp) < 0)
return -1; /* errno is already set */

/*
* Initialize the collection of probes that is made available by the
* known providers.
*/
dt_probe_init(dtp);
for (i = 0; i < ARRAY_SIZE(dt_providers); i++) {
int n;

n = dt_providers[i]->populate(dtp);
dt_dprintf("loaded %d probes for %s\n", n,
dt_providers[i]->name);
}

return 0;
}

void
dtrace_close(dtrace_hdl_t *dtp)
{
Expand Down
1 change: 1 addition & 0 deletions libdtrace/dtrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ typedef struct dtrace_aggdata dtrace_aggdata_t;
extern dtrace_hdl_t *dtrace_open(int version, int flags, int *errp);
extern dtrace_hdl_t *dtrace_vopen(int version, int flags, int *errp,
const dtrace_vector_t *vector, void *arg);
extern int dtrace_init(dtrace_hdl_t *dtp);

extern int dtrace_go(dtrace_hdl_t *dtp, uint_t cflags);
extern int dtrace_stop(dtrace_hdl_t *dtp);
Expand Down
3 changes: 2 additions & 1 deletion libdtrace/libdtrace.ver
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# Oracle Linux DTrace.
# Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.

Expand Down Expand Up @@ -45,6 +45,7 @@ LIBDTRACE_1.0 {
dtrace_handle_proc;
dtrace_handle_setopt;
dtrace_id2desc;
dtrace_init;
dtrace_lookup_by_addr;
dtrace_lookup_by_name;
dtrace_lookup_by_type;
Expand Down
19 changes: 19 additions & 0 deletions test/unittest/options/err.ctfpath.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Oracle Linux DTrace.
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/

/*
* ASSERTION: The -xctfpath option overrides the default vmlinux CTF archive.
*
* SECTION: Options and Tunables/Consumer Options
*/

/* @@runtest-opts: -xctfpath=/dev/null */

BEGIN
{
exit(0);
}
3 changes: 3 additions & 0 deletions test/unittest/options/err.ctfpath.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- @@stderr --
dtrace: script 'test/unittest/options/err.ctfpath.d' matched 1 probe
dtrace: could not enable tracing: Module does not contain any CTF data
5 changes: 5 additions & 0 deletions test/unittest/options/tst.ctfpath.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FUNCTION:NAME
:BEGIN

-- @@stderr --
dtrace: description 'BEGIN ' matched 1 probe
19 changes: 19 additions & 0 deletions test/unittest/options/tst.ctfpath.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash
#
# Oracle Linux DTrace.
# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.
#

dtrace=$1

#
# First determine the location of the vmlinux CTF archive.
#
ctf=`$dtrace $dt_flags -xdebug |&
awk '/Loaded shared CTF from/ { $0 = $NF; sub(/\.$/, ""); print; }'`

$dtrace $dt_flags -xctfpath=$ctf -n 'BEGIN { exit(0); }'

exit $?

0 comments on commit ac2b606

Please sign in to comment.