2018-06-07 02:03:22 +00:00
|
|
|
/*-
|
2023-05-10 15:40:58 +00:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2018-06-07 02:03:22 +00:00
|
|
|
*
|
|
|
|
* Copyright (c) 2018, Matthew Macy
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/sysctl.h>
|
2019-04-14 00:06:49 +00:00
|
|
|
#include <assert.h>
|
2018-06-07 02:03:22 +00:00
|
|
|
#include <err.h>
|
2019-04-14 00:06:49 +00:00
|
|
|
#include <errno.h>
|
2018-06-07 02:03:22 +00:00
|
|
|
#include <limits.h>
|
2019-04-14 00:06:49 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
2018-06-07 02:03:22 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <string>
|
|
|
|
#include <sysexits.h>
|
2019-04-14 00:06:49 +00:00
|
|
|
|
|
|
|
#include <pmc.h>
|
2018-06-07 02:03:22 +00:00
|
|
|
#include <pmcformat.h>
|
2019-04-14 00:06:49 +00:00
|
|
|
#include <pmclog.h>
|
2018-06-07 02:03:22 +00:00
|
|
|
|
|
|
|
using std::string;
|
|
|
|
|
|
|
|
static const char *typenames[] = {
|
|
|
|
"",
|
|
|
|
"{\"type\": \"closelog\"}\n",
|
|
|
|
"{\"type\": \"dropnotify\"}\n",
|
|
|
|
"{\"type\": \"initialize\"",
|
|
|
|
"",
|
|
|
|
"{\"type\": \"pmcallocate\"",
|
|
|
|
"{\"type\": \"pmcattach\"",
|
|
|
|
"{\"type\": \"pmcdetach\"",
|
|
|
|
"{\"type\": \"proccsw\"",
|
|
|
|
"{\"type\": \"procexec\"",
|
|
|
|
"{\"type\": \"procexit\"",
|
|
|
|
"{\"type\": \"procfork\"",
|
|
|
|
"{\"type\": \"sysexit\"",
|
|
|
|
"{\"type\": \"userdata\"",
|
|
|
|
"{\"type\": \"map_in\"",
|
|
|
|
"{\"type\": \"map_out\"",
|
|
|
|
"{\"type\": \"callchain\"",
|
|
|
|
"{\"type\": \"pmcallocatedyn\"",
|
|
|
|
"{\"type\": \"thr_create\"",
|
|
|
|
"{\"type\": \"thr_exit\"",
|
|
|
|
"{\"type\": \"proc_create\"",
|
|
|
|
};
|
|
|
|
|
|
|
|
static string
|
|
|
|
startentry(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[128];
|
|
|
|
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf), "%s, \"tsc\": \"%jd\"",
|
2018-06-07 03:19:21 +00:00
|
|
|
typenames[ev->pl_type], (uintmax_t)ev->pl_ts.tv_sec);
|
2018-06-07 02:03:22 +00:00
|
|
|
return (string(eventbuf));
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
initialize_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[256];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"version\": \"0x%08x\", \"arch\": \"0x%08x\", \"cpuid\": \"%s\", "
|
|
|
|
"\"tsc_freq\": \"%jd\", \"sec\": \"%jd\", \"nsec\": \"%jd\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_i.pl_version, ev->pl_u.pl_i.pl_arch,
|
|
|
|
ev->pl_u.pl_i.pl_cpuid, (uintmax_t)ev->pl_u.pl_i.pl_tsc_freq,
|
|
|
|
(uintmax_t)ev->pl_u.pl_i.pl_ts.tv_sec, (uintmax_t)ev->pl_u.pl_i.pl_ts.tv_nsec);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
pmcallocate_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[256];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"pmcid\": \"0x%08x\", \"event\": \"0x%08x\", \"flags\": \"0x%08x\", "
|
|
|
|
"\"rate\": \"%jd\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_a.pl_pmcid, ev->pl_u.pl_a.pl_event,
|
|
|
|
ev->pl_u.pl_a.pl_flags, (intmax_t)ev->pl_u.pl_a.pl_rate);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
pmcattach_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[2048];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", \"pathname\": \"%s\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_t.pl_pmcid, ev->pl_u.pl_t.pl_pid,
|
|
|
|
ev->pl_u.pl_t.pl_pathname);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
pmcdetach_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[128];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_d.pl_pmcid, ev->pl_u.pl_d.pl_pid);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static string
|
|
|
|
proccsw_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[128];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf), "%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\" "
|
|
|
|
"\"tid\": \"%d\", \"value\": \"0x%016jx\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_c.pl_pmcid, ev->pl_u.pl_c.pl_pid,
|
|
|
|
ev->pl_u.pl_c.pl_tid, (uintmax_t)ev->pl_u.pl_c.pl_value);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
procexec_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[2048];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", "
|
pmc: Rework PROCEXEC event to support PIEs
Currently the PROCEXEC event only reports a single address, entryaddr,
which is the entry point of the interpreter in the typical dynamic case,
and used solely to calculate the base address of the interpreter. For
PDEs this is fine, since the base address is known from the program
headers, but for PIEs the base address varies at run time based on where
the kernel chooses to load it, and so pmcstat has no way of knowing the
real address ranges for the executable. This was less of an issue in the
past since PIEs were rare, but now they're on by default on 64-bit
architectures it's more of a problem.
To solve this, pass through what was picked for et_dyn_addr by the
kernel, and use that as the offset for the executable's start address
just as is done for everything in the kernel. Since we're changing this
interface, sanitise the way we determine the interpreter's base address
by passing it through directly rather than indirectly via the entry
point and having to subtract off whatever the ELF header's e_entry is
(and anything that wants the entry point in future can still add that
back on as needed; this merely changes the interface to directly provide
the underlying variables involved).
This will be followed up by a bump to the pmc major version.
Reviewed by: jhb
Differential Revision: https://reviews.freebsd.org/D39595
2023-05-30 23:20:36 +00:00
|
|
|
"\"base\": \"0x%016jx\", \"dyn\": \"0x%016jx\", "
|
|
|
|
"\"pathname\": \"%s\"}\n",
|
2018-06-07 02:03:22 +00:00
|
|
|
startent.c_str(), ev->pl_u.pl_x.pl_pmcid, ev->pl_u.pl_x.pl_pid,
|
pmc: Rework PROCEXEC event to support PIEs
Currently the PROCEXEC event only reports a single address, entryaddr,
which is the entry point of the interpreter in the typical dynamic case,
and used solely to calculate the base address of the interpreter. For
PDEs this is fine, since the base address is known from the program
headers, but for PIEs the base address varies at run time based on where
the kernel chooses to load it, and so pmcstat has no way of knowing the
real address ranges for the executable. This was less of an issue in the
past since PIEs were rare, but now they're on by default on 64-bit
architectures it's more of a problem.
To solve this, pass through what was picked for et_dyn_addr by the
kernel, and use that as the offset for the executable's start address
just as is done for everything in the kernel. Since we're changing this
interface, sanitise the way we determine the interpreter's base address
by passing it through directly rather than indirectly via the entry
point and having to subtract off whatever the ELF header's e_entry is
(and anything that wants the entry point in future can still add that
back on as needed; this merely changes the interface to directly provide
the underlying variables involved).
This will be followed up by a bump to the pmc major version.
Reviewed by: jhb
Differential Revision: https://reviews.freebsd.org/D39595
2023-05-30 23:20:36 +00:00
|
|
|
(uintmax_t)ev->pl_u.pl_x.pl_baseaddr,
|
|
|
|
(uintmax_t)ev->pl_u.pl_x.pl_dynaddr,
|
|
|
|
ev->pl_u.pl_x.pl_pathname);
|
2018-06-07 02:03:22 +00:00
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
procexit_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[128];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", "
|
|
|
|
"\"value\": \"0x%016jx\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_e.pl_pmcid, ev->pl_u.pl_e.pl_pid,
|
|
|
|
(uintmax_t)ev->pl_u.pl_e.pl_value);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
procfork_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[128];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"oldpid\": \"%d\", \"newpid\": \"%d\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_f.pl_oldpid, ev->pl_u.pl_f.pl_newpid);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
sysexit_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[128];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf), "%s, \"pid\": \"%d\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_se.pl_pid);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
userdata_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[128];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf), "%s, \"userdata\": \"0x%08x\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_u.pl_userdata);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
map_in_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[2048];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf), "%s, \"pid\": \"%d\", "
|
|
|
|
"\"start\": \"0x%016jx\", \"pathname\": \"%s\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_mi.pl_pid,
|
|
|
|
(uintmax_t)ev->pl_u.pl_mi.pl_start, ev->pl_u.pl_mi.pl_pathname);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
map_out_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[256];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf), "%s, \"pid\": \"%d\", "
|
|
|
|
"\"start\": \"0x%016jx\", \"end\": \"0x%016jx\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_mi.pl_pid,
|
|
|
|
(uintmax_t)ev->pl_u.pl_mi.pl_start,
|
|
|
|
(uintmax_t)ev->pl_u.pl_mo.pl_end);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
callchain_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[1024];
|
|
|
|
string result;
|
|
|
|
uint32_t i;
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"pmcid\": \"0x%08x\", \"pid\": \"%d\", \"tid\": \"%d\", "
|
|
|
|
"\"cpuflags\": \"0x%08x\", \"cpuflags2\": \"0x%08x\", \"pc\": [ ",
|
|
|
|
startent.c_str(), ev->pl_u.pl_cc.pl_pmcid, ev->pl_u.pl_cc.pl_pid,
|
|
|
|
ev->pl_u.pl_cc.pl_tid, ev->pl_u.pl_cc.pl_cpuflags, ev->pl_u.pl_cc.pl_cpuflags2);
|
|
|
|
result = string(eventbuf);
|
|
|
|
for (i = 0; i < ev->pl_u.pl_cc.pl_npc - 1; i++) {
|
2018-06-07 03:19:21 +00:00
|
|
|
snprintf(eventbuf, sizeof(eventbuf), "\"0x%016jx\", ", (uintmax_t)ev->pl_u.pl_cc.pl_pc[i]);
|
2018-06-07 02:03:22 +00:00
|
|
|
result += string(eventbuf);
|
|
|
|
}
|
2018-06-07 03:19:21 +00:00
|
|
|
snprintf(eventbuf, sizeof(eventbuf), "\"0x%016jx\"]}\n", (uintmax_t)ev->pl_u.pl_cc.pl_pc[i]);
|
2018-06-07 02:03:22 +00:00
|
|
|
result += string(eventbuf);
|
|
|
|
return (result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
pmcallocatedyn_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[2048];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"pmcid\": \"0x%08x\", \"event\": \"%d\", \"flags\": \"0x%08x\", \"evname\": \"%s\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_ad.pl_pmcid, ev->pl_u.pl_ad.pl_event,
|
|
|
|
ev->pl_u.pl_ad.pl_flags, ev->pl_u.pl_ad.pl_evname);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
proccreate_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[2048];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"pid\": \"%d\", \"flags\": \"0x%08x\", \"pcomm\": \"%s\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_pc.pl_pid,
|
|
|
|
ev->pl_u.pl_pc.pl_flags, ev->pl_u.pl_pc.pl_pcomm);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
threadcreate_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[2048];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf),
|
|
|
|
"%s, \"tid\": \"%d\", \"pid\": \"%d\", \"flags\": \"0x%08x\", \"tdname\": \"%s\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_tc.pl_tid, ev->pl_u.pl_tc.pl_pid,
|
|
|
|
ev->pl_u.pl_tc.pl_flags, ev->pl_u.pl_tc.pl_tdname);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
threadexit_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
char eventbuf[256];
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
snprintf(eventbuf, sizeof(eventbuf), "%s, \"tid\": \"%d\"}\n",
|
|
|
|
startent.c_str(), ev->pl_u.pl_te.pl_tid);
|
|
|
|
return string(eventbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static string
|
|
|
|
stub_to_json(struct pmclog_ev *ev)
|
|
|
|
{
|
|
|
|
string startent;
|
|
|
|
|
|
|
|
startent = startentry(ev);
|
|
|
|
startent += string("}\n");
|
|
|
|
return startent;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef string (*jconv) (struct pmclog_ev*);
|
|
|
|
|
|
|
|
static jconv jsonconvert[] = {
|
|
|
|
NULL,
|
|
|
|
stub_to_json,
|
|
|
|
stub_to_json,
|
|
|
|
initialize_to_json,
|
|
|
|
NULL,
|
|
|
|
pmcallocate_to_json,
|
|
|
|
pmcattach_to_json,
|
|
|
|
pmcdetach_to_json,
|
|
|
|
proccsw_to_json,
|
|
|
|
procexec_to_json,
|
|
|
|
procexit_to_json,
|
|
|
|
procfork_to_json,
|
|
|
|
sysexit_to_json,
|
|
|
|
userdata_to_json,
|
|
|
|
map_in_to_json,
|
|
|
|
map_out_to_json,
|
|
|
|
callchain_to_json,
|
|
|
|
pmcallocatedyn_to_json,
|
|
|
|
threadcreate_to_json,
|
|
|
|
threadexit_to_json,
|
|
|
|
proccreate_to_json,
|
|
|
|
};
|
|
|
|
|
|
|
|
string
|
|
|
|
event_to_json(struct pmclog_ev *ev){
|
|
|
|
|
|
|
|
switch (ev->pl_type) {
|
|
|
|
case PMCLOG_TYPE_DROPNOTIFY:
|
|
|
|
case PMCLOG_TYPE_CLOSELOG:
|
|
|
|
case PMCLOG_TYPE_INITIALIZE:
|
|
|
|
case PMCLOG_TYPE_PMCALLOCATE:
|
|
|
|
case PMCLOG_TYPE_PMCATTACH:
|
|
|
|
case PMCLOG_TYPE_PMCDETACH:
|
|
|
|
case PMCLOG_TYPE_PROCCSW:
|
|
|
|
case PMCLOG_TYPE_PROCEXEC:
|
|
|
|
case PMCLOG_TYPE_PROCEXIT:
|
|
|
|
case PMCLOG_TYPE_PROCFORK:
|
|
|
|
case PMCLOG_TYPE_SYSEXIT:
|
|
|
|
case PMCLOG_TYPE_USERDATA:
|
|
|
|
case PMCLOG_TYPE_MAP_IN:
|
|
|
|
case PMCLOG_TYPE_MAP_OUT:
|
|
|
|
case PMCLOG_TYPE_CALLCHAIN:
|
|
|
|
case PMCLOG_TYPE_PMCALLOCATEDYN:
|
|
|
|
case PMCLOG_TYPE_THR_CREATE:
|
|
|
|
case PMCLOG_TYPE_THR_EXIT:
|
|
|
|
case PMCLOG_TYPE_PROC_CREATE:
|
|
|
|
return jsonconvert[ev->pl_type](ev);
|
|
|
|
default:
|
|
|
|
errx(EX_USAGE, "ERROR: unrecognized event type: %d\n", ev->pl_type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|