Author: tim.bunce
Date: Sun Mar 8 12:10:07 2009
New Revision: 706
Modified:
trunk/Changes
trunk/NYTProf.xs
trunk/lib/Devel/NYTProf/Constants.pm
trunk/lib/Devel/NYTProf/FileInfo.pm
trunk/t/lib/NYTProfTest.pm
Log:
Fix savesrc by writing source at end of profile run
added a fid flag to indicate src is available,
and another to indicate src should be saved.
Modified: trunk/Changes
==============================================================================
--- trunk/Changes (original)
+++ trunk/Changes Sun Mar 8 12:10:07 2009
@@ -9,7 +9,9 @@
Fixed report filename generation to remove colons,
for Windows, reported by Adam Kennedy in rt bug #43798.
Fixed report filename generation to remove dots, for VMS.
+ Fixed savesrc which wasn't safe and reliable.
Added missing t/test22-strevala.t to MANIFEST.
+ Extended testing to exercise compress and savesrc options.
Ported to VMS, thanks to Peter (Stig) Edwards:
Modified: trunk/NYTProf.xs
==============================================================================
--- trunk/NYTProf.xs (original)
+++ trunk/NYTProf.xs Sun Mar 8 12:10:07 2009
@@ -30,6 +30,9 @@
#if !defined(OutCopFILE)
# define OutCopFILE CopFILE
#endif
+#ifndef gv_fetchfile_flags
+#define gv_fetchfile_flags(str, len, flags) gv_fetchfile(str)
+#endif
#ifndef OP_SETSTATE
#define OP_SETSTATE OP_NEXTSTATE
@@ -77,6 +80,8 @@
#define NYTP_FIDf_VIA_STMT 0x0002 /* fid first seen by stmt profiler
*/
#define NYTP_FIDf_VIA_SUB 0x0004 /* fid first seen by sub profiler
*/
#define NYTP_FIDf_IS_AUTOSPLIT 0x0008 /* fid is cone of the 'parent' fid
it was autosplit from */
+#define NYTP_FIDf_HAS_SRC 0x0010 /* src is available to profiler */
+#define NYTP_FIDf_SAVE_SRC 0x0020 /* src will be saved by profiler,
if NYTP_FIDf_HAS_SRC also set */
#define NYTP_TAG_ATTRIBUTE ':' /* :name=value\n */
#define NYTP_TAG_COMMENT '#' /* till newline */
@@ -310,6 +315,7 @@
static void open_output_file(pTHX_ char *);
static int reinit_if_forked(pTHX);
static void write_cached_fids(void);
+static void write_src_of_files(pTHX);
static void write_sub_line_ranges(pTHX);
static void write_sub_callers(pTHX);
static HV *load_profile_data_from_stream(SV* cb);
@@ -1249,58 +1255,39 @@
found->fid_flags |= NYTP_FIDf_IS_PMC;
found->fid_flags |= created_via; /* NYTP_FIDf_VIA_STMT or
NYTP_FIDf_VIA_SUB */
- emit_fid(found);
+ /* is source code available? */
+ /* source only available if PERLDB_LINE or PERLDB_SAVESRC is true */
+ /* which we set if savesrc option is enabled */
+ if ( (src_av = GvAV(gv_fetchfile_flags(found->key, found->key_len,
0))) )
+ found->fid_flags |= NYTP_FIDf_HAS_SRC;
/* if it's a string eval or a synthetic filename from CODE ref in @INC,
- * or the command line -e '...code...'
- * then think about writing out the source code */
+ * or the command line -e '...code...'
+ * then we'd like to save the src (NYTP_FIDf_HAS_SRC) if it's available
+ */
if (found->eval_fid
|| (found->key_len > 10 && found->key[9] == 'x' &&
strnEQ(found->key, "/loader/0x", 10))
|| (found->key_len == 1 && strnEQ(found->key, "-", 1))
|| (found->key_len == 2 && strnEQ(found->key, "-e", 2))
|| (profile_opts & NYTP_OPTf_SAVESRC)
) {
- /* source only available if PERLDB_LINE or PERLDB_SAVESRC is true
*/
-#ifdef gv_fetchfile_flags
- src_av = GvAV(gv_fetchfile_flags(found->key, found->key_len, 0));
-#else
- src_av = GvAV(gv_fetchfile(found->key));
-#endif
- if (!src_av && trace_level >= 3)
- warn("No source available for fid %d%s\n",
- found->id, use_db_sub ? "" : ", set use_db_sub=1 option");
+ found->fid_flags |= NYTP_FIDf_SAVE_SRC;
}
+ emit_fid(found);
+
if (trace_level >= 2) {
/* including last_executed_fid can be handy for tracking down how
* a file got loaded */
- warn("New fid %2u (after %2u:%-4u) %x e%u:%u %.*s %s%s\n",
+ warn("New fid %2u (after %2u:%-4u) %x e%u:%u %.*s %s %s,%s\n",
found->id, last_executed_fid, last_executed_line,
found->fid_flags, found->eval_fid, found->eval_line_num,
found->key_len, found->key, (found->key_abs) ?
found->key_abs : "",
- src_av ? ", with src" : ""
+ (found->fid_flags & NYTP_FIDf_HAS_SRC) ? "has src" : "no src",
+ (found->fid_flags & NYTP_FIDf_SAVE_SRC) ? "save src" : "won't
save"
);
}
- if (src_av) {
- I32 lines = av_len(src_av);
- int line;
- if (trace_level >= 4)
- warn("fid %d has %ld src lines", found->id, (long)lines);
- for (line = 1; line <= lines; ++line) { /* lines start at 1 */
- SV **svp = av_fetch(src_av, line, 0);
- STRLEN len = 0;
- char *src = (svp) ? SvPV(*svp, len) : "";
- /* outputting the tag and fid for each (non empty) line
- * is a little inefficient, but not enough to worry about */
- output_tag_int(NYTP_TAG_SRC_LINE, found->id);
- output_int(line);
- output_str(src, (I32)len); /* includes newline */
- if (trace_level >= 5)
- warn("fid %d src line %d: %s", found->id, line, src);
- }
- }
-
return found->id;
}
@@ -1919,6 +1906,7 @@
if (!out)
return;
+ write_src_of_files(aTHX);
write_sub_line_ranges(aTHX);
write_sub_callers(aTHX);
/* mark end of profile data for last_pid pid
@@ -2776,6 +2764,67 @@
}
+static void
+write_src_of_files(pTHX)
+{
+ Hash_entry *e;
+ int t_has_src = 0;
+ int t_save_src = 0;
+ int t_no_src = 0;
+ long t_lines = 0;
+
+ if (trace_level >= 1)
+ warn("writing file source code\n");
+
+ for (e = hashtable.first_inserted; e; e = (Hash_entry
*)e->next_inserted) {
+ I32 lines;
+ int line;
+ AV *src_av = GvAV(gv_fetchfile_flags(e->key, e->key_len, 0));
+
+ if ( !(e->fid_flags & NYTP_FIDf_HAS_SRC) ) {
+ ++t_no_src;
+ if (src_av) /* sanity check */
+ warn("fid %d has src but NYTP_FIDf_HAS_SRC not set!
(%.*s)",
+ e->id, e->key_len, e->key);
+ continue;
+ }
+ if (!src_av) { /* sanity check */
+ ++t_no_src;
+ warn("fid %d has no src but NYTP_FIDf_HAS_SRC is set! (%.*s)",
+ e->id, e->key_len, e->key);
+ continue;
+ }
+ ++t_has_src;
+
+ if ( !(e->fid_flags & NYTP_FIDf_SAVE_SRC) ) {
+ continue;
+ }
+ ++t_save_src;
+
+ lines = av_len(src_av);
+ if (trace_level >= 4)
+ warn("fid %d has %ld src lines", e->id, (long)lines);
+ for (line = 1; line <= lines; ++line) { /* lines start at 1 */
+ SV **svp = av_fetch(src_av, line, 0);
+ STRLEN len = 0;
+ char *src = (svp) ? SvPV(*svp, len) : "";
+ /* outputting the tag and fid for each (non empty) line
+ * is a little inefficient, but not enough to worry about */
+ output_tag_int(NYTP_TAG_SRC_LINE, e->id);
+ output_int(line);
+ output_str(src, (I32)len); /* includes newline */
+ if (trace_level >= 5)
+ warn("fid %d src line %d: %s", e->id, line, src);
+ ++t_lines;
+ }
+ }
+
+ if (trace_level >= 1)
+ warn("wrote %d source lines for %d files (%d skipped without
savesrc option, %d others had no source available)\n",
+ t_lines, t_save_src, t_has_src-t_save_src, t_no_src);
+}
+
+
/**
* Read an integer by decompressing the next 1 to 4 bytes of binary into a
32-
* bit integer. See output_int() for the compression details.
@@ -3724,7 +3773,13 @@
BOOT:
{
HV *stash = gv_stashpv("Devel::NYTProf::Constants", GV_ADDWARN);
- newCONSTSUB(stash, "NYTP_FIDf_IS_PMC", newSViv(NYTP_FIDf_IS_PMC));
+ /* NYTP_FIDf_* */
+ newCONSTSUB(stash, "NYTP_FIDf_IS_PMC",
newSViv(NYTP_FIDf_IS_PMC));
+ newCONSTSUB(stash, "NYTP_FIDf_VIA_STMT",
newSViv(NYTP_FIDf_VIA_STMT));
+ newCONSTSUB(stash, "NYTP_FIDf_VIA_SUB",
newSViv(NYTP_FIDf_VIA_SUB));
+ newCONSTSUB(stash, "NYTP_FIDf_IS_AUTOSPLIT",
newSViv(NYTP_FIDf_IS_AUTOSPLIT));
+ newCONSTSUB(stash, "NYTP_FIDf_HAS_SRC",
newSViv(NYTP_FIDf_HAS_SRC));
+ newCONSTSUB(stash, "NYTP_FIDf_SAVE_SRC",
newSViv(NYTP_FIDf_SAVE_SRC));
/* NYTP_FIDi_* */
newCONSTSUB(stash, "NYTP_FIDi_FILENAME", newSViv(NYTP_FIDi_FILENAME));
newCONSTSUB(stash, "NYTP_FIDi_EVAL_FID", newSViv(NYTP_FIDi_EVAL_FID));
Modified: trunk/lib/Devel/NYTProf/Constants.pm
==============================================================================
--- trunk/lib/Devel/NYTProf/Constants.pm (original)
+++ trunk/lib/Devel/NYTProf/Constants.pm Sun Mar 8 12:10:07 2009
@@ -10,4 +10,6 @@
our @EXPORT_OK = grep { /^NYTP_/ } keys %$symbol_table;
+#warn "Constants: ".join(" ", sort @EXPORT_OK);
+
1;
Modified: trunk/lib/Devel/NYTProf/FileInfo.pm
==============================================================================
--- trunk/lib/Devel/NYTProf/FileInfo.pm (original)
+++ trunk/lib/Devel/NYTProf/FileInfo.pm Sun Mar 8 12:10:07 2009
@@ -5,6 +5,8 @@
use Devel::NYTProf::Util qw(strip_prefix_from_paths);
use Devel::NYTProf::Constants qw(
+ NYTP_FIDf_HAS_SRC NYTP_FIDf_SAVE_SRC
+
NYTP_FIDi_FILENAME NYTP_FIDi_EVAL_FID NYTP_FIDi_EVAL_LINE NYTP_FIDi_FID
NYTP_FIDi_FLAGS NYTP_FIDi_FILESIZE NYTP_FIDi_FILEMTIME
NYTP_FIDi_PROFILE
NYTP_FIDi_EVAL_FI NYTP_FIDi_HAS_EVALS NYTP_FIDi_SUBS_DEFINED
NYTP_FIDi_SUBS_CALLED
@@ -173,6 +175,9 @@
# normalize eval sequence numbers in 'file' names to 0
$self->[NYTP_FIDi_FILENAME] =~ s/ \( ((?:re_)?) eval \s \d+ \)
/(${1}eval 0)/xg;
+
+ # normalize flags to avoid failures due to savesrc and perl version
+ $self->[NYTP_FIDi_FLAGS] &= ~(NYTP_FIDf_HAS_SRC|NYTP_FIDf_SAVE_SRC);
for my $sc (map { values %$_ } values %{ $self->sub_call_lines }) {
$sc->[NYTP_SCi_INCL_RTIME] =
Modified: trunk/t/lib/NYTProfTest.pm
==============================================================================
--- trunk/t/lib/NYTProfTest.pm (original)
+++ trunk/t/lib/NYTProfTest.pm Sun Mar 8 12:10:07 2009
@@ -140,6 +140,7 @@
}
}
+
sub run_test {
my ($test) = @_;
--~--~---------~--~----~------------~-------~--~----~
You've received this message because you are subscribed to
the Devel::NYTProf Development User group.
Group hosted at: http://groups.google.com/group/develnytprof-dev
Project hosted at: http://perl-devel-nytprof.googlecode.com
CPAN distribution: http://search.cpan.org/dist/Devel-NYTProf
To post, email: [email protected]
To unsubscribe, email: [email protected]
-~----------~----~----~----~------~----~------~--~---