Skip to content

Commit d7ffca5

Browse files
committed
Allow OCI8 to be DTrace-enabled independently of core PHP's DTrace
status. The proviso is OCI8 must be built "shared" when DTrace is enabled. This implementation (i) works around an incomplete core PHP solution for extension tracing (ii) avoid any issues with DOF section location and the complexities of needing to merge all provider .d files for static builds (iii) allows OCI8 to be DTrace-enabled when doing PECL installs of OCI8 on PHP versions without core PHP DTrace support. This is an initial patch i.e. it will undergo further testing.
1 parent 82da51b commit d7ffca5

File tree

5 files changed

+161
-57
lines changed

5 files changed

+161
-57
lines changed

ext/oci8/config.m4

Lines changed: 110 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,99 @@ AC_DEFUN([AC_OCI8_ORACLE_VERSION],[
8282
AC_MSG_RESULT($OCI8_ORACLE_VERSION)
8383
])
8484

85+
dnl
86+
dnl OCI8_INIT_DTRACE(providerdesc, header-file, sources)
87+
dnl This mimics PHP_INIT_DTRACE from PHP 5.4's acinclude.m4. It is
88+
dnl necessarily different from PHP_INIT_DTRACE which doesn't currently
89+
dnl support DTrace for extensions. Creating OCI8_INIT_DTRACE
90+
dnl independently instead of using a refactored PHP_INIT_DTRACE allows
91+
dnl OCI8 to be DTraced on versions of PHP where core PHP DTrace support
92+
dnl isn't available.
93+
dnl
94+
AC_DEFUN([OCI8_INIT_DTRACE],[
95+
ac_srcdir=[]PHP_EXT_SRCDIR([oci8])/
96+
ac_bdir=[]PHP_EXT_BUILDDIR([oci8])/
97+
98+
dnl providerdesc
99+
ac_provsrc=$1
100+
101+
dnl header-file
102+
ac_hdrobj=$2
103+
104+
dnl DTrace objects
105+
old_IFS=[$]IFS
106+
for ac_src in $3; do
107+
IFS=.
108+
set $ac_src
109+
ac_obj=[$]1
110+
IFS=$old_IFS
111+
112+
OCI8_DTRACE_OBJS="[$]OCI8_DTRACE_OBJS [$]ac_bdir[$]ac_obj.lo"
113+
done;
114+
115+
for ac_lo in $OCI8_DTRACE_OBJS; do
116+
dtrace_oci8_objs="[$]dtrace_oci8_objs `echo $ac_lo | $SED -e 's,\.lo$,.o,' -e 's#\(.*\)\/#\1\/.libs\/#'`"
117+
done;
118+
119+
dnl Generate Makefile.objects entry
120+
dnl The empty $ac_provsrc command stops an implicit circular dependency
121+
dnl in GNU Make which causes the .d file to be overwritten (Bug 61268)
122+
cat>>Makefile.objects<<EOF
123+
124+
PHP_EXT_SRCDIR([oci8])/$ac_provsrc:;
125+
126+
$ac_bdir[$]ac_hdrobj: $ac_srcdir[$]ac_provsrc
127+
CFLAGS="\$(CFLAGS_CLEAN)" dtrace -h -C -s $ac_srcdir[$]ac_provsrc -o \$[]@.bak && \$(SED) -e 's,PHP_,DTRACE_,g' \$[]@.bak > \$[]@
128+
129+
\$(OCI8_DTRACE_OBJS): $ac_bdir[$]ac_hdrobj
130+
131+
EOF
132+
133+
case $host_alias in
134+
*solaris*|*linux*)
135+
dtrace_prov_name="`echo $ac_provsrc | $SED -e 's#\(.*\)\/##'`.o"
136+
dtrace_lib_dir="`echo $ac_bdir[$]ac_provsrc | $SED -e 's#\(.*\)/[^/]*#\1#'`/.libs"
137+
dtrace_d_obj="`echo $ac_bdir[$]ac_provsrc | $SED -e 's#\(.*\)/\([^/]*\)#\1/.libs/\2#'`.o"
138+
dtrace_nolib_objs='$(OCI8_DTRACE_OBJS:.lo=.o)'
139+
for ac_lo in $OCI8_DTRACE_OBJS; do
140+
dtrace_oci8_lib_objs="[$]dtrace_oci8_lib_objs `echo $ac_lo | $SED -e 's,\.lo$,.o,' -e 's#\(.*\)\/#\1\/.libs\/#'`"
141+
done;
142+
dnl Always attempt to create both PIC and non-PIC DTrace objects (Bug 63692)
143+
cat>>Makefile.objects<<EOF
144+
$ac_bdir[$]ac_provsrc.lo: \$(OCI8_DTRACE_OBJS)
145+
echo "[#] Generated by Makefile for libtool" > \$[]@
146+
@test -d "$dtrace_lib_dir" || mkdir $dtrace_lib_dir
147+
if CFLAGS="\$(CFLAGS_CLEAN)" dtrace -G -o $dtrace_d_obj -s $ac_srcdir[$]ac_provsrc $dtrace_oci8_lib_objs 2> /dev/null && test -f "$dtrace_d_obj"; then [\\]
148+
echo "pic_object=['].libs/$dtrace_prov_name[']" >> \$[]@ [;\\]
149+
else [\\]
150+
echo "pic_object='none'" >> \$[]@ [;\\]
151+
fi
152+
if CFLAGS="\$(CFLAGS_CLEAN)" dtrace -G -o $ac_bdir[$]ac_provsrc.o -s $ac_srcdir[$]ac_provsrc $dtrace_nolib_objs 2> /dev/null && test -f "$ac_bdir[$]ac_provsrc.o"; then [\\]
153+
echo "non_pic_object=[']$dtrace_prov_name[']" >> \$[]@ [;\\]
154+
else [\\]
155+
echo "non_pic_object='none'" >> \$[]@ [;\\]
156+
fi
157+
158+
EOF
159+
;;
160+
*)
161+
AC_MSG_WARN([OCI8 extension: OCI8 DTrace support is not confirmed on this platform])
162+
cat>>Makefile.objects<<EOF
163+
$ac_bdir[$]ac_provsrc.o: \$(OCI8_DTRACE_OBJS)
164+
CFLAGS="\$(CFLAGS_CLEAN)" dtrace -G -o \$[]@ -s $ac_srcdir[$]ac_provsrc $dtrace_oci8_objs
165+
166+
EOF
167+
;;
168+
esac
169+
])
170+
85171

