blob: f6c13c4b64122e3734198fa500a2e842236d2b06 [file]
/* **********************************************************
* Copyright (c) 2014-2025 Google, Inc. All rights reserved.
* **********************************************************/
/* Dr. Memory: the memory debugger
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License, and no later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* DRMF sample: strace.c
*
* Uses drsyscall to print the name and result of of every system call executed.
*/
#include "dr_api.h"
#include "drmgr.h"
#include "drsyscall.h"
static bool
event_filter_syscall(void *drcontext, int sysnum)
{
return true; /* we want to see all syscalls */
}
static bool
event_pre_syscall(void *drcontext, int sysnum)
{
drsys_syscall_t *syscall;
const char *name = "<unknown>";
if (drsys_cur_syscall(drcontext, &syscall) == DRMF_SUCCESS)
drsys_syscall_name(syscall, &name);
dr_fprintf(STDERR, "[%s ", name, sysnum);
/* We can also get the # of args and the type of each arg.
* See the drstrace tool for an example of how to do that.
*/
return true; /* execute normally */
}
static void
event_post_syscall(void *drcontext, int sysnum)
{
bool success;
uint64 result;
uint error;
if (drsys_cur_syscall_result(drcontext, &success, &result, &error) == DRMF_SUCCESS) {
dr_fprintf(STDERR, "=> 0x" HEX64_FORMAT_STRING " (" SZFMT "), error=%d%s]\n",
result, (ptr_int_t)result, error, success ? "" : " (failed)");
}
}
static void
event_exit(void)
{
if (drsys_exit() != DRMF_SUCCESS)
DR_ASSERT(false);
drmgr_exit();
}
DR_EXPORT void
dr_init(client_id_t id)
{
drsys_options_t ops = {
sizeof(ops),
0,
};
drmgr_init();
drmgr_register_filter_syscall_event(event_filter_syscall);
drmgr_register_pre_syscall_event(event_pre_syscall);
drmgr_register_post_syscall_event(event_post_syscall);
if (drsys_init(id, &ops) != DRMF_SUCCESS)
DR_ASSERT(false);
drmgr_register_exit_event(event_exit);
#ifdef WINDOWS
dr_enable_console_printing(); /* ensure output shows up in cmd */
#endif
}