Skip to content

Commit

Permalink
Merge pull request #155 from newrelic/dev
Browse files Browse the repository at this point in the history
Merge 9.17.1 changes from dev to main
  • Loading branch information
Fahmy-Mohammed authored Apr 27, 2021
2 parents adbdca6 + 8375b36 commit 6498785
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 81 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ src/newrelic/infinite_tracing/com_newrelic_trace_v1/v1.pb.go: protocol/infinite_

.PHONY: integration
integration: Makefile daemon lasp-test-all
for PHP in $${PHPS:-7.4 7.3 7.2 7.1 7.0 5.6 5.5 5.4 5.3}; do \
for PHP in $${PHPS:-8.0 7.4 7.3 7.2 7.1 7.0 5.6 5.5 5.4 5.3}; do \
echo; echo "# PHP=$${PHP}"; \
env NRLAMP_PHP=$${PHP} bin/integration_runner $(INTEGRATION_ARGS) || exit 1; \
echo "# PHP=$${PHP}"; \
Expand Down Expand Up @@ -379,7 +379,7 @@ lasp-test: daemon
if [ ! $(SUITE_LASP) ]; then echo "USAGE: make lasp-test SUITE_LASP=suite-most-secure"; exit 1; fi
if [ "$(LICENSE_lasp_$(subst -,_,$(SUITE_LASP)))" = "" ] ; then echo "Missing license for $(SUITE_LASP)"; exit 1; fi
if [ ! -d "tests/lasp/$(SUITE_LASP)" ]; then echo "No such suite in tests/lasp folder"; exit 1; fi
for PHP in $${PHPS:-7.4 7.3 7.2 7.1 7.0 5.6 5.5 5.4 5.3}; do \
for PHP in $${PHPS:-8.0 7.4 7.3 7.2 7.1 7.0 5.6 5.5 5.4 5.3}; do \
echo; echo "# PHP=$${PHP}"; \
NRLAMP_PHP=$${PHP} bin/integration_runner $(INTEGRATION_ARGS) -loglevel debug \
-license $(LICENSE_lasp_$(subst -,_,$(SUITE_LASP))) \
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9.17.0
9.17.1
113 changes: 42 additions & 71 deletions agent/php_internal_instrument.c
Original file line number Diff line number Diff line change
Expand Up @@ -749,22 +749,50 @@ NR_INNER_WRAPPER(mysqli_options) {
}
}

static void nr_php_instrument_datastore_operation_call(
const nrinternalfn_t* nr_wrapper,
nr_datastore_t datastore,
const char* operation,
nr_datastore_instance_t* instance,
INTERNAL_FUNCTION_PARAMETERS) {
int zcaught = 0;
nr_segment_t* segment = NULL;
nr_segment_datastore_params_t params = {
.datastore = {
.type = datastore,
},
.operation = nr_strdup(operation),
.instance = instance,
.callbacks = {
.backtrace = nr_php_backtrace_callback,
},
};

segment = nr_segment_start(NRPRG(txn), NULL, NULL);
zcaught = nr_zend_call_old_handler(nr_wrapper->oldhandler,
INTERNAL_FUNCTION_PARAM_PASSTHRU);

nr_segment_datastore_end(&segment, &params);

nr_free(params.operation);

if (zcaught) {
zend_bailout();
/* NOTREACHED */
}
}

/*
* Handle
* bool mysqli_commit ( object $link [, int $flags=0, string $name] )
* bool mysqli::commit ( [, int $flags=0, string $name] )
*/
NR_INNER_WRAPPER(mysqli_commit) {
zval* mysqli_obj = NULL;
nr_segment_t* segment = NULL;
nr_datastore_instance_t* instance = NULL;
nr_explain_plan_t* plan = NULL;
char* name = NULL;
char* sqlstr = NULL;
nr_string_len_t sqlstrlen;
zend_long flags = 0;
nr_string_len_t name_len = 0;
int zcaught = 0;

if (FAILURE
== zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
Expand All @@ -780,35 +808,9 @@ NR_INNER_WRAPPER(mysqli_commit) {
mysqli_obj = NR_PHP_INTERNAL_FN_THIS();
}
}

if (NULL != name) {
sqlstr = nr_formatf("%s %s", "COMMIT", name);
} else {
sqlstr = nr_formatf("%s", "COMMIT");
}
sqlstrlen = nr_strlen(sqlstr);

segment = nr_segment_start(NRPRG(txn), NULL, NULL);

if (nrlikely(NULL != segment)) {
/*
* Set the stop time now so that we don't include the explain plan time.
*/
segment->stop_time = nr_txn_now_rel(NRPRG(txn));
instance = nr_php_mysqli_retrieve_datastore_instance(mysqli_obj TSRMLS_CC);

nr_php_txn_end_segment_sql(&segment, sqlstr, sqlstrlen, plan,
NR_DATASTORE_MYSQL, instance TSRMLS_CC);

nr_explain_plan_destroy(&plan);

}

nr_free(sqlstr);
if (zcaught) {
zend_bailout();
/* NOTREACHED */
}
nr_php_instrument_datastore_operation_call(nr_wrapper, NR_DATASTORE_MYSQL,
"commit", instance,
INTERNAL_FUNCTION_PARAM_PASSTHRU);
}

/*
Expand Down Expand Up @@ -1445,39 +1447,6 @@ NR_INNER_WRAPPER(mysqli_stmt_prepare) {
}
}

static void nr_php_instrument_datastore_operation_call(
const nrinternalfn_t* nr_wrapper,
nr_datastore_t datastore,
const char* operation,
nr_datastore_instance_t* instance,
INTERNAL_FUNCTION_PARAMETERS) {
int zcaught = 0;
nr_segment_t* segment = NULL;
nr_segment_datastore_params_t params = {
.datastore = {
.type = datastore,
},
.operation = nr_strdup(operation),
.instance = instance,
.callbacks = {
.backtrace = nr_php_backtrace_callback,
},
};

segment = nr_segment_start(NRPRG(txn), NULL, NULL);
zcaught = nr_zend_call_old_handler(nr_wrapper->oldhandler,
INTERNAL_FUNCTION_PARAM_PASSTHRU);

nr_segment_datastore_end(&segment, &params);

nr_free(params.operation);

if (zcaught) {
zend_bailout();
/* NOTREACHED */
}
}

/*
* Handle
* bool memcache_xxx( ... )
Expand Down Expand Up @@ -2698,11 +2667,13 @@ NR_INNER_WRAPPER(curl_multi_exec) {
int rv = FAILURE;

#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO /* PHP 8.0+ */
rv = zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"ol", &curlres, &still_running);
rv = zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
ZEND_NUM_ARGS() TSRMLS_CC, "ol", &curlres,
&still_running);
#else
rv = zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC,
"rl", &curlres, &still_running);
rv = zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
ZEND_NUM_ARGS() TSRMLS_CC, "rl", &curlres,
&still_running);
#endif /* PHP 8.0+ */

if (SUCCESS != rv) {
Expand Down
14 changes: 12 additions & 2 deletions agent/php_pdo.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ int nr_php_pdo_rebind_apply_parameter(struct pdo_bound_param_data* param,
zval* type = nr_php_zval_alloc();
zval* retval = NULL;

#ifdef PHP7
#if ZEND_MODULE_API_NO >= ZEND_7_0_X_API_NO /* PHP 7.0+ */
value = &param->parameter;
#else
value = param->parameter;
#endif /* PHP7 */
#endif /* PHP 7.0+ */

if (nr_php_zend_hash_key_is_string(hash_key)) {
/*
Expand All @@ -152,6 +152,16 @@ int nr_php_pdo_rebind_apply_parameter(struct pdo_bound_param_data* param,

ZVAL_LONG(type, param->param_type);

#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO /* PHP 8.0+ */
/*
* Create a reference to value to prevent PHP 8 from
* emitting a warning.
*/
if (!Z_ISREF_P(value)) {
Z_TRY_ADDREF_P(value);
ZVAL_NEW_REF(value, value);
}
#endif
retval = nr_php_call(stmt, "bindParam", key, value, type);

nr_php_zval_free(&key);
Expand Down
8 changes: 4 additions & 4 deletions axiom/nr_version.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
* Here's a list:
* https://en.wikipedia.org/wiki/List_of_colors_(compact)
*
* ube (9.14)
* vanilla (9.15)
* watermelon (9.16)
* xigua (9.17)
* ube 29Oct2020 (9.14)
* vanilla 07Dec2020 (9.15)
* watermelon 25Jan2021 (9.16)
* xigua 21Apr2021 (9.17)
*/
#define NR_CODENAME "xigua"

Expand Down
2 changes: 1 addition & 1 deletion docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ _(most operating systems package these with `-dev` or `-devel` suffixes)_

### PHP

The PHP agent supports PHP versions `5.3`, `5.4`, `5.5`, `5.6`, `7.0`, `7.1`, `7.2`, `7.3`, `7.4`, and `8.0`.
The PHP agent supports PHP versions `5.5`, `5.6`, `7.0`, `7.1`, `7.2`, `7.3`, `7.4`, and `8.0`.

## Build the PHP Agent

Expand Down
93 changes: 93 additions & 0 deletions tests/integration/pdo/test_prepared_stmt_params.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php
/*
* Copyright 2020 New Relic Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/

/*DESCRIPTION
The agent should record a slow sql trace when a prepared
statment with a parameter is executed via PDOStatement::execute()
exceeds the explain threshold.
*/

/*SKIPIF
<?php require('skipif_mysql.inc');
*/

/*INI
newrelic.datastore_tracer.database_name_reporting.enabled = 0
newrelic.datastore_tracer.instance_reporting.enabled = 0
newrelic.transaction_tracer.explain_enabled = true
newrelic.transaction_tracer.explain_threshold = 0
newrelic.transaction_tracer.record_sql = "obfuscated"
*/

/*EXPECT
ok - execute prepared statement with a param
*/

/*EXPECT_SLOW_SQLS
[
[
[
"OtherTransaction/php__FILE__",
"<unknown>",
"?? SQL id",
"select * from tables where table_name = ? limit ?;",
"Datastore/statement/MySQL/tables/select",
1,
"?? total time",
"?? min time",
"?? max time",
{
"backtrace": [
" in PDOStatement::execute called at __FILE__ (??)",
" in test_prepared_statement called at __FILE__ (??)"
],
"explain_plan": [
[
"id",
"select_type",
"table",
"type",
"possible_keys",
"key",
"key_len",
"ref",
"rows",
"Extra"
],
[
[
"1",
"SIMPLE",
"tables",
"ALL",
null,
"TABLE_NAME",
null,
null,
"??",
"??"
]
]
]
}
]
]
]
*/

require_once(realpath (dirname ( __FILE__ )) . '/../../include/tap.php');
require_once(realpath (dirname ( __FILE__ )) . '/pdo.inc');

function test_prepared_statement() {
global $PDO_MYSQL_DSN, $MYSQL_USER, $MYSQL_PASSWD;

$conn = new PDO($PDO_MYSQL_DSN, $MYSQL_USER, $MYSQL_PASSWD);
$stmt = $conn->prepare('select * from tables where table_name = ? limit 1;');
$stmt->bindValue(1, "missing");
tap_assert($stmt->execute(), 'execute prepared statement with a param');
}

test_prepared_statement();

0 comments on commit 6498785

Please sign in to comment.