86172
dnl --with-oci8=shared,instantclient,/path/to/client/dir/lib
87173
dnl or
88174
dnl --with-oci8=shared,/path/to/oracle/home
89175
PHP_ARG_WITH(oci8, for Oracle Database OCI8 support,
90-
[ --with-oci8[=DIR] Include Oracle Database OCI8 support. DIR defaults to \$ORACLE_HOME.
91-
Use --with-oci8=instantclient,/path/to/instant/client/lib
176+
[ --with-oci8[=DIR] Include Oracle Database OCI8 support. DIR defaults to [$]ORACLE_HOME.
177+
Use --with-oci8=instantclient,/path/to/instant/client/lib
92178
to use an Oracle Instant Client installation])
93179

94180
if test "$PHP_OCI8" != "no"; then
@@ -128,22 +214,30 @@ if test "$PHP_OCI8" != "no"; then
128214
AC_MSG_RESULT([$php_version, ok])
129215
fi
130216

131-
dnl conditionally define PHP_INIT_DTRACE.
132-
dnl This prevents 'configure' failing for PECL installs on older PHP versions.
133-
dnl Note DTrace support can't be enabled on older PHP versions.
134-
AC_PROVIDE_IFELSE([PHP_INIT_DTRACE], [], [AC_DEFUN([PHP_INIT_DTRACE], )])
135-
136-
if test "$PHP_DTRACE" = "yes"; then
137-
if test "$oci8_php_version" -lt "5004000"; then
138-
AC_MSG_ERROR([You need at least PHP 5.4 to be able to use DTrace with PHP OCI8])
217+
dnl Check whether --enable-dtrace was set.
218+
dnl To use DTrace with a PECL install, extract the OCI8 archive, phpize it, and set
219+
dnl PHP_DTRACE=yes before running configure
220+
AC_MSG_CHECKING([OCI8 DTrace support])
221+
oci8_do_dtrace="`echo $PHP_OCI8 | cut -d, -f3`"
222+
if test "$PHP_DTRACE" = "yes" -o "$oci8_do_dtrace" = "dtrace" ; then
223+
AC_MSG_RESULT([yes])
224+
if test "$ext_shared" = "no"; then
225+
AC_MSG_ERROR([For DTrace support OCI8 must be configured as a shared extension])
139226
else
140227
AC_CHECK_HEADERS([sys/sdt.h], [
141-
PHP_INIT_DTRACE([ext/oci8/oci8_dtrace.d],[ext/oci8/oci8_dtrace_gen.h],[ext/oci8/oci8.c ext/oci8/oci8_statement.c])
228+
OCI8_INIT_DTRACE([oci8_dtrace.d],[oci8_dtrace_gen.h],[oci8.c oci8_statement.c])
229+
142230
], [
143231
AC_MSG_ERROR(
144232
[Cannot find sys/sdt.h which is required for DTrace support])
145233
])
234+
PHP_SUBST(OCI8_DTRACE_OBJS)
235+
AC_DEFINE(HAVE_OCI8_DTRACE,1,[Defined to 1 if PHP OCI8 DTrace support was enabled during configuration])
236+
dnl Developer warning: hard coded extension is OK for the known supported environments
237+
shared_objects_oci8="$shared_objects_oci8 PHP_EXT_BUILDDIR(oci8)/oci8_dtrace.d.lo"
146238
fi
239+
else
240+
AC_MSG_RESULT([no])
147241
fi
148242

149243
dnl Set some port specific directory components for use later
@@ -255,14 +349,14 @@ if test "$PHP_OCI8" != "no"; then
255349
;;
256350

257351
*)
258-
AC_DEFINE(HAVE_OCI_LOB_READ2,1,[ ])
352+
AC_DEFINE(HAVE_OCI_LOB_READ2,1,[Defined to 1 if OCI8 configuration located Oracle's OCILobRead2 function])
259353
;;
260354
esac
261355

262356
PHP_ADD_LIBRARY(clntsh, 1, OCI8_SHARED_LIBADD)
263357
PHP_ADD_LIBPATH($OCI8_DIR/$OCI8_LIB_DIR, OCI8_SHARED_LIBADD)
264358
PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c, $ext_shared)
265-
AC_DEFINE(HAVE_OCI8,1,[ ])
359+
AC_DEFINE(HAVE_OCI8,1,[Defined to 1 if the PHP OCI8 extension for Oracle Database is configured])
266360

267361
PHP_SUBST_OLD(OCI8_SHARED_LIBADD)
268362
PHP_SUBST_OLD(OCI8_DIR)
@@ -330,11 +424,11 @@ if test "$PHP_OCI8" != "no"; then
330424
PHP_ADD_LIBRARY(clntsh, 1, OCI8_SHARED_LIBADD)
331425
PHP_ADD_LIBPATH($PHP_OCI8_INSTANT_CLIENT, OCI8_SHARED_LIBADD)
332426

333-
AC_DEFINE(HAVE_OCI_INSTANT_CLIENT,1,[ ])
334-
AC_DEFINE(HAVE_OCI_LOB_READ2,1,[ ])
427+
AC_DEFINE(HAVE_OCI_INSTANT_CLIENT,1,[Defined to 1 if OCI8 configuration located Oracle's Instant Client libraries])
428+
AC_DEFINE(HAVE_OCI_LOB_READ2,1,[Defined to 1 if OCI8 configuration located Oracle's OCILobRead2 function])
335429

336430
PHP_NEW_EXTENSION(oci8, oci8.c oci8_lob.c oci8_statement.c oci8_collection.c oci8_interface.c, $ext_shared)
337-
AC_DEFINE(HAVE_OCI8,1,[ ])
431+
AC_DEFINE(HAVE_OCI8,1,[Defined to 1 if the PHP OCI8 extension for Oracle Database is configured])
338432

339433
PHP_SUBST_OLD(OCI8_SHARED_LIBADD)
340434
PHP_SUBST_OLD(OCI8_DIR)

ext/oci8/oci8.c

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,13 +1354,20 @@ PHP_MINFO_FUNCTION(oci)
13541354

13551355
php_info_print_table_start();
13561356
php_info_print_table_row(2, "OCI8 Support", "enabled");
1357+
#if defined(HAVE_OCI8_DTRACE)
1358+
php_info_print_table_row(2, "OCI8 DTrace Support", "enabled");
1359+
#else
1360+
php_info_print_table_row(2, "OCI8 DTrace Support", "disabled");
1361+
#endif
13571362
php_info_print_table_row(2, "OCI8 Version", PHP_OCI8_VERSION);
13581363
php_info_print_table_row(2, "Revision", "$Id$");
13591364

13601365
#if ((OCI_MAJOR_VERSION > 10) || ((OCI_MAJOR_VERSION == 10) && (OCI_MINOR_VERSION >= 2)))
13611366
php_oci_client_get_version(&ver TSRMLS_CC);
13621367
php_info_print_table_row(2, "Oracle Run-time Client Library Version", ver);
13631368
efree(ver);
1369+
#else
1370+
php_info_print_table_row(2, "Oracle Run-time Client Library Version", "Unknown");
13641371
#endif
13651372
#if defined(OCI_MAJOR_VERSION) && defined(OCI_MINOR_VERSION)
13661373
snprintf(buf, sizeof(buf), "%d.%d", OCI_MAJOR_VERSION, OCI_MINOR_VERSION);
@@ -1384,6 +1391,7 @@ PHP_MINFO_FUNCTION(oci)
13841391
#endif
13851392
#endif
13861393

1394+
13871395
php_info_print_table_end();
13881396

13891397
DISPLAY_INI_ENTRIES();
@@ -1467,11 +1475,11 @@ static void php_oci_pconnection_list_np_dtor(zend_rsrc_list_entry *entry TSRMLS_
14671475
OCI_G(num_persistent)--;
14681476
}
14691477

1470-
#ifdef HAVE_DTRACE
1478+
#ifdef HAVE_OCI8_DTRACE
14711479
if (DTRACE_OCI8_CONNECT_P_DTOR_CLOSE_ENABLED()) {
14721480
DTRACE_OCI8_CONNECT_P_DTOR_CLOSE(connection);
14731481
}
1474-
#endif /* HAVE_DTRACE */
1482+
#endif /* HAVE_OCI8_DTRACE */
14751483
} else {
14761484
/*
14771485
* Release the connection to underlying pool. We do this unconditionally so that
@@ -1484,11 +1492,11 @@ static void php_oci_pconnection_list_np_dtor(zend_rsrc_list_entry *entry TSRMLS_
14841492
*/
14851493
php_oci_connection_release(connection TSRMLS_CC);
14861494

1487-
#ifdef HAVE_DTRACE
1495+
#ifdef HAVE_OCI8_DTRACE
14881496
if (DTRACE_OCI8_CONNECT_P_DTOR_RELEASE_ENABLED()) {
14891497
DTRACE_OCI8_CONNECT_P_DTOR_RELEASE(connection);
14901498
}
1491-
#endif /* HAVE_DTRACE */
1499+
#endif /* HAVE_OCI8_DTRACE */
14921500
}
14931501
}
14941502
/* }}} */
@@ -1687,11 +1695,11 @@ sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC)
16871695
break;
16881696
}
16891697

1690-
#ifdef HAVE_DTRACE
1698+
#ifdef HAVE_OCI8_DTRACE
16911699
if (DTRACE_OCI8_ERROR_ENABLED()) {
16921700
DTRACE_OCI8_ERROR(status, errcode);
16931701
}
1694-
#endif /* HAVE_DTRACE */
1702+
#endif /* HAVE_OCI8_DTRACE */
16951703

16961704
return errcode;
16971705
}
@@ -1771,23 +1779,23 @@ void php_oci_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent, int exclus
17711779
return;
17721780
}
17731781

