On Mon, Feb 08, 2010 at 11:32:24AM +0000, Nicholas Clark wrote:
> On Sun, Feb 07, 2010 at 11:02:11AM -0800, Ivan Fomichev wrote:
> > On 14 ??????, 17:03, hhaldn <[email protected]> wrote:
> >
> > > I try to merge 2 datafiles generated undermod_perl, I get an error:
> >
> > I have the same problem.
> >
> > Reading tmp/nytprof.out.1144
> > unknown eval_fid 9 at /usr/local/bin/nytprofmerge line 206
> > main::__ANON__('NEW_FID', 8, 9, 1, 34, 0, 0, '(eval 4)') called at /
> ^ ^
> | file ID for the container of this eval
> |
> file ID for this eval
>
> > What can be the root of the problem? Is there an instant workaround?
>
> I don't know what the root is.
>
> (Other than what the message means - that the merger encountered the 'NEW_FID'
> for an eval where that new file ID makes a reference to a file ID that doesn't
> (yet) exist. It seems that the eval has file ID 8, yet lives inside the file
> with ID 9, which is strange, as that means that the file IDs are being
> generated out of order.)
This can happen when get_file_id() is called with an eval string like
(eval 2)[/some/file:line]
*if* "/some/file" hasn't been seen before so doesn't already have a fid
assigned to it.
The underlying issue is that hash_op(), called by get_file_id(),
combines looking up a fid in the cache with assigning a new one if there
isn't an entry. So the fid for "(eval 2)[/some/file:line]" is assigned
first then "/some/file" is looked up, discovered to be new, and so gets
the next fid in sequence.
The fids are _output_ to the file in the right order to avoid problems,
but (I think) that ordering workaround gets lost in the nytprofmerge
processing.
I've appended one completely untested, off-the-top-of-my-head, approach
to fixing this. I think the basic idea is sound, i.e., arrange for the
recursive get_file_id() calls to reuse and output the just-allocated fid
if it needs a new fid, then detect this and adjust the just-allocated
(but not yet output) fid. It would probably be best to encapsule this in
a new get_file_id_of_container(..., found) that wraps get_file_id().
Tim.
--- NYTProf.xs (revision 1044)
+++ NYTProf.xs (working copy)
@@ -798,6 +798,7 @@
* filename, and associate that fid with this eval fid
*/
if ('(' == file_name[0]) { /* first char is '(' */
+ int saved_next_fid = next_fid;
if (']' == file_name[file_name_len-1]) { /* last char is ']' */
char *start = strchr(file_name, '[');
const char *colon = ":";
@@ -810,6 +811,7 @@
}
++start; /* move past [ */
/* recurse */
+ next_fid--;
found->eval_fid = get_file_id(aTHX_ start, end - start,
created_via);
found->eval_line_num = atoi(end+1);
}
@@ -818,11 +820,22 @@
/* seen in mod_perl, possibly from eval_sv(sv) api call */
/* also when nameevals=0 option is in effect */
char eval_file[] = "/unknown-eval-invoker";
+ next_fid--;
found->eval_fid = get_file_id(aTHX_ eval_file, sizeof(eval_file) -
1,
NYTP_FIDf_IS_FAKE | created_via
);
found->eval_line_num = 1;
}
+ /* if get_file_id allocated a new fid then, because of the next_fid--
above,
+ * it would have reused the same fid as found->id (and output it).
+ * So we now adopt ++next_fid as our found->id.
+ */
+ if (next_fid != saved_next_fid)) {
+ found->id = ++next_fid;
+ }
+ else {
+ next_fid = saved_next_fid;
+ }
}
--
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]