Skip to content

Instantly share code, notes, and snippets.

@luqmana
Created December 12, 2022 00:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save luqmana/b9a8b649a88c4ced20bafd7b0b92f248 to your computer and use it in GitHub Desktop.
Save luqmana/b9a8b649a88c4ced20bafd7b0b92f248 to your computer and use it in GitHub Desktop.
#!/usr/sbin/dtrace -s
dtrace:::BEGIN
{
}
/* The link we're interested in. */
uint32 linkid;
string linkname;
/* Trace creation of dls_devnet_t */
dls_devnet_create:entry/self->in_create == 0 && linkid == 0/ {
self->in_create = 1;
self->mh = (mac_impl_t *)arg0;
self->linkid = arg1;
self->dpp = (dls_devnet_t*)NULL;
}
dls_devnet_set:entry/self->in_create && args[0] == self->mh->mi_name/ {
self->in_set = 1;
}
mod_hash_insert:entry/self->in_create && self->in_set && args[0] == `i_dls_devnet_hash && stringof(args[1]) == stringof(self->mh->mi_name)/ {
self->dpp = (dls_devnet_t*)arg2;
}
dls_devnet_set:return/self->in_create && self->in_set/ {
self->in_set = 0;
}
dls_devnet_create:return/self->in_create && self->dpp && arg1 == 0/ {
/* Stash linkid in global if successful. */
linkid = self->linkid;
linkname = stringof(self->dpp->dd_linkname);
printf("Associated linkid %d [%s] w/ link %s\n", self->linkid, self->dpp->dd_linkname, self->mh->mi_name);
stack();
printf("Created dls_devnet_t and added to hash table.\n");
printf("Refs: dpp->dd_ref = %d\tdpp->dd_tref = %d\n", self->dpp->dd_ref, self->dpp->dd_tref);
}
dls_devnet_create:return/self->in_create && arg1 != 0/ {
printf("Failed to associate linkid %d, err = %d\n", self->linkid, arg1);
stack();
}
dls_devnet_create:return/self->in_create/ {
self->in_create = 0;
self->mh = NULL;
self->linkid = 0;
self->dpp = NULL;
}
/* Trace deletion of dls_devnet_t */
dls_devnet_destroy:entry/self->in_destroy == 0 && linkid != 0/ {
self->in_destroy = 1;
self->mh = (mac_impl_t *)arg0;
self->dpp = (dls_devnet_t*)NULL;
}
dls_devnet_unset:entry/self->in_destroy && args[0] == self->mh->mi_name/ {
self->in_unset = 1;
}
mod_hash_find:entry/self->in_destroy && self->in_unset && args[0] == `i_dls_devnet_hash && args[1] == self->mh->mi_name/ {
self->dpp_ptr = (dls_devnet_t**)arg2;
}
mod_hash_find:return/self->in_destroy && self->in_unset && self->dpp_ptr != NULL/ {
self->dpp = *self->dpp_ptr;
self->dpp_ptr = NULL;
}
dls_devnet_unset:return/self->in_destroy && self->in_unset/ {
self->in_unset = 0;
}
dls_devnet_destroy:return/self->in_destroy && self->dpp && self->dpp->dd_linkid == linkid/ {
printf("Disassociating linkid %d [%s] from link %s\n", self->dpp->dd_linkid, self->dpp->dd_linkname, self->mh->mi_name);
stack();
printf("Refs: dpp->dd_ref = %d\tdpp->dd_tref = %d\n",self->dpp->dd_ref, self->dpp->dd_tref);
}
dls_devnet_destroy:return/self->in_destroy && arg1 != 0/ {
printf("Failed to disassociate mh = %p [%s], err = %d\n", self->mh, self->mh->mi_name, arg1);
}
dls_devnet_destroy:return/self->in_destroy/ {
self->in_destroy = 0;
self->mh = NULL;
self->dpp = NULL;
linkid = 0;
linkname = NULL;
}
/* Trace acquiring (non-temp) ref on dls_devnet_t */
dls_devnet_hold_common:entry/arg0 == linkid && arg2 == 0/ {
self->in_hold = 1;
self->dpp = (dls_devnet_t*)NULL;
}
mod_hash_find:entry/self->in_hold && args[0] == `i_dls_devnet_id_hash && arg1 == linkid/ {
self->dpp_ptr = (dls_devnet_t**)arg2;
}
mod_hash_find:return/self->in_hold && self->dpp_ptr != NULL/ {
self->dpp = *self->dpp_ptr;
self->dpp_ptr = NULL;
self->before_ref = self->dpp->dd_ref;
}
dls_devnet_hold_common:return/self->in_hold && self->dpp && self->dpp->dd_linkid == linkid/ {
printf("Acquiring ref on dls_devnet_t for linkid %d [%s]\n", self->dpp->dd_linkid, self->dpp->dd_linkname);
stack();
ustack();
printf("Before: dpp->dd_ref = %d\n", self->before_ref);
printf("After: dpp->dd_ref = %d\n", self->dpp->dd_ref);
}
dls_devnet_hold_common:return/self->in_hold/ {
self->in_hold = 0;
self->dpp = NULL;
self->before_ref = 0;
}
/* Trace releasing ref on dls_devnet_t */
dls_devnet_rele:entry/args[0]->dd_linkid == linkid/ {
self->dpp = args[0];
self->before_ref = self->dpp->dd_ref;
}
dls_devnet_rele:return/self->dpp/ {
printf("Releasing ref on dls_devnet_t for linkid %d [%s]\n", self->dpp->dd_linkid, self->dpp->dd_linkname);
stack();
printf("Before: dpp->dd_ref = %d\n", self->before_ref);
printf("After: dpp->dd_ref = %d\n", self->dpp->dd_ref);
self->dpp = NULL;
self->before_ref = 0;
}
/* Trace alternate ref acquiring path */
syscall::open:entry/self->in_open == 0 && linkid != 0/ {
self->in_open = 1;
self->execname = execname;
self->file = copyinstr(arg0);
}
dls_devnet_hold_by_dev:entry/linkid != 0/ {
self->in_hold_by_dev = 1;
self->dpp = (dls_devnet_t*)NULL;
}
mod_hash_find:entry/self->in_hold_by_dev && args[0] == `i_dls_devnet_hash/ {
self->dpp_ptr = (dls_devnet_t**)arg2;
}
mod_hash_find:return/self->in_hold_by_dev && self->dpp_ptr != NULL/ {
self->dpp = *self->dpp_ptr;
self->dpp_ptr = NULL;
self->before_ref = self->dpp->dd_ref;
}
dls_devnet_hold_by_dev:return/self->in_open && self->in_hold_by_dev && self->dpp && self->dpp->dd_linkid == linkid/ {
printf("Acquiring ref (by dev) on dls_devnet_t for linkid %d [%s]\n", self->dpp->dd_linkid, self->dpp->dd_linkname);
printf("Caller %s [%s]\n", self->execname, self->file);
ustack();
stack();
printf("Before: dpp->dd_ref = %d\n", self->before_ref);
printf("After: dpp->dd_ref = %d\n", self->dpp->dd_ref);
}
dls_devnet_hold_by_dev:return/self->in_hold_by_dev/ {
self->in_hold_by_dev = 0;
self->dpp = NULL;
self->before_ref = 0;
}
syscall::open:return/self->in_open/ {
self->in_open = 0;
self->execname = NULL;
self->file = NULL;
}
/* Trace closing DLPI handle. */
pid$target::dlpi_close:entry/self->in_dlpi_close == 0/ {
self->in_dlpi_close = 1;
self->dlpi_fd = *(int *)copyin(arg0, 4);
printf("close:\n\tfi_name = %s\n\tfi_dirname = %s\n\tfi_pathname = %s\n\tfi_fs = %s\n\tfi_mount = %s\n",
fds[self->dlpi_fd].fi_name,
fds[self->dlpi_fd].fi_dirname,
fds[self->dlpi_fd].fi_pathname,
fds[self->dlpi_fd].fi_fs,
fds[self->dlpi_fd].fi_mount
);
}
genunix:close:entry/self->in_dlpi_close/ {
self->syscall_fd = arg0;
}
closef:entry/self->in_dlpi_close/ {
printf("Inner close, fp count = %d\n", args[0]->f_count);
}
genunix:close:return/self->in_dlpi_close && self->syscall_fd == self->dlpi_fd/ {
self->syscall_fd = 0;
printf("Closed DLPI fd %d, ret = %d\n", self->dlpi_fd, arg1);
stack();
ustack();
}
pid$target::dlpi_close:return/self->in_dlpi_close/ {
self->in_dlpi_close = 0;
self->dlpi_fd = 0;
}
dld_str_close:entry/self->in_dld_str_close == 0 && linkid != 0/ {
self->in_dld_str_close = 1;
}
dld_str_detach:entry/self->in_dld_str_close && args[0]->ds_ddh->dd_linkid == linkid/ {
this->dpp = args[0]->ds_ddh;
printf("Closed stream for linkid %d [%s]\n", this->dpp->dd_linkid, this->dpp->dd_linkname);
stack();
ustack();
}
dld_str_close:return/self->in_dld_str_close/ {
self->in_dld_str_close = 0;
}
dtrace:::END
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment