This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
begin filling the 5.16.0 delta from 5.15.7
[perl5.git] / util.c
diff --git a/util.c b/util.c
index 7583d23..1ff5913 100644 (file)
--- a/util.c
+++ b/util.c
@@ -94,8 +94,8 @@ Perl_safesysmalloc(MEM_SIZE size)
     size += sTHX;
 #endif
 #ifdef DEBUGGING
-    if ((long)size < 0)
-       Perl_croak_nocontext("panic: malloc");
+    if ((SSize_t)size < 0)
+       Perl_croak_nocontext("panic: malloc, size=%"UVuf, (UV) size);
 #endif
     ptr = (Malloc_t)PerlMem_malloc(size?size:1);       /* malloc(0) is NASTY on our system */
     PERL_ALLOC_CHECK(ptr);
@@ -172,7 +172,8 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size)
            = (struct perl_memory_debug_header *)where;
 
        if (header->interpreter != aTHX) {
-           Perl_croak_nocontext("panic: realloc from wrong pool");
+           Perl_croak_nocontext("panic: realloc from wrong pool, %p!=%p",
+                                header->interpreter, aTHX);
        }
        assert(header->next->prev == header);
        assert(header->prev->next == header);
@@ -187,8 +188,8 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size)
     }
 #endif
 #ifdef DEBUGGING
-    if ((long)size < 0)
-       Perl_croak_nocontext("panic: realloc");
+    if ((SSize_t)size < 0)
+       Perl_croak_nocontext("panic: realloc, size=%"UVuf, (UV)size);
 #endif
     ptr = (Malloc_t)PerlMem_realloc(where,size);
     PERL_ALLOC_CHECK(ptr);
@@ -258,14 +259,19 @@ Perl_safesysfree(Malloc_t where)
                = (struct perl_memory_debug_header *)where;
 
            if (header->interpreter != aTHX) {
-               Perl_croak_nocontext("panic: free from wrong pool");
+               Perl_croak_nocontext("panic: free from wrong pool, %p!=%p",
+                                    header->interpreter, aTHX);
            }
            if (!header->prev) {
                Perl_croak_nocontext("panic: duplicate free");
            }
-           if (!(header->next) || header->next->prev != header
-               || header->prev->next != header) {
-               Perl_croak_nocontext("panic: bad free");
+           if (!(header->next))
+               Perl_croak_nocontext("panic: bad free, header->next==NULL");
+           if (header->next->prev != header || header->prev->next != header) {
+               Perl_croak_nocontext("panic: bad free, ->next->prev=%p, "
+                                    "header=%p, ->prev->next=%p",
+                                    header->next->prev, header,
+                                    header->prev->next);
            }
            /* Unlink us from the chain.  */
            header->next->prev = header->prev;
@@ -316,8 +322,9 @@ Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size)
     }
 #endif /* HAS_64K_LIMIT */
 #ifdef DEBUGGING
-    if ((long)size < 0 || (long)count < 0)
-       Perl_croak_nocontext("panic: calloc");
+    if ((SSize_t)size < 0 || (SSize_t)count < 0)
+       Perl_croak_nocontext("panic: calloc, size=%"UVuf", count=%"UVuf,
+                            (UV)size, (UV)count);
 #endif
 #ifdef PERL_TRACK_MEMPOOL
     /* Have to use malloc() because we've added some space for our tracking
@@ -460,7 +467,8 @@ Perl_instr(register const char *big, register const char *little)
     return NULL;
 }
 
-/* same as instr but allow embedded nulls */
+/* same as instr but allow embedded nulls.  The end pointers point to 1 beyond
+ * the final character desired to be checked */
 
 char *
 Perl_ninstr(const char *big, const char *bigend, const char *little, const char *lend)
@@ -2735,7 +2743,7 @@ Perl_my_popen_list(pTHX_ const char *mode, int n, SV **args)
            int pid2, status;
            PerlLIO_close(p[This]);
            if (n != sizeof(int))
-               Perl_croak(aTHX_ "panic: kid popen errno read");
+               Perl_croak(aTHX_ "panic: kid popen errno read, n=%u", n);
            do {
                pid2 = wait4pid(pid, &status, 0);
            } while (pid2 == -1 && errno == EINTR);
