X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/5c35adbb8fc4c988807097c4d379e2485ada5865..6b913759a0729c294b9370f21f563e385be726f2:/util.c diff --git a/util.c b/util.c index fef0393..ea84cda 100644 --- a/util.c +++ b/util.c @@ -1,7 +1,7 @@ /* util.c * - * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, by Larry Wall and others + * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + * 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -9,8 +9,10 @@ */ /* - * "Very useful, no doubt, that was to Saruman; yet it seems that he was - * not content." --Gandalf + * 'Very useful, no doubt, that was to Saruman; yet it seems that he was + * not content.' --Gandalf to Pippin + * + * [p.598 of _The Lord of the Rings_, III/xi: "The Palantír"] */ /* This file contains assorted utility routines. @@ -178,11 +180,11 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size) ptr = (Malloc_t)PerlMem_realloc(where,size); PERL_ALLOC_CHECK(ptr); - DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) rfree\n",PTR2UV(where),(long)PL_an++)); - DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) realloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size)); - - if (ptr != NULL) { + /* MUST do this fixup first, before doing ANYTHING else, as anything else + might allocate memory/free/move memory, and until we do the fixup, it + may well be chasing (and writing to) free memory. */ #ifdef PERL_TRACK_MEMPOOL + if (ptr != NULL) { struct perl_memory_debug_header *const header = (struct perl_memory_debug_header *)ptr; @@ -198,7 +200,17 @@ Perl_safesysrealloc(Malloc_t where,MEM_SIZE size) header->prev->next = header; ptr = (Malloc_t)((char*)ptr+sTHX); + } #endif + + /* In particular, must do that fixup above before logging anything via + *printf(), as it can reallocate memory, which can cause SEGVs. */ + + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) rfree\n",PTR2UV(where),(long)PL_an++)); + DEBUG_m(PerlIO_printf(Perl_debug_log, "0x%"UVxf": (%05ld) realloc %ld bytes\n",PTR2UV(ptr),(long)PL_an++,(long)size)); + + + if (ptr != NULL) { return ptr; } else if (PL_nomemok) @@ -264,12 +276,12 @@ Perl_safesyscalloc(MEM_SIZE count, MEM_SIZE size) if (size && (count <= MEM_SIZE_MAX / size)) total_size = size * count; else - Perl_croak_nocontext(PL_memory_wrap); + Perl_croak_nocontext("%s", PL_memory_wrap); #ifdef PERL_TRACK_MEMPOOL if (sTHX <= MEM_SIZE_MAX - (MEM_SIZE)total_size) total_size += sTHX; else - Perl_croak_nocontext(PL_memory_wrap); + Perl_croak_nocontext("%s", PL_memory_wrap); #endif #ifdef HAS_64K_LIMIT if (total_size > 0xffff) { @@ -362,6 +374,8 @@ Perl_delimcpy(pTHX_ register char *to, register const char *toend, register cons register I32 tolen; PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_DELIMCPY; + for (tolen = 0; from < fromend; from++, tolen++) { if (*from == '\\') { if (from[1] != delim) { @@ -391,6 +405,8 @@ Perl_instr(pTHX_ register const char *big, register const char *little) register I32 first; PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_INSTR; + if (!little) return (char*)big; first = *little++; @@ -421,13 +437,14 @@ Perl_instr(pTHX_ register const char *big, register const char *little) char * Perl_ninstr(pTHX_ const char *big, const char *bigend, const char *little, const char *lend) { + PERL_ARGS_ASSERT_NINSTR; PERL_UNUSED_CONTEXT; if (little >= lend) return (char*)big; { - char first = *little++; + const char first = *little; const char *s, *x; - bigend -= lend - little; + bigend -= lend - little++; OUTER: while (big <= bigend) { if (*big++ == first) { @@ -452,6 +469,8 @@ Perl_rninstr(pTHX_ register const char *big, const char *bigend, const char *lit register const char * const littleend = lend; PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_RNINSTR; + if (little >= littleend) return (char*)bigend; bigbeg = big; @@ -501,6 +520,8 @@ Perl_fbm_compile(pTHX_ SV *sv, U32 flags) U32 rarest = 0; U32 frequency = 256; + PERL_ARGS_ASSERT_FBM_COMPILE; + if (flags & FBMcf_TAIL) { MAGIC * const mg = SvUTF8(sv) && SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_utf8) : NULL; sv_catpvs(sv, "\n"); /* Taken into account in fbm_instr() */ @@ -578,6 +599,8 @@ Perl_fbm_instr(pTHX_ unsigned char *big, register unsigned char *bigend, SV *lit register STRLEN littlelen = l; register const I32 multiline = flags & FBMrf_MULTILINE; + PERL_ARGS_ASSERT_FBM_INSTR; + if ((STRLEN)(bigend - big) < littlelen) { if ( SvTAIL(littlestr) && ((STRLEN)(bigend - big) == littlelen - 1) @@ -781,6 +804,8 @@ Perl_screaminstr(pTHX_ SV *bigstr, SV *littlestr, I32 start_shift, I32 end_shift register const unsigned char *littleend; I32 found = 0; + PERL_ARGS_ASSERT_SCREAMINSTR; + assert(SvTYPE(littlestr) == SVt_PVGV); assert(SvVALID(littlestr)); @@ -864,6 +889,8 @@ Perl_ibcmp(pTHX_ const char *s1, const char *s2, register I32 len) register const U8 *b = (const U8 *)s2; PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_IBCMP; + while (len--) { if (*a != *b && *a != PL_fold[*b]) return 1; @@ -880,6 +907,8 @@ Perl_ibcmp_locale(pTHX_ const char *s1, const char *s2, register I32 len) register const U8 *b = (const U8 *)s2; PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_IBCMP_LOCALE; + while (len--) { if (*a != *b && *a != PL_fold_locale[*b]) return 1; @@ -985,7 +1014,9 @@ char * Perl_savesharedpvn(pTHX_ const char *const pv, const STRLEN len) { char *const newaddr = (char*)PerlMemShared_malloc(len + 1); - assert(pv); + + PERL_ARGS_ASSERT_SAVESHAREDPVN; + if (!newaddr) { return write_no_mem(); } @@ -1009,6 +1040,8 @@ Perl_savesvpv(pTHX_ SV *sv) const char * const pv = SvPV_const(sv, len); register char *newaddr; + PERL_ARGS_ASSERT_SAVESVPV; + ++len; Newx(newaddr,len,char); return (char *) CopyD(pv,newaddr,len,char); @@ -1025,7 +1058,7 @@ S_mess_alloc(pTHX) XPVMG *any; if (!PL_dirty) - return sv_2mortal(newSVpvs("")); + return newSVpvs_flags("", SVs_TEMP); if (PL_mess_sv) return PL_mess_sv; @@ -1048,6 +1081,7 @@ Perl_form_nocontext(const char* pat, ...) dTHX; char *retval; va_list args; + PERL_ARGS_ASSERT_FORM_NOCONTEXT; va_start(args, pat); retval = vform(pat, &args); va_end(args); @@ -1080,6 +1114,7 @@ Perl_form(pTHX_ const char* pat, ...) { char *retval; va_list args; + PERL_ARGS_ASSERT_FORM; va_start(args, pat); retval = vform(pat, &args); va_end(args); @@ -1090,6 +1125,7 @@ char * Perl_vform(pTHX_ const char *pat, va_list *args) { SV * const sv = mess_alloc(); + PERL_ARGS_ASSERT_VFORM; sv_vsetpvfn(sv, pat, strlen(pat), args, NULL, 0, NULL); return SvPVX(sv); } @@ -1101,6 +1137,7 @@ Perl_mess_nocontext(const char *pat, ...) dTHX; SV *retval; va_list args; + PERL_ARGS_ASSERT_MESS_NOCONTEXT; va_start(args, pat); retval = vmess(pat, &args); va_end(args); @@ -1113,6 +1150,7 @@ Perl_mess(pTHX_ const char *pat, ...) { SV *retval; va_list args; + PERL_ARGS_ASSERT_MESS; va_start(args, pat); retval = vmess(pat, &args); va_end(args); @@ -1125,6 +1163,8 @@ S_closest_cop(pTHX_ const COP *cop, const OP *o) dVAR; /* Look for PL_op starting from o. cop is the last COP we've seen. */ + PERL_ARGS_ASSERT_CLOSEST_COP; + if (!o || o == PL_op) return cop; @@ -1158,6 +1198,8 @@ Perl_vmess(pTHX_ const char *pat, va_list *args) dVAR; SV * const sv = mess_alloc(); + PERL_ARGS_ASSERT_VMESS; + sv_vsetpvfn(sv, pat, strlen(pat), args, NULL, 0, NULL); if (!SvCUR(sv) || *(SvEND(sv) - 1) != '\n') { /* @@ -1199,9 +1241,11 @@ Perl_write_to_stderr(pTHX_ const char* message, int msglen) IO *io; MAGIC *mg; + PERL_ARGS_ASSERT_WRITE_TO_STDERR; + if (PL_stderrgv && SvREFCNT(PL_stderrgv) && (io = GvIO(PL_stderrgv)) - && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar))) + && (mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar))) { dSP; ENTER; @@ -1215,8 +1259,8 @@ Perl_write_to_stderr(pTHX_ const char* message, int msglen) PUSHMARK(SP); EXTEND(SP,2); - PUSHs(SvTIED_obj((SV*)io, mg)); - PUSHs(sv_2mortal(newSVpvn(message, msglen))); + PUSHs(SvTIED_obj(MUTABLE_SV(io), mg)); + mPUSHp(message, msglen); PUTBACK; call_method("PRINT", G_SCALAR); @@ -1227,14 +1271,14 @@ Perl_write_to_stderr(pTHX_ const char* message, int msglen) else { #ifdef USE_SFIO /* SFIO can really mess with your errno */ - const int e = errno; + dSAVED_ERRNO; #endif PerlIO * const serr = Perl_error_log; PERL_WRITE_MSG_TO_CONSOLE(serr, message, msglen); (void)PerlIO_flush(serr); #ifdef USE_SFIO - errno = e; + RESTORE_ERRNO; #endif } } @@ -1270,8 +1314,7 @@ S_vdie_common(pTHX_ const char *message, STRLEN msglen, I32 utf8, bool warn) *hook = NULL; } if (warn || message) { - msg = newSVpvn(message, msglen); - SvFLAGS(msg) |= utf8; + msg = newSVpvn_flags(message, msglen, utf8); SvREADONLY_on(msg); SAVEFREESV(msg); } @@ -1283,7 +1326,7 @@ S_vdie_common(pTHX_ const char *message, STRLEN msglen, I32 utf8, bool warn) PUSHMARK(SP); XPUSHs(msg); PUTBACK; - call_sv((SV*)cv, G_DISCARD); + call_sv(MUTABLE_SV(cv), G_DISCARD); POPSTACK; LEAVE; return TRUE; @@ -1313,17 +1356,14 @@ S_vdie_croak_common(pTHX_ const char* pat, va_list* args, STRLEN* msglen, message = NULL; } - DEBUG_S(PerlIO_printf(Perl_debug_log, - "%p: die/croak: message = %s\ndiehook = %p\n", - (void*)thr, message, (void*)PL_diehook)); if (PL_diehook) { S_vdie_common(aTHX_ message, *msglen, *utf8, FALSE); } return message; } -OP * -Perl_vdie(pTHX_ const char* pat, va_list *args) +static OP * +S_vdie(pTHX_ const char* pat, va_list *args) { dVAR; const char *message; @@ -1331,17 +1371,10 @@ Perl_vdie(pTHX_ const char* pat, va_list *args) STRLEN msglen; I32 utf8 = 0; - DEBUG_S(PerlIO_printf(Perl_debug_log, - "%p: die: curstack = %p, mainstack = %p\n", - (void*)thr, (void*)PL_curstack, (void*)PL_mainstack)); - message = vdie_croak_common(pat, args, &msglen, &utf8); PL_restartop = die_where(message, msglen); SvFLAGS(ERRSV) |= utf8; - DEBUG_S(PerlIO_printf(Perl_debug_log, - "%p: die: restartop = %p, was_in_eval = %d, top_env = %p\n", - (void*)thr, (void*)PL_restartop, was_in_eval, (void*)PL_top_env)); if ((!PL_restartop && was_in_eval) || PL_top_env->je_prev) JMPENV_JUMP(3); return PL_restartop; @@ -1354,6 +1387,7 @@ Perl_die_nocontext(const char* pat, ...) dTHX; OP *o; va_list args; + PERL_ARGS_ASSERT_DIE_NOCONTEXT; va_start(args, pat); o = vdie(pat, &args); va_end(args); @@ -1420,7 +1454,7 @@ sidestepping the normal C order of execution. See C. If you want to throw an exception object, assign the object to C<$@> and then pass C to croak(): - errsv = get_sv("@", TRUE); + errsv = get_sv("@", GV_ADD); sv_setsv(errsv, exception_object); croak(NULL); @@ -1446,6 +1480,8 @@ Perl_vwarn(pTHX_ const char* pat, va_list *args) const I32 utf8 = SvUTF8(msv); const char * const message = SvPV_const(msv, msglen); + PERL_ARGS_ASSERT_VWARN; + if (PL_warnhook) { if (vdie_common(message, msglen, utf8, TRUE)) return; @@ -1460,6 +1496,7 @@ Perl_warn_nocontext(const char *pat, ...) { dTHX; va_list args; + PERL_ARGS_ASSERT_WARN_NOCONTEXT; va_start(args, pat); vwarn(pat, &args); va_end(args); @@ -1479,6 +1516,7 @@ void Perl_warn(pTHX_ const char *pat, ...) { va_list args; + PERL_ARGS_ASSERT_WARN; va_start(args, pat); vwarn(pat, &args); va_end(args); @@ -1490,6 +1528,7 @@ Perl_warner_nocontext(U32 err, const char *pat, ...) { dTHX; va_list args; + PERL_ARGS_ASSERT_WARNER_NOCONTEXT; va_start(args, pat); vwarner(err, pat, &args); va_end(args); @@ -1500,6 +1539,7 @@ void Perl_warner(pTHX_ U32 err, const char* pat,...) { va_list args; + PERL_ARGS_ASSERT_WARNER; va_start(args, pat); vwarner(err, pat, &args); va_end(args); @@ -1509,6 +1549,7 @@ void Perl_vwarner(pTHX_ U32 err, const char* pat, va_list* args) { dVAR; + PERL_ARGS_ASSERT_VWARNER; if (PL_warnhook == PERL_WARNHOOK_FATAL || ckDEAD(err)) { SV * const msv = vmess(pat, args); STRLEN msglen; @@ -1590,6 +1631,7 @@ Perl_new_warnings_bitfield(pTHX_ STRLEN *buffer, const char *const bits, STRLEN size) { const MEM_SIZE len_wanted = sizeof(STRLEN) + size; PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_NEW_WARNINGS_BITFIELD; buffer = (STRLEN*) (specialWARN(buffer) ? @@ -1625,9 +1667,16 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val) #ifndef PERL_USE_SAFE_PUTENV if (!PL_use_safe_putenv) { /* most putenv()s leak, so we manipulate environ directly */ - register I32 i=setenv_getix(nam); /* where does it go? */ + register I32 i; + register const I32 len = strlen(nam); int nlen, vlen; + /* where does it go? */ + for (i = 0; environ[i]; i++) { + if (strnEQ(environ[i],nam,len) && environ[i][len] == '=') + break; + } + if (environ == PL_origenviron) { /* need we copy environment? */ I32 j; I32 max; @@ -1731,28 +1780,6 @@ Perl_my_setenv(pTHX_ const char *nam, const char *val) #endif /* WIN32 || NETWARE */ -#ifndef PERL_MICRO -I32 -Perl_setenv_getix(pTHX_ const char *nam) -{ - register I32 i; - register const I32 len = strlen(nam); - PERL_UNUSED_CONTEXT; - - for (i = 0; environ[i]; i++) { - if ( -#ifdef WIN32 - strnicmp(environ[i],nam,len) == 0 -#else - strnEQ(environ[i],nam,len) -#endif - && environ[i][len] == '=') - break; /* strnEQ must come first to avoid */ - } /* potential SEGV's */ - return i; -} -#endif /* !PERL_MICRO */ - #endif /* !VMS && !EPOC*/ #ifdef UNLINK_ALL_VERSIONS @@ -1761,6 +1788,8 @@ Perl_unlnk(pTHX_ const char *f) /* unlink all versions of a file */ { I32 retries = 0; + PERL_ARGS_ASSERT_UNLNK; + while (PerlLIO_unlink(f) >= 0) retries++; return retries ? 0 : -1; @@ -1774,6 +1803,8 @@ Perl_my_bcopy(register const char *from,register char *to,register I32 len) { char * const retval = to; + PERL_ARGS_ASSERT_MY_BCOPY; + if (from - to >= 0) { while (len--) *to++ = *from++; @@ -1795,6 +1826,8 @@ Perl_my_memset(register char *loc, register I32 ch, register I32 len) { char * const retval = loc; + PERL_ARGS_ASSERT_MY_MEMSET; + while (len--) *loc++ = ch; return retval; @@ -1808,6 +1841,8 @@ Perl_my_bzero(register char *loc, register I32 len) { char * const retval = loc; + PERL_ARGS_ASSERT_MY_BZERO; + while (len--) *loc++ = 0; return retval; @@ -1823,6 +1858,8 @@ Perl_my_memcmp(const char *s1, const char *s2, register I32 len) register const U8 *b = (const U8 *)s2; register I32 tmp; + PERL_ARGS_ASSERT_MY_MEMCMP; + while (len--) { if ((tmp = *a++ - *b++)) return tmp; @@ -2206,6 +2243,8 @@ Perl_my_swabn(void *ptr, int n) register char *e = s + (n-1); register char tc; + PERL_ARGS_ASSERT_MY_SWABN; + for (n /= 2; n > 0; s++, e--, n--) { tc = *s; *s = *e; @@ -2214,7 +2253,7 @@ Perl_my_swabn(void *ptr, int n) } PerlIO * -Perl_my_popen_list(pTHX_ char *mode, int n, SV **args) +Perl_my_popen_list(pTHX_ const char *mode, int n, SV **args) { #if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(OS2) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL) && !defined(NETWARE) && !defined(__LIBCATAMOUNT__) dVAR; @@ -2225,6 +2264,8 @@ Perl_my_popen_list(pTHX_ char *mode, int n, SV **args) I32 did_pipes = 0; int pp[2]; + PERL_ARGS_ASSERT_MY_POPEN_LIST; + PERL_FLUSHALL_FOR_CHILD; This = (*mode == 'w'); that = !This; @@ -2247,6 +2288,8 @@ Perl_my_popen_list(pTHX_ char *mode, int n, SV **args) } return NULL; } + if (ckWARN(WARN_PIPE)) + Perl_warner(aTHX_ packWARN(WARN_PIPE), "Can't fork, trying again in 5 seconds"); sleep(5); } if (pid == 0) { @@ -2365,6 +2408,8 @@ Perl_my_popen(pTHX_ const char *cmd, const char *mode) I32 did_pipes = 0; int pp[2]; + PERL_ARGS_ASSERT_MY_POPEN; + PERL_FLUSHALL_FOR_CHILD; #ifdef OS2 if (doexec) { @@ -2390,9 +2435,11 @@ Perl_my_popen(pTHX_ const char *cmd, const char *mode) PerlLIO_close(pp[1]); } if (!doexec) - Perl_croak(aTHX_ "Can't fork"); + Perl_croak(aTHX_ "Can't fork: %s", Strerror(errno)); return NULL; } + if (ckWARN(WARN_PIPE)) + Perl_warner(aTHX_ packWARN(WARN_PIPE), "Can't fork, trying again in 5 seconds"); sleep(5); } if (pid == 0) { @@ -2513,6 +2560,7 @@ FILE *popen(); PerlIO * Perl_my_popen(pTHX_ const char *cmd, const char *mode) { + PERL_ARGS_ASSERT_MY_POPEN; PERL_FLUSHALL_FOR_CHILD; /* Call system's popen() to get a FILE *, then import it. used 0 for 2nd parameter to PerlIO_importFILE; @@ -2598,11 +2646,13 @@ Perl_my_fork(void) #ifdef DUMP_FDS void -Perl_dump_fds(pTHX_ char *s) +Perl_dump_fds(pTHX_ const char *const s) { int fd; Stat_t tmpstatbuf; + PERL_ARGS_ASSERT_DUMP_FDS; + PerlIO_printf(Perl_debug_log,"%s", s); for (fd = 0; fd < 32; fd++) { if (PerlLIO_fstat(fd,&tmpstatbuf) >= 0) @@ -2702,6 +2752,8 @@ Perl_rsignal_save(pTHX_ int signo, Sighandler_t handler, Sigsave_t *save) dVAR; struct sigaction act; + PERL_ARGS_ASSERT_RSIGNAL_SAVE; + #ifdef USE_ITHREADS /* only "parent" interpreter can diddle signals */ if (PL_curinterp != aTHX) @@ -2814,10 +2866,7 @@ Perl_my_pclose(pTHX_ PerlIO *ptr) Pid_t pid; Pid_t pid2; bool close_failed; - int saved_errno = 0; -#ifdef WIN32 - int saved_win32_errno; -#endif + dSAVEDERRNO; LOCK_FDPID_MUTEX; svp = av_fetch(PL_fdpid,PerlIO_fileno(ptr),TRUE); @@ -2830,12 +2879,8 @@ Perl_my_pclose(pTHX_ PerlIO *ptr) return my_syspclose(ptr); } #endif - if ((close_failed = (PerlIO_close(ptr) == EOF))) { - saved_errno = errno; -#ifdef WIN32 - saved_win32_errno = GetLastError(); -#endif - } + close_failed = (PerlIO_close(ptr) == EOF); + SAVE_ERRNO; #ifdef UTS if(PerlProc_kill(pid, 0) < 0) { return(pid); } /* HOM 12/23/91 */ #endif @@ -2853,7 +2898,7 @@ Perl_my_pclose(pTHX_ PerlIO *ptr) rsignal_restore(SIGQUIT, &qstat); #endif if (close_failed) { - SETERRNO(saved_errno, 0); + RESTORE_ERRNO; return -1; } return(pid2 < 0 ? pid2 : status == 0 ? 0 : (errno = 0, status)); @@ -2874,6 +2919,7 @@ Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags) { dVAR; I32 result = 0; + PERL_ARGS_ASSERT_WAIT4PID; if (!pid) return -1; #ifdef PERL_USES_PL_PIDSTATUS @@ -2946,6 +2992,7 @@ Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags) #endif if (result < 0 && errno == EINTR) { PERL_ASYNC_CHECK(); + errno = EINTR; /* reset in case a signal handler changed $! */ } return result; } @@ -2953,7 +3000,7 @@ Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags) #ifdef PERL_USES_PL_PIDSTATUS void -Perl_pidgone(pTHX_ Pid_t pid, int status) +S_pidgone(pTHX_ Pid_t pid, int status) { register SV *sv; @@ -3004,6 +3051,8 @@ Perl_repeatcpy(pTHX_ register char *to, register const char *from, I32 len, regi register const char * const frombase = from; PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_REPEATCPY; + if (len == 1) { register const char c = *from; while (count-- > 0) @@ -3028,6 +3077,8 @@ Perl_same_dirent(pTHX_ const char *a, const char *b) Stat_t tmpstatbuf2; SV * const tmpsv = sv_newmortal(); + PERL_ARGS_ASSERT_SAME_DIRENT; + if (fa) fa++; else @@ -3039,13 +3090,13 @@ Perl_same_dirent(pTHX_ const char *a, const char *b) if (strNE(a,b)) return FALSE; if (fa == a) - sv_setpvn(tmpsv, ".", 1); + sv_setpvs(tmpsv, "."); else sv_setpvn(tmpsv, a, fa - a); if (PerlLIO_stat(SvPVX_const(tmpsv), &tmpstatbuf1) < 0) return FALSE; if (fb == b) - sv_setpvn(tmpsv, ".", 1); + sv_setpvs(tmpsv, "."); else sv_setpvn(tmpsv, b, fb - b); if (PerlLIO_stat(SvPVX_const(tmpsv), &tmpstatbuf2) < 0) @@ -3090,6 +3141,8 @@ Perl_find_script(pTHX_ const char *scriptname, bool dosearch, # define MAX_EXT_LEN 0 #endif + PERL_ARGS_ASSERT_FIND_SCRIPT; + /* * If dosearch is true and if scriptname does not contain path * delimiters, search the PATH for scriptname. @@ -3318,6 +3371,7 @@ void Perl_set_context(void *t) { dVAR; + PERL_ARGS_ASSERT_SET_CONTEXT; #if defined(USE_ITHREADS) # ifdef I_MACH_CTHREADS cthread_set_data(cthread_self(), t); @@ -3382,6 +3436,7 @@ Perl_getenv_len(pTHX_ const char *env_elem, unsigned long *len) { char * const env_trans = PerlEnv_getenv(env_elem); PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_GETENV_LEN; if (env_trans) *len = strlen(env_trans); return env_trans; @@ -3679,11 +3734,13 @@ Perl_init_tm(pTHX_ struct tm *ptm) /* see mktime, strftime and asctime */ #ifdef HAS_TM_TM_ZONE Time_t now; const struct tm* my_tm; + PERL_ARGS_ASSERT_INIT_TM; (void)time(&now); my_tm = localtime(&now); if (my_tm) Copy(my_tm, ptm, 1, struct tm); #else + PERL_ARGS_ASSERT_INIT_TM; PERL_UNUSED_ARG(ptm); #endif } @@ -3701,6 +3758,8 @@ Perl_mini_mktime(pTHX_ struct tm *ptm) int odd_cent, odd_year; PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_MINI_MKTIME; + #define DAYS_PER_YEAR 365 #define DAYS_PER_QYEAR (4*DAYS_PER_YEAR+1) #define DAYS_PER_CENT (25*DAYS_PER_QYEAR-1) @@ -3895,6 +3954,8 @@ Perl_my_strftime(pTHX_ const char *fmt, int sec, int min, int hour, int mday, in struct tm mytm; int len; + PERL_ARGS_ASSERT_MY_STRFTIME; + init_tm(&mytm); /* XXX workaround - see init_tm() above */ mytm.tm_sec = sec; mytm.tm_min = min; @@ -4002,6 +4063,8 @@ Perl_getcwd_sv(pTHX_ register SV *sv) SvTAINTED_on(sv); #endif + PERL_ARGS_ASSERT_GETCWD_SV; + #ifdef HAS_GETCWD { char buf[MAXPATHLEN]; @@ -4174,6 +4237,9 @@ Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv) bool vinf = FALSE; AV * const av = newAV(); SV * const hv = newSVrv(rv, "version"); /* create an SV and upgrade the RV */ + + PERL_ARGS_ASSERT_SCAN_VERSION; + (void)sv_upgrade(hv, SVt_PVHV); /* needs to be an HV type */ while (isSPACE(*s)) /* leading whitespace is OK */ @@ -4221,11 +4287,11 @@ Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv) pos = s; if ( qv ) - (void)hv_stores((HV *)hv, "qv", newSViv(qv)); + (void)hv_stores(MUTABLE_HV(hv), "qv", newSViv(qv)); if ( alpha ) - (void)hv_stores((HV *)hv, "alpha", newSViv(alpha)); + (void)hv_stores(MUTABLE_HV(hv), "alpha", newSViv(alpha)); if ( !qv && width < 3 ) - (void)hv_stores((HV *)hv, "width", newSViv(width)); + (void)hv_stores(MUTABLE_HV(hv), "width", newSViv(width)); while (isDIGIT(*pos)) pos++; @@ -4319,7 +4385,7 @@ Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv) Compiler in question is: gcc version 3.3 20030304 (Apple Computer, Inc. build 1640) for ( len = 2 - len; len > 0; len-- ) - av_push((AV *)sv, newSViv(0)); + av_push(MUTABLE_AV(sv), newSViv(0)); */ len = 2 - len; while (len-- > 0) @@ -4329,8 +4395,8 @@ Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv) /* need to save off the current version string for later */ if ( vinf ) { SV * orig = newSVpvn("v.Inf", sizeof("v.Inf")-1); - (void)hv_stores((HV *)hv, "original", orig); - (void)hv_stores((HV *)hv, "vinf", newSViv(1)); + (void)hv_stores(MUTABLE_HV(hv), "original", orig); + (void)hv_stores(MUTABLE_HV(hv), "vinf", newSViv(1)); } else if ( s > start ) { SV * orig = newSVpvn(start,s-start); @@ -4338,15 +4404,15 @@ Perl_scan_version(pTHX_ const char *s, SV *rv, bool qv) /* need to insert a v to be consistent */ sv_insert(orig, 0, 0, "v", 1); } - (void)hv_stores((HV *)hv, "original", orig); + (void)hv_stores(MUTABLE_HV(hv), "original", orig); } else { - (void)hv_stores((HV *)hv, "original", newSVpvn("0",1)); + (void)hv_stores(MUTABLE_HV(hv), "original", newSVpvs("0")); av_push(av, newSViv(0)); } /* And finally, store the AV in the hash */ - (void)hv_stores((HV *)hv, "version", newRV_noinc((SV *)av)); + (void)hv_stores(MUTABLE_HV(hv), "version", newRV_noinc(MUTABLE_SV(av))); /* fix RT#19517 - special case 'undef' as string */ if ( *s == 'u' && strEQ(s,"undef") ) { @@ -4374,6 +4440,7 @@ 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 */ { I32 key; @@ -4387,25 +4454,25 @@ Perl_new_version(pTHX_ SV *ver) ver = SvRV(ver); /* Begin copying all of the elements */ - if ( hv_exists((HV *)ver, "qv", 2) ) - (void)hv_stores((HV *)hv, "qv", newSViv(1)); + if ( hv_exists(MUTABLE_HV(ver), "qv", 2) ) + (void)hv_stores(MUTABLE_HV(hv), "qv", newSViv(1)); - if ( hv_exists((HV *)ver, "alpha", 5) ) - (void)hv_stores((HV *)hv, "alpha", newSViv(1)); + if ( hv_exists(MUTABLE_HV(ver), "alpha", 5) ) + (void)hv_stores(MUTABLE_HV(hv), "alpha", newSViv(1)); - if ( hv_exists((HV*)ver, "width", 5 ) ) + if ( hv_exists(MUTABLE_HV(ver), "width", 5 ) ) { - const I32 width = SvIV(*hv_fetchs((HV*)ver, "width", FALSE)); - (void)hv_stores((HV *)hv, "width", newSViv(width)); + const I32 width = SvIV(*hv_fetchs(MUTABLE_HV(ver), "width", FALSE)); + (void)hv_stores(MUTABLE_HV(hv), "width", newSViv(width)); } - if ( hv_exists((HV*)ver, "original", 8 ) ) + if ( hv_exists(MUTABLE_HV(ver), "original", 8 ) ) { - SV * pv = *hv_fetchs((HV*)ver, "original", FALSE); - (void)hv_stores((HV *)hv, "original", newSVsv(pv)); + SV * pv = *hv_fetchs(MUTABLE_HV(ver), "original", FALSE); + (void)hv_stores(MUTABLE_HV(hv), "original", newSVsv(pv)); } - sav = (AV *)SvRV(*hv_fetchs((HV*)ver, "version", FALSE)); + sav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(ver), "version", FALSE))); /* This will get reblessed later if a derived class*/ for ( key = 0; key <= av_len(sav); key++ ) { @@ -4413,7 +4480,7 @@ Perl_new_version(pTHX_ SV *ver) av_push(av, newSViv(rev)); } - (void)hv_stores((HV *)hv, "version", newRV_noinc((SV *)av)); + (void)hv_stores(MUTABLE_HV(hv), "version", newRV_noinc(MUTABLE_SV(av))); return rv; } #ifdef SvVOK @@ -4459,6 +4526,8 @@ Perl_upg_version(pTHX_ SV *ver, bool qv) const MAGIC *mg; #endif + PERL_ARGS_ASSERT_UPG_VERSION; + if ( SvNOK(ver) && !( SvPOK(ver) && sv_len(ver) == 3 ) ) { /* may get too much accuracy */ @@ -4551,13 +4620,16 @@ bool Perl_vverify(pTHX_ SV *vs) { SV *sv; + + PERL_ARGS_ASSERT_VVERIFY; + if ( SvROK(vs) ) vs = SvRV(vs); /* see if the appropriate elements exist */ if ( SvTYPE(vs) == SVt_PVHV - && hv_exists((HV*)vs, "version", 7) - && (sv = SvRV(*hv_fetchs((HV*)vs, "version", FALSE))) + && hv_exists(MUTABLE_HV(vs), "version", 7) + && (sv = SvRV(*hv_fetchs(MUTABLE_HV(vs), "version", FALSE))) && SvTYPE(sv) == SVt_PVAV ) return TRUE; else @@ -4586,6 +4658,9 @@ Perl_vnumify(pTHX_ SV *vs) bool alpha = FALSE; SV * const sv = newSV(0); AV *av; + + PERL_ARGS_ASSERT_VNUMIFY; + if ( SvROK(vs) ) vs = SvRV(vs); @@ -4593,16 +4668,16 @@ Perl_vnumify(pTHX_ SV *vs) Perl_croak(aTHX_ "Invalid version object"); /* see if various flags exist */ - if ( hv_exists((HV*)vs, "alpha", 5 ) ) + if ( hv_exists(MUTABLE_HV(vs), "alpha", 5 ) ) alpha = TRUE; - if ( hv_exists((HV*)vs, "width", 5 ) ) - width = SvIV(*hv_fetchs((HV*)vs, "width", FALSE)); + if ( hv_exists(MUTABLE_HV(vs), "width", 5 ) ) + width = SvIV(*hv_fetchs(MUTABLE_HV(vs), "width", FALSE)); else width = 3; /* attempt to retrieve the version array */ - if ( !(av = (AV *)SvRV(*hv_fetchs((HV*)vs, "version", FALSE)) ) ) { + if ( !(av = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(vs), "version", FALSE))) ) ) { sv_catpvs(sv,"0"); return sv; } @@ -4664,15 +4739,18 @@ Perl_vnormal(pTHX_ SV *vs) bool alpha = FALSE; SV * const sv = newSV(0); AV *av; + + PERL_ARGS_ASSERT_VNORMAL; + if ( SvROK(vs) ) vs = SvRV(vs); if ( !vverify(vs) ) Perl_croak(aTHX_ "Invalid version object"); - if ( hv_exists((HV*)vs, "alpha", 5 ) ) + if ( hv_exists(MUTABLE_HV(vs), "alpha", 5 ) ) alpha = TRUE; - av = (AV *)SvRV(*hv_fetchs((HV*)vs, "version", FALSE)); + av = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(vs), "version", FALSE))); len = av_len(av); if ( len == -1 ) @@ -4718,18 +4796,28 @@ the original version contained 1 or more dots, respectively SV * Perl_vstringify(pTHX_ SV *vs) { - SV *pv; + PERL_ARGS_ASSERT_VSTRINGIFY; + if ( SvROK(vs) ) vs = SvRV(vs); - + if ( !vverify(vs) ) Perl_croak(aTHX_ "Invalid version object"); - pv = *hv_fetchs((HV*)vs, "original", FALSE); - if ( SvPOK(pv) ) - return newSVsv(pv); - else - return &PL_sv_undef; + if (hv_exists(MUTABLE_HV(vs), "original", sizeof("original") - 1)) { + SV *pv; + pv = *hv_fetchs(MUTABLE_HV(vs), "original", FALSE); + if ( SvPOK(pv) ) + return newSVsv(pv); + else + return &PL_sv_undef; + } + else { + if ( hv_exists(MUTABLE_HV(vs), "qv", 2) ) + return vnormal(vs); + else + return vnumify(vs); + } } /* @@ -4750,6 +4838,9 @@ Perl_vcmp(pTHX_ SV *lhv, SV *rhv) I32 left = 0; I32 right = 0; AV *lav, *rav; + + PERL_ARGS_ASSERT_VCMP; + if ( SvROK(lhv) ) lhv = SvRV(lhv); if ( SvROK(rhv) ) @@ -4762,13 +4853,13 @@ Perl_vcmp(pTHX_ SV *lhv, SV *rhv) Perl_croak(aTHX_ "Invalid version object"); /* get the left hand term */ - lav = (AV *)SvRV(*hv_fetchs((HV*)lhv, "version", FALSE)); - if ( hv_exists((HV*)lhv, "alpha", 5 ) ) + lav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(lhv), "version", FALSE))); + if ( hv_exists(MUTABLE_HV(lhv), "alpha", 5 ) ) lalpha = TRUE; /* and the right hand term */ - rav = (AV *)SvRV(*hv_fetchs((HV*)rhv, "version", FALSE)); - if ( hv_exists((HV*)rhv, "alpha", 5 ) ) + rav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(rhv), "version", FALSE))); + if ( hv_exists(MUTABLE_HV(rhv), "alpha", 5 ) ) ralpha = TRUE; l = av_len(lav); @@ -4958,12 +5049,12 @@ S_socketpair_udp (int fd[2]) { errno = ECONNABORTED; tidy_up_and_fail: { - const int save_errno = errno; + dSAVE_ERRNO; if (sockets[0] != -1) PerlLIO_close(sockets[0]); if (sockets[1] != -1) PerlLIO_close(sockets[1]); - errno = save_errno; + RESTORE_ERRNO; return -1; } } @@ -5062,14 +5153,14 @@ Perl_my_socketpair (int family, int type, int protocol, int fd[2]) { #endif tidy_up_and_fail: { - const int save_errno = errno; + dSAVE_ERRNO; if (listener != -1) PerlLIO_close(listener); if (connector != -1) PerlLIO_close(connector); if (acceptor != -1) PerlLIO_close(acceptor); - errno = save_errno; + RESTORE_ERRNO; return -1; } } @@ -5131,6 +5222,8 @@ Perl_parse_unicode_opts(pTHX_ const char **popt) const char *p = *popt; U32 opt = 0; + PERL_ARGS_ASSERT_PARSE_UNICODE_OPTS; + if (*p) { if (isDIGIT(*p)) { opt = (U32) atoi(p); @@ -5310,6 +5403,7 @@ Perl_stashpv_hvname_match(pTHX_ const COP *c, const HV *hv) const char * const stashpv = CopSTASHPV(c); const char * const name = HvNAME_get(hv); PERL_UNUSED_CONTEXT; + PERL_ARGS_ASSERT_STASHPV_HVNAME_MATCH; if (stashpv == name) return TRUE; @@ -5386,6 +5480,7 @@ Perl_init_global_struct(pTHX) void Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp) { + PERL_ARGS_ASSERT_FREE_GLOBAL_STRUCT; # ifdef PERL_GLOBAL_STRUCT # ifdef PERL_UNSET_VARS PERL_UNSET_VARS(plvarsp); @@ -5406,9 +5501,15 @@ Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp) * PERL_MEM_LOG: the Perl_mem_log_..() will be compiled. * * PERL_MEM_LOG_ENV: if defined, during run time the environment - * variable PERL_MEM_LOG will be consulted, and if the integer value - * of that is true, the logging will happen. (The default is to - * always log if the PERL_MEM_LOG define was in effect.) + * variables PERL_MEM_LOG and PERL_SV_LOG will be consulted, and + * if the integer value of that is true, the logging will happen. + * (The default is to always log if the PERL_MEM_LOG define was + * in effect.) + * + * PERL_MEM_LOG_TIMESTAMP: if defined, a timestamp will be logged + * before every memory logging entry. This can be turned off at run + * time by setting the environment variable PERL_MEM_LOG_TIMESTAMP + * to zero. */ /* @@ -5427,15 +5528,27 @@ Perl_free_global_struct(pTHX_ struct perl_vars *plvarsp) # define PERL_MEM_LOG_FD 2 /* If STDERR is too boring for you. */ #endif -Malloc_t -Perl_mem_log_alloc(const UV n, const UV typesize, const char *typename, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname) -{ #ifdef PERL_MEM_LOG_STDERR + +# ifdef DEBUG_LEAKING_SCALARS +# define SV_LOG_SERIAL_FMT " [%lu]" +# define _SV_LOG_SERIAL_ARG(sv) , (unsigned long) (sv)->sv_debug_serial +# else +# define SV_LOG_SERIAL_FMT +# define _SV_LOG_SERIAL_ARG(sv) +# endif + +static void +S_mem_log_common(enum mem_log_type mlt, const UV n, const UV typesize, const char *type_name, const SV *sv, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname) +{ # if defined(PERL_MEM_LOG_ENV) || defined(PERL_MEM_LOG_ENV_FD) - char *s; + const char *s; # endif + + PERL_ARGS_ASSERT_MEM_LOG_COMMON; + # ifdef PERL_MEM_LOG_ENV - s = getenv("PERL_MEM_LOG"); + s = PerlEnv_getenv(mlt < MLT_NEW_SV ? "PERL_MEM_LOG" : "PERL_SV_LOG"); if (s ? atoi(s) : 0) # endif { @@ -5443,83 +5556,90 @@ Perl_mem_log_alloc(const UV n, const UV typesize, const char *typename, Malloc_t * so we'll use stdio and low-level IO instead. */ char buf[PERL_MEM_LOG_SPRINTF_BUF_SIZE]; # ifdef PERL_MEM_LOG_TIMESTAMP - struct timeval tv; # ifdef HAS_GETTIMEOFDAY +# define MEM_LOG_TIME_FMT "%10d.%06d: " +# define MEM_LOG_TIME_ARG (int)tv.tv_sec, (int)tv.tv_usec + struct timeval tv; gettimeofday(&tv, 0); +# else +# define MEM_LOG_TIME_FMT "%10d: " +# define MEM_LOG_TIME_ARG (int)when + Time_t when; + (void)time(&when); # endif /* If there are other OS specific ways of hires time than - * gettimeofday() (see ext/Time/HiRes), the easiest way is + * gettimeofday() (see ext/Time-HiRes), the easiest way is * probably that they would be used to fill in the struct * timeval. */ # endif { - const STRLEN len = - my_snprintf(buf, - sizeof(buf), -# ifdef PERL_MEM_LOG_TIMESTAMP - "%10d.%06d: " + int fd = PERL_MEM_LOG_FD; + STRLEN len; + +# ifdef PERL_MEM_LOG_ENV_FD + if ((s = PerlEnv_getenv("PERL_MEM_LOG_FD"))) { + fd = atoi(s); + } # endif - "alloc: %s:%d:%s: %"IVdf" %"UVuf - " %s = %"IVdf": %"UVxf"\n", -# ifdef PERL_MEM_LOG_TIMESTAMP - (int)tv.tv_sec, (int)tv.tv_usec, +# ifdef PERL_MEM_LOG_TIMESTAMP + s = PerlEnv_getenv("PERL_MEM_LOG_TIMESTAMP"); + if (!s || atoi(s)) { + len = my_snprintf(buf, sizeof(buf), + MEM_LOG_TIME_FMT, MEM_LOG_TIME_ARG); + PerlLIO_write(fd, buf, len); + } # endif - filename, linenumber, funcname, n, typesize, - typename, n * typesize, PTR2UV(newalloc)); -# ifdef PERL_MEM_LOG_ENV_FD - s = PerlEnv_getenv("PERL_MEM_LOG_FD"); - PerlLIO_write(s ? atoi(s) : PERL_MEM_LOG_FD, buf, len); -# else - PerlLIO_write(PERL_MEM_LOG_FD, buf, len); -#endif + switch (mlt) { + case MLT_ALLOC: + len = my_snprintf(buf, sizeof(buf), + "alloc: %s:%d:%s: %"IVdf" %"UVuf + " %s = %"IVdf": %"UVxf"\n", + filename, linenumber, funcname, n, typesize, + type_name, n * typesize, PTR2UV(newalloc)); + break; + case MLT_REALLOC: + len = my_snprintf(buf, sizeof(buf), + "realloc: %s:%d:%s: %"IVdf" %"UVuf + " %s = %"IVdf": %"UVxf" -> %"UVxf"\n", + filename, linenumber, funcname, n, typesize, + type_name, n * typesize, PTR2UV(oldalloc), + PTR2UV(newalloc)); + break; + case MLT_FREE: + len = my_snprintf(buf, sizeof(buf), + "free: %s:%d:%s: %"UVxf"\n", + filename, linenumber, funcname, + PTR2UV(oldalloc)); + break; + case MLT_NEW_SV: + case MLT_DEL_SV: + len = my_snprintf(buf, sizeof(buf), + "%s_SV: %s:%d:%s: %"UVxf SV_LOG_SERIAL_FMT "\n", + mlt == MLT_NEW_SV ? "new" : "del", + filename, linenumber, funcname, + PTR2UV(sv) _SV_LOG_SERIAL_ARG(sv)); + break; + } + PerlLIO_write(fd, buf, len); } } +} +#endif + +Malloc_t +Perl_mem_log_alloc(const UV n, const UV typesize, const char *type_name, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname) +{ +#ifdef PERL_MEM_LOG_STDERR + mem_log_common(MLT_ALLOC, n, typesize, type_name, NULL, NULL, newalloc, filename, linenumber, funcname); #endif return newalloc; } Malloc_t -Perl_mem_log_realloc(const UV n, const UV typesize, const char *typename, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname) +Perl_mem_log_realloc(const UV n, const UV typesize, const char *type_name, Malloc_t oldalloc, Malloc_t newalloc, const char *filename, const int linenumber, const char *funcname) { #ifdef PERL_MEM_LOG_STDERR -# if defined(PERL_MEM_LOG_ENV) || defined(PERL_MEM_LOG_ENV_FD) - char *s; -# endif -# ifdef PERL_MEM_LOG_ENV - s = PerlEnv_getenv("PERL_MEM_LOG"); - if (s ? atoi(s) : 0) -# endif - { - /* We can't use SVs or PerlIO for obvious reasons, - * so we'll use stdio and low-level IO instead. */ - char buf[PERL_MEM_LOG_SPRINTF_BUF_SIZE]; -# ifdef PERL_MEM_LOG_TIMESTAMP - struct timeval tv; - gettimeofday(&tv, 0); -# endif - { - const STRLEN len = - my_snprintf(buf, - sizeof(buf), -# ifdef PERL_MEM_LOG_TIMESTAMP - "%10d.%06d: " -# endif - "realloc: %s:%d:%s: %"IVdf" %"UVuf - " %s = %"IVdf": %"UVxf" -> %"UVxf"\n", -# ifdef PERL_MEM_LOG_TIMESTAMP - (int)tv.tv_sec, (int)tv.tv_usec, -# endif - filename, linenumber, funcname, n, typesize, - typename, n * typesize, PTR2UV(oldalloc), - PTR2UV(newalloc)); -# ifdef PERL_MEM_LOG_ENV_FD - s = PerlEnv_getenv("PERL_MEM_LOG_FD"); - PerlLIO_write(s ? atoi(s) : PERL_MEM_LOG_FD, buf, len); -# else - PerlLIO_write(PERL_MEM_LOG_FD, buf, len); -# endif - } - } + mem_log_common(MLT_REALLOC, n, typesize, type_name, NULL, oldalloc, newalloc, filename, linenumber, funcname); #endif return newalloc; } @@ -5528,46 +5648,27 @@ Malloc_t Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber, const char *funcname) { #ifdef PERL_MEM_LOG_STDERR -# if defined(PERL_MEM_LOG_ENV) || defined(PERL_MEM_LOG_ENV_FD) - char *s; -# endif -# ifdef PERL_MEM_LOG_ENV - s = PerlEnv_getenv("PERL_MEM_LOG"); - if (s ? atoi(s) : 0) -# endif - { - /* We can't use SVs or PerlIO for obvious reasons, - * so we'll use stdio and low-level IO instead. */ - char buf[PERL_MEM_LOG_SPRINTF_BUF_SIZE]; -# ifdef PERL_MEM_LOG_TIMESTAMP - struct timeval tv; - gettimeofday(&tv, 0); -# endif - { - const STRLEN len = - my_snprintf(buf, - sizeof(buf), -# ifdef PERL_MEM_LOG_TIMESTAMP - "%10d.%06d: " -# endif - "free: %s:%d:%s: %"UVxf"\n", -# ifdef PERL_MEM_LOG_TIMESTAMP - (int)tv.tv_sec, (int)tv.tv_usec, -# endif - filename, linenumber, funcname, - PTR2UV(oldalloc)); -# ifdef PERL_MEM_LOG_ENV_FD - s = PerlEnv_getenv("PERL_MEM_LOG_FD"); - PerlLIO_write(s ? atoi(s) : PERL_MEM_LOG_FD, buf, len); -# else - PerlLIO_write(PERL_MEM_LOG_FD, buf, len); -# endif - } - } + mem_log_common(MLT_FREE, 0, 0, "", NULL, oldalloc, NULL, filename, linenumber, funcname); #endif return oldalloc; } +void +Perl_mem_log_new_sv(const SV *sv, const char *filename, const int linenumber, const char *funcname) +{ +#ifdef PERL_MEM_LOG_STDERR + mem_log_common(MLT_NEW_SV, 0, 0, "", sv, NULL, NULL, filename, linenumber, funcname); +#endif +} + +void +Perl_mem_log_del_sv(const SV *sv, const char *filename, const int linenumber, const char *funcname) +{ +#ifdef PERL_MEM_LOG_STDERR + mem_log_common(MLT_DEL_SV, 0, 0, "", sv, NULL, NULL, filename, linenumber, funcname); +#endif +} + #endif /* PERL_MEM_LOG */ /* @@ -5584,6 +5685,7 @@ int Perl_my_sprintf(char *buffer, const char* pat, ...) { va_list args; + PERL_ARGS_ASSERT_MY_SPRINTF; va_start(args, pat); vsprintf(buffer, pat, args); va_end(args); @@ -5609,6 +5711,7 @@ Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...) dTHX; int retval; va_list ap; + PERL_ARGS_ASSERT_MY_SNPRINTF; va_start(ap, format); #ifdef HAS_VSNPRINTF retval = vsnprintf(buffer, len, format, ap); @@ -5640,6 +5743,9 @@ Perl_my_vsnprintf(char *buffer, const Size_t len, const char *format, va_list ap int retval; #ifdef NEED_VA_COPY va_list apc; + + PERL_ARGS_ASSERT_MY_VSNPRINTF; + Perl_va_copy(ap, apc); # ifdef HAS_VSNPRINTF retval = vsnprintf(buffer, len, format, apc); @@ -5729,6 +5835,7 @@ Perl_my_cxt_init(pTHX_ int *index, size_t size) { dVAR; void *p; + PERL_ARGS_ASSERT_MY_CXT_INIT; if (*index == -1) { /* this module hasn't been allocated an index yet */ MUTEX_LOCK(&PL_my_ctx_mutex); @@ -5763,6 +5870,8 @@ Perl_my_cxt_index(pTHX_ const char *my_cxt_key) dVAR; int index; + PERL_ARGS_ASSERT_MY_CXT_INDEX; + for (index = 0; index < PL_my_cxt_index; index++) { const char *key = PL_my_cxt_keys[index]; /* try direct pointer compare first - there are chances to success, @@ -5781,6 +5890,8 @@ Perl_my_cxt_init(pTHX_ const char *my_cxt_key, size_t size) void *p; int index; + PERL_ARGS_ASSERT_MY_CXT_INIT; + index = Perl_my_cxt_index(aTHX_ my_cxt_key); if (index == -1) { /* this module hasn't been allocated an index yet */ @@ -5867,6 +5978,8 @@ Perl_get_db_sub(pTHX_ SV **svp, CV *cv) * it's for informational purposes only. */ + PERL_ARGS_ASSERT_GET_DB_SUB; + save_item(dbsv); if (!PERLDB_SUB_NN) { GV * const gv = CvGV(cv); @@ -5874,10 +5987,11 @@ Perl_get_db_sub(pTHX_ SV **svp, CV *cv) if ( svp && ((CvFLAGS(cv) & (CVf_ANON | CVf_CLONED)) || strEQ(GvNAME(gv), "END") || ((GvCV(gv) != cv) && /* Could be imported, and old sub redefined. */ - !( (SvTYPE(*svp) == SVt_PVGV) && (GvCV((GV*)*svp) == cv) )))) { + !( (SvTYPE(*svp) == SVt_PVGV) + && (GvCV((const GV *)*svp) == cv) )))) { /* Use GV from the stack as a fallback. */ /* GV is potentially non-unique, or contain different CV. */ - SV * const tmp = newRV((SV*)cv); + SV * const tmp = newRV(MUTABLE_SV(cv)); sv_setsv(dbsv, tmp); SvREFCNT_dec(tmp); } @@ -5919,10 +6033,10 @@ Perl_get_re_arg(pTHX_ SV *sv) { if (SvMAGICAL(sv)) mg_get(sv); if (SvROK(sv) && - (tmpsv = (SV*)SvRV(sv)) && /* assign deliberate */ + (tmpsv = MUTABLE_SV(SvRV(sv))) && /* assign deliberate */ SvTYPE(tmpsv) == SVt_REGEXP) { - return ((struct xregexp *)SvANY(tmpsv))->xrx_regexp; + return (REGEXP*) tmpsv; } }