Skip to content

Commit

Permalink
support issues#3
Browse files Browse the repository at this point in the history
  • Loading branch information
longxinH committed Nov 15, 2017
1 parent ef623ae commit fcbd62e
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 12 deletions.
1 change: 1 addition & 0 deletions examples/ini/apm.ini
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ apm.auto = 1
;APM_FLAGS_NO_BUILTINS
;APM_FLAGS_CPU
;APM_FLAGS_MEMORY
;APM_FLAGS_FILES
apm.flags = APM_FLAGS_CPU | APM_FLAGS_MEMORY

;apm.ignored = md5
Expand Down
9 changes: 6 additions & 3 deletions extension/php_xhprof_apm.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ extern zend_module_entry xhprof_apm_module_entry;
#define APM_FLAGS_NO_BUILTINS 0x0001 /* do not profile builtins */
#define APM_FLAGS_CPU 0x0002 /* gather CPU times for funcs */
#define APM_FLAGS_MEMORY 0x0004 /* gather memory usage for funcs */
#define APM_FLAGS_FILES 0x0008

/* Constant for ignoring functions, transparent to hierarchical profile */
#define APM_MAX_IGNORED_FUNCTIONS 256
Expand Down Expand Up @@ -116,16 +117,16 @@ extern zend_module_entry xhprof_apm_module_entry;
do { \
/* Use a hash code to filter most of the string comparisons. */ \
uint8 hash_code = hp_inline_hash(symbol); \
profile_curr = !hp_ignore_entry_work(hash_code, symbol TSRMLS_CC); \
profile_curr = !hp_ignore_entry_work(hash_code, symbol TSRMLS_CC); \
if (profile_curr) { \
if (execute_data != NULL) { \
symbol = hp_get_trace_callback(symbol, execute_data TSRMLS_CC); \
} \
hp_entry_t *cur_entry = hp_fast_alloc_hprof_entry(TSRMLS_C); \
hp_entry_t *cur_entry = hp_fast_alloc_hprof_entry(TSRMLS_C); \
(cur_entry)->hash_code = hash_code; \
(cur_entry)->name_hprof = symbol; \
(cur_entry)->prev_hprof = (*(entries)); \
hp_mode_hier_beginfn_cb((entries), (cur_entry) TSRMLS_CC); \
hp_mode_hier_beginfn_cb((entries), (cur_entry), execute_data TSRMLS_CC); \
/* Update entries linked list */ \
(*(entries)) = (cur_entry); \
} \
Expand Down Expand Up @@ -189,6 +190,8 @@ typedef struct hp_entry_t {
long int pmu_start_hprof; /* peak memory usage */
struct hp_entry_t *prev_hprof; /* ptr to prev entry being profiled */
uint8 hash_code; /* hash_code for the function name */
char *filename;
int lineno;
} hp_entry_t;

typedef struct hp_ignored_function_map {
Expand Down
59 changes: 52 additions & 7 deletions extension/xhprof_apm.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ static void hp_register_constants(INIT_FUNC_ARGS) {
REGISTER_LONG_CONSTANT("APM_FLAGS_MEMORY",
APM_FLAGS_MEMORY,
CONST_CS | CONST_PERSISTENT);

REGISTER_LONG_CONSTANT("APM_FLAGS_FILES",
APM_FLAGS_FILES,
CONST_CS | CONST_PERSISTENT);
}

/**
Expand Down Expand Up @@ -672,7 +676,7 @@ static inline uint64 get_tsc_from_us(uint64 usecs, double cpu_frequency) {
*
* @author kannan
*/
static void hp_mode_hier_beginfn_cb(hp_entry_t **entries, hp_entry_t *current TSRMLS_DC)
static void hp_mode_hier_beginfn_cb(hp_entry_t **entries, hp_entry_t *current, zend_execute_data *data TSRMLS_DC)
{
hp_entry_t *p;
/* This symbol's recursive level */
Expand Down Expand Up @@ -705,6 +709,22 @@ static void hp_mode_hier_beginfn_cb(hp_entry_t **entries, hp_entry_t *current TS
current->mu_start_hprof = zend_memory_usage(0 TSRMLS_CC);
current->pmu_start_hprof = zend_memory_peak_usage(0 TSRMLS_CC);
}

if (APM_G(xhprof_flags) & APM_FLAGS_FILES) {
current->filename = NULL;
current->lineno = 0;
if (data) {
if (data->op_array && data->op_array->filename) {
current->filename = strdup(data->op_array->filename);
} else {
current->filename = NULL;
}

if (data->opline && current->filename) {
current->lineno = data->opline->lineno;
}
}
}
}

/**
Expand All @@ -720,7 +740,7 @@ static void hp_mode_hier_beginfn_cb(hp_entry_t **entries, hp_entry_t *current TS
*/
static void hp_mode_hier_endfn_cb(hp_entry_t **entries TSRMLS_DC) {
hp_entry_t *top = (*entries);
zval *counts;
zval *counts, *files_stack, *file;
char *symbol;
long int mu_end;
long int pmu_end;
Expand Down Expand Up @@ -764,7 +784,34 @@ static void hp_mode_hier_endfn_cb(hp_entry_t **entries TSRMLS_DC) {
hp_inc_count(counts, "pmu", pmu_end - top->pmu_start_hprof TSRMLS_CC);
}

APM_G(func_hash_counters[top->hash_code])--;
if (APM_G(xhprof_flags) & APM_FLAGS_FILES) {
if (top->filename) {
if (zend_hash_find(Z_ARRVAL_P(counts), "files", strlen("files") + 1, &data) == SUCCESS) {
files_stack = *(zval **) data;
} else {
MAKE_STD_ZVAL(files_stack);
array_init(files_stack);
add_assoc_zval(counts, "files", files_stack);
}

if (zend_hash_find(Z_ARRVAL_P(files_stack), top->filename, strlen(top->filename) + 1, &data) == SUCCESS) {
file = *(zval **) data;
} else {
MAKE_STD_ZVAL(file);
array_init(file);
add_assoc_zval(files_stack, top->filename, file);
}

if (zend_hash_index_find(HASH_OF(file), top->lineno, &data) == SUCCESS) {
ZVAL_LONG(*(zval**)data, Z_LVAL_PP((zval**)data) + 1);
} else {
add_index_long(file, top->lineno, 1);
}
}

}

APM_G(func_hash_counters[top->hash_code])--;
efree(symbol);
}

Expand Down Expand Up @@ -837,13 +884,11 @@ ZEND_DLEXPORT void hp_execute_ex (zend_execute_data *execute_data TSRMLS_DC) {
#if PHP_VERSION_ID < 50500
#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))

ZEND_DLEXPORT void hp_execute_internal(zend_execute_data *execute_data,
int ret TSRMLS_DC) {
ZEND_DLEXPORT void hp_execute_internal(zend_execute_data *execute_data, int ret TSRMLS_DC) {
#else
#define EX_T(offset) (*EX_TMP_VAR(execute_data, offset))

ZEND_DLEXPORT void hp_execute_internal(zend_execute_data *execute_data,
struct _zend_fcall_info *fci, int ret TSRMLS_DC) {
ZEND_DLEXPORT void hp_execute_internal(zend_execute_data *execute_data, struct _zend_fcall_info *fci, int ret TSRMLS_DC) {
#endif
zend_execute_data *current_data;
char *func = NULL;
Expand Down
1 change: 1 addition & 0 deletions web/composer.json
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"require": {
"php": ">=5.4.0",
"slim/slim": "^3.0",
"twig/twig": "^1.0",
"slim/twig-view": "^2.0",
"slim/pdo": "~1.10"
},
Expand Down
3 changes: 2 additions & 1 deletion web/include/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
$app->get('/run/flamegraph', 'Controller\Run:flamegraph')->setName('run.flamegraph');
$app->get('/run/flamegraph/data', 'Controller\Run:flamegraphData')->setName('run.flamegraph.data');
$app->get('/run/compare', 'Controller\Run:compare')->setName('run.compare');
$app->get('/url/view', 'Controller\Run:url')->setName('url.view');
$app->get('/url/view', 'Controller\Run:url')->setName('url.view');
$app->get('/url/stack', 'Controller\Run:stack')->setName('url.stack');
20 changes: 20 additions & 0 deletions web/src/Controller/Run.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public function view()
'memory' => $memoryChart,
'profile' => $profile,
'date_format' => $this->config('date.format'),
'stack' => $result->checkStack()
];

$this->render('runs/view.twig', $tpl_var);
Expand Down Expand Up @@ -122,6 +123,25 @@ public function url()
$this->render('runs/url.twig', $tpl_var);
}

public function stack()
{
$id = $this->_request->getQueryParam('id');
$symbol = $this->_request->getQueryParam('symbol');

$profile = $this->_profiles->get($id);
$profile->calculateSelf();
list(, $current, ) = $profile->getRelatives($symbol);

$tpl_var = [
'symbol' => $symbol,
'id' => $id,
'main' => $profile->get('main()'),
'current' => $current,
];

$this->render('runs/stack.twig', $tpl_var);
}

public function symbol()
{
$id = $this->_request->getQueryParam('id');
Expand Down
10 changes: 10 additions & 0 deletions web/src/Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Profile
protected $_collapsed;
protected $_indexed;
protected $_visited;
protected $_stack = false;

protected $_metricTime = ['wt', 'cpu', 'ewt', 'ecpu'];
protected $_metricBytes = ['mu', 'emu', 'epmu'];
Expand Down Expand Up @@ -50,6 +51,10 @@ protected function _process()
if (isset($result[$func])) {
$result[$func] = $this->_sumKeys($result[$func], $values);
$result[$func]['parents'][] = $parent;
if (isset($result[$func]['files'])) {
$result[$func]['files'] = array_merge_recursive($result[$func]['files'], $values['files']);
$this->_stack = true;
}
} else {
$result[$func] = $values;
$result[$func]['parents'] = array($parent);
Expand Down Expand Up @@ -158,6 +163,11 @@ public function getData($key = null)
return $data;
}

public function checkStack()
{
return $this->_stack;
}

/**
* Get meta data about the profile. Read's a . split path
* out of the meta data in a profile. For example `SERVER.REQUEST_TIME`
Expand Down
39 changes: 39 additions & 0 deletions web/templates/runs/stack.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{% extends 'layout/base.twig' %}
{% import 'macros/helpers.twig' as helpers %}

{% block title %}
调用栈 - {{ symbol }}
{% endblock %}

{% block content %}
<div class="row-fluid">
<a class="back-link" href="{{ path_for('run.view', {}, {'id': id}) }}">&laquo; Back to run</a>
<h1>调用栈</h1>
<h3 class="function-name">{{ symbol }}</h3>
</div>
<div class="row-fluid">
<table class="table table-hover">
<thead>
<tr>
<th>文件名</th>
<th>行号</th>
<th>调用次数</th>
</tr>
</thead>
<tbody>
{% if current.files is not empty %}
{% for filename, stack in current.files %}
{% for lineno, num in stack %}
<tr>
<td>{{ filename }}</td>
<td>{{ lineno }}</td>
<td>{{ num }}</td>
</tr>
{% endfor %}
{% endfor %}
{% endif %}
</tbody>
</table>
</div>

{% endblock %}
12 changes: 11 additions & 1 deletion web/templates/runs/view.twig
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@
<thead>
<tr>
<th>函数</th>
{% if stack %}
<th>调用栈</th>
{% endif %}
<th>调用次数</th>
<th>执行时间</th>
<th>CPU时间</th>
Expand All @@ -112,11 +115,18 @@
<td class="text">
{{ helpers.tip_link(
key,
65,
45,
'run.symbol',
{'id': result.id|trim, 'symbol': key}
) }}
</td>
{% if stack %}
<td class="right">
{% if value.files %}
<a href="{{ path_for('url.stack', {}, {'id': result.id|trim, 'symbol': key}) }}">查看</a>
{% endif %}
</td>
{% endif %}
<td class="right">{{ value.ct }}</td>
<td class="right">{{ value.ewt|as_time }}</td>
<td class="right">{{ value.ecpu|as_time }}</td>
Expand Down

0 comments on commit fcbd62e

Please sign in to comment.