Author: timbo
Date: Thu Mar 11 02:47:17 2004
New Revision: 212
Modified:
dbi/trunk/DBI.pm
dbi/trunk/DBI.xs
dbi/trunk/t/09trace.t
Log:
Fix $h->trace with no args core dump
Fix ShowErrorStatement core dump if error triggered by certain methods
(thanks to Jeff Urlwin for finding these)
Modified: dbi/trunk/DBI.pm
==============================================================================
--- dbi/trunk/DBI.pm (original)
+++ dbi/trunk/DBI.pm Thu Mar 11 02:47:17 2004
@@ -1251,7 +1251,7 @@
}
}
if (@unknown && (ref $h ? $h->FETCH('Warn') : 1)) {
- Carp::carp("$h->parse_trace_flags($spec): Unknown trace flags ignored: ".
+ Carp::carp("$h->parse_trace_flags($spec) ignored unknown trace flags: ".
join(" ", map { DBI::neat($_) } @unknown));
}
$flags |= $level;
Modified: dbi/trunk/DBI.xs
==============================================================================
--- dbi/trunk/DBI.xs (original)
+++ dbi/trunk/DBI.xs Thu Mar 11 02:47:17 2004
@@ -621,6 +621,9 @@
parse_trace_flags(SV *h, SV *level_sv, IV old_level)
{
IV level;
+ if (!level_sv || !SvOK(level_sv))
+ level = old_level; /* undef: no change */
+ else
if (SvTRUE(level_sv)) {
if (looks_like_number(level_sv) && SvIV(level_sv)>=0)
level = SvIV(level_sv); /* number: number */
@@ -637,10 +640,8 @@
PUTBACK;
}
}
- else if (SvOK(level_sv))
- level = 0; /* defined but false: 0 */
- else
- level = old_level; /* undef: no change */
+ else /* defined but false: 0 */
+ level = 0;
return level;
}
@@ -2290,6 +2291,7 @@
char *meth_name = GvNAME(CvGV(cv));
dbi_ima_t *ima = (dbi_ima_t*)CvXSUBANY(cv).any_ptr;
+ U32 ima_flags = (ima) ? ima->flags : 0;
imp_xxh_t *imp_xxh = NULL;
SV *imp_msv = Nullsv;
SV *qsv = Nullsv; /* quick result from a shortcut method */
@@ -2300,7 +2302,7 @@
PerlIO_printf(logfp,"%c >> %-11s DISPATCH (%s rc%ld/%ld @%ld g%x ima%lx
pid#%ld)",
(dirty?'!':' '), meth_name, neatsvpv(h,0),
(long)SvREFCNT(h), (SvROK(h) ? (long)SvREFCNT(SvRV(h)) : (long)-1),
- (long)items, (int)gimme, (long)(ima?ima->flags:0),
(long)PerlProc_getpid());
+ (long)items, (int)gimme, (long)ima_flags, (long)PerlProc_getpid());
PerlIO_puts(logfp, log_where(trace_level, 0, 0, "\n"));
PerlIO_flush(logfp);
}
@@ -2394,9 +2396,9 @@
/* Check method call against Internal Method Attributes */
if (ima) {
- if (ima->flags &
(IMA_STUB|IMA_FUNC_REDIRECT|IMA_KEEP_ERR|IMA_KEEP_ERR_SUB|IMA_CLEAR_STMT|IMA_EXECUTE))
{
+ if (ima_flags &
(IMA_STUB|IMA_FUNC_REDIRECT|IMA_KEEP_ERR|IMA_KEEP_ERR_SUB|IMA_CLEAR_STMT|IMA_EXECUTE))
{
- if (ima->flags & IMA_STUB) {
+ if (ima_flags & IMA_STUB) {
if (*meth_name == 'c' && strEQ(meth_name,"can")) {
char *can_meth = SvPV(st1,lna);
SV *dbi_msv = Nullsv;
@@ -2418,7 +2420,7 @@
}
XSRETURN(0);
}
- if (ima->flags & IMA_FUNC_REDIRECT) {
+ if (ima_flags & IMA_FUNC_REDIRECT) {
SV *meth_name_sv = POPs;
PUTBACK;
--items;
@@ -2427,24 +2429,24 @@
neatsvpv(h,0), meth_name, neatsvpv(meth_name_sv,0));
meth_name = SvPV(meth_name_sv, lna);
}
- if (ima->flags & IMA_EXECUTE) {
+ if (ima_flags & IMA_EXECUTE) {
imp_xxh_t *parent = DBIc_PARENT_COM(imp_xxh);
DBIc_on(imp_xxh, DBIcf_Executed);
if (parent)
DBIc_on(parent, DBIcf_Executed);
}
- if (ima->flags & IMA_KEEP_ERR)
+ if (ima_flags & IMA_KEEP_ERR)
keep_error = TRUE;
- if (ima->flags & IMA_KEEP_ERR_SUB
+ if (ima_flags & IMA_KEEP_ERR_SUB
&& DBIc_PARENT_COM(imp_xxh) &&
DBIc_CALL_DEPTH(DBIc_PARENT_COM(imp_xxh)) > 0)
keep_error = TRUE;
- if (ima->flags & IMA_CLEAR_STMT) {
+ if (ima_flags & IMA_CLEAR_STMT) {
/* don't use SvOK_off: dbh's Statement may be ref to sth's */
hv_store((HV*)SvRV(h), "Statement", 9, &sv_undef, 0);
}
}
- if (ima->flags & IMA_HAS_USAGE) {
+ if (ima_flags & IMA_HAS_USAGE) {
char *err = NULL;
char msg[200];
@@ -2465,7 +2467,7 @@
if (tainting && items > 1 /* method call has args */
&& DBIc_is(imp_xxh, DBIcf_TaintIn) /* taint checks requested */
- && !(ima && ima->flags & IMA_NO_TAINT_IN)
+ && !(ima_flags & IMA_NO_TAINT_IN)
) {
for(i=1; i < items; ++i) {
if (SvTAINTED(ST(i))) {
@@ -2525,13 +2527,11 @@
SAVEINT(DBIc_CALL_DEPTH(imp_xxh));
call_depth = ++DBIc_CALL_DEPTH(imp_xxh);
- if (ima) {
- if (ima->flags & IMA_COPY_UP_STMT) { /* execute() */
- SV *parent = DBIc_PARENT_H(imp_xxh);
- SV *tmp_sv = *hv_fetch((HV*)SvRV(h), "Statement", 9, 1);
- /* XXX sv_copy() if Profiling? */
- hv_store((HV*)SvRV(parent), "Statement", 9, SvREFCNT_inc(tmp_sv), 0);
- }
+ if (ima_flags & IMA_COPY_UP_STMT) { /* execute() */
+ SV *parent = DBIc_PARENT_H(imp_xxh);
+ SV *tmp_sv = *hv_fetch((HV*)SvRV(h), "Statement", 9, 1);
+ /* XXX sv_copy() if Profiling? */
+ hv_store((HV*)SvRV(parent), "Statement", 9, SvREFCNT_inc(tmp_sv), 0);
}
}
@@ -2624,7 +2624,7 @@
outitems = 0;
goto post_dispatch;
}
- if (ima && ima->flags & IMA_NOT_FOUND_OKAY) {
+ if (ima_flags & IMA_NOT_FOUND_OKAY) {
outitems = 0;
goto post_dispatch;
}
@@ -2703,9 +2703,9 @@
goto skip_meth_return_trace;
}
if (SvOK(err_sv)) {
- PerlIO_printf(logfp, " %s %s %s %s\n", (keep_error) ? " " : "!!",
+ PerlIO_printf(logfp, " %s %s %s %s (err#%ld)\n", (keep_error) ? " " :
"!!",
SvTRUE(err_sv) ? "ERROR:" : strlen(SvPV_nolen(err_sv)) ? "warn:" :
"info:",
- neatsvpv(err_sv,0), neatsvpv(DBIc_ERRSTR(imp_xxh),0));
+ neatsvpv(err_sv,0), neatsvpv(DBIc_ERRSTR(imp_xxh),0),
(long)DBIc_ErrCount(imp_xxh));
}
PerlIO_printf(logfp,"%c%c <%c %s",
(call_depth > 1) ? '0'+call_depth-1 : (dirty?'!':' '),
@@ -2763,7 +2763,7 @@
PerlIO_flush(logfp);
}
- if (ima && ima->flags & IMA_END_WORK) { /* commit() or rollback() */
+ if (ima_flags & IMA_END_WORK) { /* commit() or rollback() */
DBIc_off(imp_xxh, DBIcf_Executed);
if (DBIc_has(imp_xxh, DBIcf_BegunWork)) {
@@ -2790,7 +2790,7 @@
/* XXX this would taint *everything* being returned from *any* */
/* method that doesn't have IMA_NO_TAINT_OUT set. */
/* DISABLED: just tainting fetched data in get_fbav seems ok */
- && 0/* XXX disabled*/ /* !(ima && ima->flags & IMA_NO_TAINT_OUT) */
+ && 0/* XXX disabled*/ /* !(ima_flags & IMA_NO_TAINT_OUT) */
) {
dTHR;
TAINT; /* affects sv_setsv()'s within same perl statement */
@@ -2857,8 +2857,8 @@
sv_catsv(msg, DBIc_ERRSTR(imp_xxh));
if ( DBIc_has(imp_xxh, DBIcf_ShowErrorStatement)
- && (DBIc_TYPE(imp_xxh) == DBIt_ST || ima->flags & IMA_SHOW_ERR_STMT)
- && !(ima->flags & IMA_UNRELATED_TO_STMT) /* error unrelated to
Statement */
+ && (DBIc_TYPE(imp_xxh) == DBIt_ST || ima_flags & IMA_SHOW_ERR_STMT)
+ && !(ima_flags & IMA_UNRELATED_TO_STMT) /* error unrelated to Statement */
&& (statement_svp = hv_fetch((HV*)SvRV(h), "Statement", 9, 0))
&& statement_svp && SvOK(*statement_svp)
) {
@@ -2938,7 +2938,7 @@
}
if (profile_t1) { /* see also dbi_profile() call a few lines below */
- char *Statement = (ima && ima->flags & IMA_UNRELATED_TO_STMT) ? "" :
Nullch;
+ char *Statement = (ima_flags & IMA_UNRELATED_TO_STMT) ? "" : Nullch;
dbi_profile(h, imp_xxh, Statement, imp_msv ? imp_msv : (SV*)cv,
profile_t1, dbi_time());
}
@@ -2954,7 +2954,7 @@
}
}
else if (profile_t1) { /* see also dbi_profile() call a few lines above */
- char *Statement = (ima && ima->flags & IMA_UNRELATED_TO_STMT) ? "" : Nullch;
+ char *Statement = (ima_flags & IMA_UNRELATED_TO_STMT) ? "" : Nullch;
dbi_profile(h, imp_xxh, Statement, imp_msv ? imp_msv : (SV*)cv,
profile_t1, dbi_time());
}
@@ -4069,7 +4069,7 @@
int
-trace(h, level=0, file=Nullsv)
+trace(h, level=&sv_undef, file=Nullsv)
SV *h
SV *level
SV *file
Modified: dbi/trunk/t/09trace.t
==============================================================================
--- dbi/trunk/t/09trace.t (original)
+++ dbi/trunk/t/09trace.t Thu Mar 11 02:47:17 2004
@@ -5,7 +5,7 @@
use Test::More;
use DBI;
-BEGIN { plan tests => 53 }
+BEGIN { plan tests => 65 }
$|=1;
@@ -46,8 +46,14 @@
$dbh->{TraceLevel} = $flag1;
is( $dbh->{TraceLevel}, $flag1 );
+
$dbh->{TraceLevel} = 0;
is( $dbh->{TraceLevel}, 0 );
+
+ $dbh->trace($flag1);
+ is $dbh->trace, $flag1;
+ is $dbh->{TraceLevel}, $flag1;
+
$dbh->{TraceLevel} = $name; # set by name
$dbh->{TraceLevel} = undef; # check no change on undef
is( $dbh->{TraceLevel}, $flag1 );