1774-
#ifdef HAVE_DTRACE
1782+
#ifdef HAVE_OCI8_DTRACE
17751783
if (DTRACE_OCI8_CONNECT_ENTRY_ENABLED()) {
17761784
DTRACE_OCI8_CONNECT_ENTRY(username, dbname, charset, session_mode, persistent, exclusive);
17771785
}
1778-
#endif /* HAVE_DTRACE */
1786+
#endif /* HAVE_OCI8_DTRACE */
17791787

17801788
if (!charset_len) {
17811789
charset = NULL;
17821790
}
17831791

17841792
connection = php_oci_do_connect_ex(username, username_len, password, password_len, NULL, 0, dbname, dbname_len, charset, session_mode, persistent, exclusive TSRMLS_CC);
17851793

1786-
#ifdef HAVE_DTRACE
1794+
#ifdef HAVE_OCI8_DTRACE
17871795
if (DTRACE_OCI8_CONNECT_RETURN_ENABLED()) {
17881796
DTRACE_OCI8_CONNECT_RETURN(connection);
17891797
}
1790-
#endif /* HAVE_DTRACE */
1798+
#endif /* HAVE_OCI8_DTRACE */
17911799

17921800

17931801
if (!connection) {
@@ -1955,11 +1963,11 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
19551963
}
19561964
}
19571965