@@ -2849,9 +2857,6 @@ Perl_my_popen(pTHX_ const char *cmd, const char *mode)
       default, binary, low-level mode; see PerlIOBuf_open(). */
    PerlLIO_setmode((*mode == 'r'), O_BINARY);
 #endif 
-#ifdef THREADS_HAVE_PIDS
-       PL_ppid = (IV)getppid();
-#endif
        PL_forkprocess = 0;
 #ifdef PERL_USES_PL_PIDSTATUS
        hv_clear(PL_pidstatus); /* we have no children */
@@ -2894,7 +2899,7 @@ Perl_my_popen(pTHX_ const char *cmd, const char *mode)
            int pid2, status;
            PerlLIO_close(p[This]);
            if (n != sizeof(int))
-               Perl_croak(aTHX_ "panic: kid popen errno read");
+               Perl_croak(aTHX_ "panic: kid popen errno read, n=%u", n);
            do {
                pid2 = wait4pid(pid, &status, 0);
            } while (pid2 == -1 && errno == EINTR);
@@ -3404,7 +3409,7 @@ Perl_my_pclose(pTHX_ PerlIO *ptr)
 
 #define PERL_REPEATCPY_LINEAR 4
 void
-Perl_repeatcpy(register char *to, register const char *from, I32 len, register I32 count)
+Perl_repeatcpy(register char *to, register const char *from, I32 len, register IV count)
 {
     PERL_ARGS_ASSERT_REPEATCPY;
 
@@ -3412,19 +3417,19 @@ Perl_repeatcpy(register char *to, register const char *from, I32 len, register I
        memset(to, *from, count);
     else if (count) {
        register char *p = to;
-       I32 items, linear, half;
+       IV items, linear, half;
 
        linear = count < PERL_REPEATCPY_LINEAR ? count : PERL_REPEATCPY_LINEAR;
        for (items = 0; items < linear; ++items) {
            register const char *q = from;
-           I32 todo;
+           IV todo;
            for (todo = len; todo > 0; todo--)
                *p++ = *q++;
         }
 
        half = count / 2;
        while (items <= half) {
-           I32 size = items * len;
+           IV size = items * len;
            memcpy(p, to, size);
            p     += size;
            items *= 2;
@@ -3681,6 +3686,7 @@ Perl_find_script(pTHX_ const char *scriptname, bool dosearch,
            seen_dot = 1;                       /* Disable message. */
        if (!xfound) {
            if (flags & 1) {                    /* do or die? */
+               /* diag_listed_as: Can't execute %s */
                Perl_croak(aTHX_ "Can't %s %s%s%s",
                      (xfailed ? "execute" : "find"),
                      (xfailed ? xfailed : scriptname),
@@ -3704,8 +3710,9 @@ Perl_get_context(void)
 #if defined(USE_ITHREADS)
 #  ifdef OLD_PTHREADS_API
     pthread_addr_t t;
-    if (pthread_getspecific(PL_thr_key, &t))
-       Perl_croak_nocontext("panic: pthread_getspecific");
+    int error = pthread_getspecific(PL_thr_key, &t)
+    if (error)
+       Perl_croak_nocontext("panic: pthread_getspecific, error=%d", error);
     return (void*)t;
 #  else
 #    ifdef I_MACH_CTHREADS
@@ -3728,8 +3735,11 @@ Perl_set_context(void *t)
 #  ifdef I_MACH_CTHREADS
     cthread_set_data(cthread_self(), t);
 #  else
-    if (pthread_setspecific(PL_thr_key, t))
-       Perl_croak_nocontext("panic: pthread_setspecific");
+    {
+       const int error = pthread_setspecific(PL_thr_key, t);
+       if (error)
+           Perl_croak_nocontext("panic: pthread_setspecific, error=%d", error);
+    }
 #  endif
 #else
     PERL_UNUSED_ARG(t);
@@ -3907,26 +3917,18 @@ Perl_report_evil_fh(pTHX_ const GV *gv)
            (const char *)
            (OP_IS_SOCKET(op) || (io && IoTYPE(io) == IoTYPE_SOCKET)
             ? "socket" : "filehandle");
-       if (name && SvPOK(name) && *SvPV_nolen(name)) {
-           Perl_warner(aTHX_ packWARN(warn_type),
-                       "%s%s on %s %s %"SVf, func, pars, vile, type, SVfARG(name));
-           if (io && IoDIRP(io) && !(IoFLAGS(io) & IOf_FAKE_DIRP))
+       const bool have_name = name && SvPOK(name) && *SvPV_nolen(name);
+       Perl_warner(aTHX_ packWARN(warn_type),
+                  "%s%s on %s %s%s%"SVf, func, pars, vile, type,
+                   have_name ? " " : "",
+                   SVfARG(have_name ? name : &PL_sv_no));
+       if (io && IoDIRP(io) && !(IoFLAGS(io) & IOf_FAKE_DIRP))
                Perl_warner(
                            aTHX_ packWARN(warn_type),
-                           "\t(Are you trying to call %s%s on dirhandle %"SVf"?)\n",
-                           func, pars, SVfARG(name)
+                       "\t(Are you trying to call %s%s on dirhandle%s%"SVf"?)\n",
+                       func, pars, have_name ? " " : "",
+                       SVfARG(have_name ? name : &PL_sv_no)
                            );
-       }
-       else {
-           Perl_warner(aTHX_ packWARN(warn_type),
-                       "%s%s on %s %s", func, pars, vile, type);
-           if (io && IoDIRP(io) && !(IoFLAGS(io) & IOf_FAKE_DIRP))
-               Perl_warner(
-                           aTHX_ packWARN(warn_type),
-                           "\t(Are you trying to call %s%s on dirhandle?)\n",
-                           func, pars
-                           );
-       }
     }
 }
 
@@ -4544,7 +4546,7 @@ dotted_decimal_version:
 
        /* and we never support negative versions */
        if ( *d == '-') {
-               BADVERSION(s,errstr,"Invalid version format (negative version number)");                
+           BADVERSION(s,errstr,"Invalid version format (negative version number)");
        }
 
        /* consume all of the integer part */
@@ -4857,7 +4859,8 @@ Perl_new_version(pTHX_ SV *ver)
     dVAR;
     SV * const rv = newSV(0);
     PERL_ARGS_ASSERT_NEW_VERSION;
-    if ( sv_derived_from(ver,"version") ) /* can just copy directly */
+    if ( sv_isobject(ver) && sv_derived_from(ver, "version") )
+        /* can just copy directly */
     {
        I32 key;
        AV * const av = newAV();
@@ -4949,14 +4952,18 @@ Perl_upg_version(pTHX_ SV *ver, bool qv)
 
     if ( SvNOK(ver) && !( SvPOK(ver) && sv_len(ver) == 3 ) )
     {
+       STRLEN len;
+
        /* may get too much accuracy */ 
        char tbuf[64];
 #ifdef USE_LOCALE_NUMERIC
-       char *loc = setlocale(LC_NUMERIC, "C");
+       char *loc = savepv(setlocale(LC_NUMERIC, NULL));
+       setlocale(LC_NUMERIC, "C");
 #endif
-       STRLEN len = my_snprintf(tbuf, sizeof(tbuf), "%.9"NVff, SvNVX(ver));
+       len = my_snprintf(tbuf, sizeof(tbuf), "%.9"NVff, SvNVX(ver));
 #ifdef USE_LOCALE_NUMERIC
        setlocale(LC_NUMERIC, loc);
+       Safefree(loc);
 #endif
        while (tbuf[len-1] == '0' && len > 0) len--;
        if ( tbuf[len-1] == '.' ) len--; /* eat the trailing decimal */
@@ -5837,6 +5844,8 @@ Perl_stashpv_hvname_match(pTHX_ const COP *c, const HV *hv)
     PERL_UNUSED_CONTEXT;
     PERL_ARGS_ASSERT_STASHPV_HVNAME_MATCH;
 
+    if (!stashpv || !name)
+       return stashpv == name;
     if ( HvNAMEUTF8(hv) && !(CopSTASH_flags(c) & SVf_UTF8 ? 1 : 0) ) {
         if (CopSTASH_flags(c) & SVf_UTF8) {
             return (bytes_cmp_utf8(
@@ -5851,6 +5860,7 @@ Perl_stashpv_hvname_match(pTHX_ const COP *c, const HV *hv)
     else
         return (stashpv == name
                     || strEQ(stashpv, name));
+    /*NOTREACHED*/
     return FALSE;
 }
 #endif
@@ -6427,7 +6437,7 @@ Perl_xs_version_bootcheck(pTHX_ U32 items, U32 ax, const char *xs_p,
     }
     if (sv) {
        SV *xssv = Perl_newSVpvn_flags(aTHX_ xs_p, xs_len, SVs_TEMP);
-       SV *pmsv = sv_derived_from(sv, "version")
+       SV *pmsv = sv_isobject(sv) && sv_derived_from(sv, "version")
            ? sv : sv_2mortal(new_version(sv));
        xssv = upg_version(xssv, 0);
        if ( vcmp(pmsv,xssv) ) {
@@ -6521,6 +6531,19 @@ long _ftol( double ); /* Defined by VC6 C libs. */
 long _ftol2( double dblSource ) { return _ftol( dblSource ); }
 #endif
 
+PERL_STATIC_INLINE bool
+S_gv_has_usable_name(pTHX_ GV *gv)
+{
+    GV **gvp;
+    return GvSTASH(gv)
+       && HvENAME(GvSTASH(gv))
+       && (gvp = (GV **)hv_fetch(
+                       GvSTASH(gv), GvNAME(gv),
+                       GvNAMEUTF8(gv) ? -GvNAMELEN(gv) : GvNAMELEN(gv), 0
+          ))
+       && *gvp == gv;
+}
+
 void
 Perl_get_db_sub(pTHX_ SV **svp, CV *cv)
 {
@@ -6528,7 +6551,8 @@ Perl_get_db_sub(pTHX_ SV **svp, CV *cv)
     SV * const dbsv = GvSVn(PL_DBsub);
     const bool save_taint = PL_tainted;
 
-    /* We do not care about using sv to call CV;
+    /* When we are called from pp_goto (svp is null),
+     * we do not care about using dbsv to call CV;
      * it's for informational purposes only.
      */
 
@@ -6539,23 +6563,33 @@ Perl_get_db_sub(pTHX_ SV **svp, CV *cv)
     if (!PERLDB_SUB_NN) {
        GV *gv = CvGV(cv);
 
-       if ( svp && ((CvFLAGS(cv) & (CVf_ANON | CVf_CLONED))
+       if (!svp) {
+           gv_efullname3(dbsv, gv, NULL);
+       }
+       else if ( (CvFLAGS(cv) & (CVf_ANON | CVf_CLONED))
             || strEQ(GvNAME(gv), "END")
-            || ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */
+            || ( /* Could be imported, and old sub redefined. */
+                (GvCV(gv) != cv || !S_gv_has_usable_name(aTHX_ gv))
+                &&
                 !( (SvTYPE(*svp) == SVt_PVGV)
                    && (GvCV((const GV *)*svp) == cv)
-                   && (gv = (GV *)*svp) 
+                   /* Use GV from the stack as a fallback. */
+                   && S_gv_has_usable_name(aTHX_ gv = (GV *)*svp) 
                  )
                )
-       )) {
-           /* Use GV from the stack as a fallback. */
+       ) {
            /* GV is potentially non-unique, or contain different CV. */
            SV * const tmp = newRV(MUTABLE_SV(cv));
            sv_setsv(dbsv, tmp);
            SvREFCNT_dec(tmp);
        }
        else {
-           gv_efullname3(dbsv, gv, NULL);
+           sv_sethek(dbsv, HvENAME_HEK(GvSTASH(gv)));
+           sv_catpvs(dbsv, "::");
+           sv_catpvn_flags(
+             dbsv, GvNAME(gv), GvNAMELEN(gv),
+             GvNAMEUTF8(gv) ? SV_CATUTF8 : SV_CATBYTES
+           );
        }
     }
     else {