-
Notifications
You must be signed in to change notification settings - Fork 570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
i#3048 drcachesim record funcs: infrastructure #3057
Changes from 4 commits
1e28578
f99373e
093cb57
3ba97a3
d1713b9
844b9a3
bb1ead5
32a8f98
647ecec
acba3bd
871c03c
6ec4a13
23e725c
f1ba45b
0c170a9
fafa638
90fc899
341f812
468d837
1943e10
d635d36
d358bf2
8d6c0a2
4f45cdf
0f64c4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -333,3 +333,17 @@ droption_t<bool> op_reuse_verify_skip | |
"Verifies every skip list-calculated reuse distance with a full list walk. " | ||
"This incurs significant additional overhead. This option is only available " | ||
"in debug builds."); | ||
|
||
// XXX: replace function return address with function callstack | ||
// XXX: default value should use the customized seperator when the relevant PR comes in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spelling: separator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
#define DEFAULT_SEPARATOR " " | ||
droption_t<std::string> op_record_function | ||
(DROPTION_SCOPE_FRONTEND, "record_function", DROPTION_FLAG_ACCUMULATE, | ||
std::string("malloc:0:1") + DEFAULT_SEPARATOR + | ||
std::string("tc_malloc:1:1") + DEFAULT_SEPARATOR + | ||
std::string("__libc_malloc:2:1"), | ||
"Record invocation traces for the specified functions", | ||
"Option value should fit this format <function_name>:<function_id>:<function_args_num>" | ||
" The trace would contain information for function return address," | ||
" function argument values, and function return value. We only record pointer-sized" | ||
" arguments and return value."); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -191,6 +191,32 @@ typedef enum { | |
*/ | ||
TRACE_MARKER_TYPE_CPU_ID, | ||
|
||
/** | ||
* The marker value contains the function id defined by user in droption | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. s/user/the user/ Missing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
*/ | ||
TRACE_MARKER_TYPE_FUNC_ID, | ||
|
||
/** | ||
* The marker value contains the return address of the function call, | ||
* whose id is specified by the closest previous FUNC_ID marker entry | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to get a link by using the full name and Missing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
* XXX: replace return address with callstack information in the future | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a comment to us, not the user, so put it in a separate regular (non-doxygen) comment (add the i# too) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
*/ | ||
TRACE_MARKER_TYPE_FUNC_RETADDR, | ||
|
||
/** | ||
* The marker value contains one argument value of the function call, | ||
* whose id is specified by the closest previous FUNC_ID marker entry. | ||
* The number of such entries for one function invocation is expected to | ||
* equal to the number of function arguments. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, but the more important point is that it does equal the specified arguments in the -record_function option, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
*/ | ||
TRACE_MARKER_TYPE_FUNC_ARG, | ||
|
||
/** | ||
* The marker value contains return value of the function call, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another skipped prior review comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
* whose id is specified by the closest previous FUNC_ID marker entry | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
*/ | ||
TRACE_MARKER_TYPE_FUNC_RETVAL, | ||
|
||
// ... | ||
// These values are reserved for future built-in marker types. | ||
// ... | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ Total counts: | |
#else | ||
13 total transfer markers | ||
#endif | ||
.* total function markers | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A slightly more specific test would be nice. Something like a simplified version of static_burst.cpp, where the app calls malloc, say, exactly 1000 times between dr_app_start() and dr_app_stop_and_cleanup(). Then we can run the basic_counts tool same way as here and check we've recorded them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure! Will add one in next commit There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
0 total other markers | ||
Thread .* counts: | ||
.* \(fetched\) instructions | ||
|
@@ -45,4 +46,5 @@ Thread .* counts: | |
#else | ||
13 transfer markers | ||
#endif | ||
.* function markers | ||
0 other markers |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/* ********************************************************** | ||
* Copyright (c) 2016-2017 Google, Inc. All rights reserved. | ||
* **********************************************************/ | ||
|
||
/* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* | ||
* * Redistributions of source code must retain the above copyright notice, | ||
* this list of conditions and the following disclaimer. | ||
* | ||
* * 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. | ||
* | ||
* * Neither the name of Google, Inc. nor the names of its contributors may be | ||
* used to endorse or promote products derived from this software without | ||
* specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 GOOGLE, INC. 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. | ||
*/ | ||
|
||
/* This application links in drmemtrace_static and acquires a trace during | ||
* a "burst" of execution in the middle of the application. It then detaches. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Explain that it invokes malloc to test function tracing |
||
*/ | ||
|
||
/* Like burst_static we deliberately do not include configure.h here */ | ||
|
||
#include "dr_api.h" | ||
#include <assert.h> | ||
#include <iostream> | ||
#include <math.h> | ||
#include <stdlib.h> | ||
|
||
bool | ||
my_setenv(const char *var, const char *value) | ||
{ | ||
#ifdef UNIX | ||
return setenv(var, value, 1/*override*/) == 0; | ||
#else | ||
return SetEnvironmentVariable(var, value) == TRUE; | ||
#endif | ||
} | ||
|
||
static int | ||
do_some_work(int arg) | ||
{ | ||
static const int iters = 1000; | ||
static double *vals[iters]; | ||
|
||
double val = (double)arg; | ||
for (int i = 0; i < iters; ++i) { | ||
vals[i] = (double *)malloc(sizeof(double)); | ||
*vals[i] = sin(val); | ||
val += *vals[i]; | ||
} | ||
for (int i = 0; i < iters; i++) { | ||
val += *vals[i]; | ||
} | ||
for (int i = 0; i < iters; i++) { | ||
free(vals[i]); | ||
} | ||
return (val > 0); | ||
} | ||
|
||
int | ||
main(int argc, const char *argv[]) | ||
{ | ||
/* We also test -rstats_to_stderr */ | ||
if (!my_setenv("DYNAMORIO_OPTIONS", "-stderr_mask 0xc -rstats_to_stderr " | ||
"-client_lib ';;-offline'")) | ||
std::cerr << "failed to set env var!\n"; | ||
|
||
/* We use an outer loop to test re-attaching (i#2157). */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. leftover comment from copy/paste? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
std::cerr << "pre-DR init\n"; | ||
dr_app_setup(); | ||
assert(!dr_app_running_under_dynamorio()); | ||
|
||
std::cerr << "pre-DR start\n"; | ||
if (do_some_work(1) < 0) | ||
std::cerr << "error in computation\n"; | ||
|
||
dr_app_start(); | ||
if (do_some_work(2) < 0) | ||
std::cerr << "error in computation\n"; | ||
std::cerr << "pre-DR detach\n"; | ||
dr_app_stop_and_cleanup(); | ||
|
||
if (do_some_work(3) < 0) | ||
std::cerr << "error in computation\n"; | ||
std::cerr << "all done\n"; | ||
return 0; | ||
} | ||
|
||
/* FIXME i#2099: the weak symbol is not supported on Windows. */ | ||
#if defined(UNIX) && defined(TEST_APP_DR_CLIENT_MAIN) | ||
# ifdef __cplusplus | ||
extern "C" { | ||
# endif | ||
|
||
/* Test if the drmemtrace_client_main() in drmemtrace will be called. */ | ||
DR_EXPORT WEAK void | ||
drmemtrace_client_main(client_id_t id, int argc, const char *argv[]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to test the weak symbol in this test, you can remove this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
{ | ||
std::cerr << "wrong drmemtrace_client_main\n"; | ||
} | ||
|
||
/* This dr_client_main should be called instead of the one in tracer.cpp */ | ||
DR_EXPORT void | ||
dr_client_main(client_id_t id, int argc, const char *argv[]) | ||
{ | ||
std::cerr << "app dr_client_main\n"; | ||
drmemtrace_client_main(id, argc, argv); | ||
} | ||
|
||
# ifdef __cplusplus | ||
} | ||
# endif | ||
#endif /* UNIX && TEST_APP_DR_CLIENT_MAIN */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
pre-DR init | ||
pre-DR start | ||
pre-DR detach | ||
DynamoRIO statistics: | ||
*Peak threads under DynamoRIO control : *1 | ||
.* | ||
all done | ||
.* | ||
.* 5000 function markers.* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to have an analysis tool test that examines the function arg, return value, and retaddr entries so we know they're correct. OK in a separate CL. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since basic_counts.cpp is already modified in this CL for counting function markers, I will include the examines for different entries in this same CL. :) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,7 +49,7 @@ basic_counts_tool_create(unsigned int verbose) | |
basic_counts_t::basic_counts_t(unsigned int verbose) : | ||
total_threads(0), total_instrs(0), total_instrs_nofetch(0), total_prefetches(0), | ||
total_loads(0), total_stores(0), total_sched_markers(0), total_xfer_markers(0), | ||
total_other_markers(0), knob_verbose(verbose) | ||
total_func_markers(0), total_other_markers(0), knob_verbose(verbose) | ||
{ | ||
// Empty. | ||
} | ||
|
@@ -59,6 +59,15 @@ basic_counts_t::~basic_counts_t() | |
// Empty. | ||
} | ||
|
||
static bool | ||
is_func_marker(trace_marker_type_t marker_type) | ||
{ | ||
return marker_type == TRACE_MARKER_TYPE_FUNC_ID || | ||
marker_type == TRACE_MARKER_TYPE_FUNC_RETADDR || | ||
marker_type == TRACE_MARKER_TYPE_FUNC_ARG || | ||
marker_type == TRACE_MARKER_TYPE_FUNC_RETVAL; | ||
} | ||
|
||
bool | ||
basic_counts_t::process_memref(const memref_t &memref) | ||
{ | ||
|
@@ -86,6 +95,9 @@ basic_counts_t::process_memref(const memref_t &memref) | |
memref.marker.marker_type == TRACE_MARKER_TYPE_KERNEL_XFER) { | ||
++thread_xfer_markers[memref.data.tid]; | ||
++total_xfer_markers; | ||
} else if (is_func_marker(memref.marker.marker_type)) { | ||
++thread_func_markers[memref.data.tid]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, would total functions (just _RETVAL might be the way to count that: should cover tailcall too via drwrap) be more useful? Maybe not -- depends on what you want to count. Ignore this here. See prior comment about a function trace analysis tool. |
||
++total_func_markers; | ||
} else { | ||
++thread_other_markers[memref.data.tid]; | ||
++total_other_markers; | ||
|
@@ -116,6 +128,7 @@ basic_counts_t::print_results() { | |
std::cerr << std::setw(12) << total_threads << " total threads\n"; | ||
std::cerr << std::setw(12) << total_sched_markers << " total scheduling markers\n"; | ||
std::cerr << std::setw(12) << total_xfer_markers << " total transfer markers\n"; | ||
std::cerr << std::setw(12) << total_func_markers << " total function markers\n"; | ||
std::cerr << std::setw(12) << total_other_markers << " total other markers\n"; | ||
|
||
// Print the threads sorted by instrs. | ||
|
@@ -134,6 +147,7 @@ basic_counts_t::print_results() { | |
std::cerr << std::setw(12) << thread_sched_markers[tid] << | ||
" scheduling markers\n"; | ||
std::cerr << std::setw(12) << thread_xfer_markers[tid] << " transfer markers\n"; | ||
std::cerr << std::setw(12) << thread_func_markers[tid] << " function markers\n"; | ||
std::cerr << std::setw(12) << thread_other_markers[tid] << " other markers\n"; | ||
} | ||
return true; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,6 +56,13 @@ typedef enum { | |
DRMEMTRACE_ERROR_NOT_IMPLEMENTED, /**< Operation failed: not implemented. */ | ||
} drmemtrace_status_t; | ||
|
||
|
||
/** | ||
* Name of drmgr instrumentation pass priorities for app2app, analysis, insert, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Repeating prior comment (!): there is no app2app There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I saw in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, you're right, my bad: I searched for "app2app" in the github diff view and it wasn't there (b/c it's on a line outside the context diff range) -- used for rep string expansion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
* and instru2instru. | ||
*/ | ||
#define DRMGR_PRIORITY_NAME_MEMTRACE "memtrace" | ||
|
||
DR_EXPORT | ||
/** | ||
* To support statically linking multiple clients on UNIX, dr_client_main() inside | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add the issue number (
XXX i#3048:
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done