1958-
#ifdef HAVE_DTRACE
1966+
#ifdef HAVE_OCI8_DTRACE
19591967
if (DTRACE_OCI8_CONNECT_LOOKUP_ENABLED()) {
19601968
DTRACE_OCI8_CONNECT_LOOKUP(connection, connection && connection->is_stub ? 1 : 0);
19611969
}
1962-
#endif /* HAVE_DTRACE */
1970+
#endif /* HAVE_OCI8_DTRACE */
19631971

19641972
/* If we got a pconnection stub, then 'load'(OCISessionGet) the real connection from its
19651973
* private spool A connection is a stub if it is only a cached structure and the real
@@ -2186,11 +2194,11 @@ php_oci_connection *php_oci_do_connect_ex(char *username, int username_len, char
21862194
OCI_G(num_links)++;
21872195
}
21882196

2189-
#ifdef HAVE_DTRACE
2197+
#ifdef HAVE_OCI8_DTRACE
21902198
if (DTRACE_OCI8_CONNECT_TYPE_ENABLED()) {
21912199
DTRACE_OCI8_CONNECT_TYPE(connection->is_persistent ? 1 : 0, exclusive ? 1 : 0, connection, OCI_G(num_persistent), OCI_G(num_links));
21922200
}
2193-
#endif /* HAVE_DTRACE */
2201+
#endif /* HAVE_OCI8_DTRACE */
21942202

21952203
return connection;
21962204
}
@@ -2773,11 +2781,11 @@ static int php_oci_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
27732781
connection = (php_oci_connection *)le->ptr;
27742782

27752783
if (!connection->used_this_request && OCI_G(persistent_timeout) != -1) {
2776-
#ifdef HAVE_DTRACE
2784+
#ifdef HAVE_OCI8_DTRACE
27772785
if (DTRACE_OCI8_CONNECT_EXPIRY_ENABLED()) {
27782786
DTRACE_OCI8_CONNECT_EXPIRY(connection, connection->is_stub ? 1 : 0, connection->idle_expiry, timestamp);
27792787
}
2780-
#endif /* HAVE_DTRACE */
2788+
#endif /* HAVE_OCI8_DTRACE */
27812789
if (connection->idle_expiry < timestamp) {
27822790
/* connection has timed out */
27832791
return ZEND_HASH_APPLY_REMOVE;
@@ -2913,11 +2921,11 @@ static php_oci_spool *php_oci_create_spool(char *username, int username_len, cha
29132921
PHP_OCI_CALL(OCIHandleFree, ((dvoid *) spoolAuth, (ub4) OCI_HTYPE_AUTHINFO));
29142922
}
29152923

2916-
#ifdef HAVE_DTRACE
2924+
#ifdef HAVE_OCI8_DTRACE
29172925
if (DTRACE_OCI8_SESSPOOL_CREATE_ENABLED()) {
29182926
DTRACE_OCI8_SESSPOOL_CREATE(session_pool);
29192927
}
2920-
#endif /* HAVE_DTRACE */
2928+
#endif /* HAVE_OCI8_DTRACE */
29212929

29222930
return session_pool;
29232931
}
@@ -3241,11 +3249,11 @@ static int php_oci_create_session(php_oci_connection *connection, php_oci_spool
32413249
connection->using_spool = 1;
32423250
}
32433251

3244-
#ifdef HAVE_DTRACE
3252+
#ifdef HAVE_OCI8_DTRACE
32453253
if (DTRACE_OCI8_SESSPOOL_TYPE_ENABLED()) {
32463254
DTRACE_OCI8_SESSPOOL_TYPE(session_pool ? 1 : 0, session_pool ? session_pool : connection->private_spool);
32473255
}
3248-
#endif /* HAVE_DTRACE */
3256+
#endif /* HAVE_OCI8_DTRACE */
32493257

32503258
/* The passed in "connection" can be a cached stub from plist or freshly created. In the former
32513259
* case, we do not have to allocate any handles
@@ -3294,15 +3302,15 @@ static int php_oci_create_session(php_oci_connection *connection, php_oci_spool
32943302
/* }}} */
32953303

32963304
/* {{{ Debug statements */
3297-
#ifdef HAVE_DTRACE
3305+
#ifdef HAVE_OCI8_DTRACE
32983306
if (DTRACE_OCI8_SESSPOOL_STATS_ENABLED()) {
32993307
ub4 numfree = 0, numbusy = 0, numopen = 0;
33003308
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)actual_spool->poolh, OCI_HTYPE_SPOOL, (dvoid *)&numopen, (ub4 *)0, OCI_ATTR_SPOOL_OPEN_COUNT, OCI_G(err)));
33013309
PHP_OCI_CALL_RETURN(OCI_G(errcode), OCIAttrGet, ((dvoid *)actual_spool->poolh, OCI_HTYPE_SPOOL, (dvoid *)&numbusy, (ub4 *)0, OCI_ATTR_SPOOL_BUSY_COUNT, OCI_G(err)));
33023310
numfree = numopen - numbusy; /* number of free connections in the pool */
33033311
DTRACE_OCI8_SESSPOOL_STATS(numfree, numbusy, numopen);
33043312
}
3305-
#endif /* HAVE_DTRACE */
3313+
#endif /* HAVE_OCI8_DTRACE */
33063314
/* }}} */
33073315

33083316
/* Ping loop: Ping and loop till we get a good connection. When a database instance goes
@@ -3471,11 +3479,11 @@ static sword php_oci_ping_init(php_oci_connection *connection, OCIError *errh TS
34713479
*/
34723480
void php_oci_dtrace_check_connection(php_oci_connection *connection, sword errcode, ub4 serverStatus)
34733481
{
3474-
#ifdef HAVE_DTRACE
3482+
#ifdef HAVE_OCI8_DTRACE
34753483
if (DTRACE_OCI8_CHECK_CONNECTION_ENABLED()) {
34763484
DTRACE_OCI8_CHECK_CONNECTION(connection, connection && connection->is_open ? 1 : 0, (int)errcode, (unsigned long)serverStatus);
34773485
}
3478-
#endif /* HAVE_DTRACE */
3486+
#endif /* HAVE_OCI8_DTRACE */
34793487
}
34803488
/* }}} */
34813489

0 commit comments

Comments
 (0)