Closed Bug 961430 Opened 10 years ago Closed 8 years ago

Let pid be added to the NSPR log name

Categories

(Core :: XPCOM, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla47
Tracking Status
firefox47 --- fixed

People

(Reporter: mayhemer, Assigned: mayhemer)

References

Details

Attachments

(1 file, 4 obsolete files)

Attached patch v1 (obsolete) — Splinter Review
To allow upload of NSPR logs from tryserver runs, the log name must have a '.log' extension.
Attachment #8362157 - Flags: review?(jduell.mcbugs)
Hmm.. further testing shows that the patch and approach from bug 534764 has serious problems.

When I set NSPR_LOG_FILE=~/foo.nspr and run e.g. mochitests, then other binaries based on nspr (certutil, ssltunnel, xpcshell...) all try to open and write to the same file.  Spawning gecko child processes has nothing to do with it.

I'm using my local path that, when NSPR_LOG_FILE_MULTIPROCESS=1 set, inserts pid between the log file name and the extension.  So, for NSPR_LOG_FILE=~/foo.nspr the log name will be ~/foo-1234.nspr.

I think to make this 100% work we rather need a solution like that.
Summary: Add '.log' to the child NSPR log name → Improve single nspr log file sharing by multiple processes
Attached patch nspr-log-with-pid.patch (obsolete) — Splinter Review
- inserts (optionally) pid to the log file name
- driven by NSPR_LOG_FILE_MULTIPROCESS
Assignee: nobody → honzab.moz
Attachment #8362157 - Attachment is obsolete: true
Status: NEW → ASSIGNED
Attachment #8362157 - Flags: review?(jduell.mcbugs)
Attachment #8362159 - Flags: review?(wtc)
Component: IPC → NSPR
Product: Core → NSPR
Version: Other Branch → 4.10.5
Blocks: 961147
(In reply to Honza Bambas (:mayhemer) from comment #1)
> When I set NSPR_LOG_FILE=~/foo.nspr and run e.g. mochitests, then other
> binaries based on nspr (certutil, ssltunnel, xpcshell...) all try to open
> and write to the same file.  Spawning gecko child processes has nothing to
> do with it.

Looks like this was just my local setting (the bash prompt I was running tests from had set the log file path).  When checking env of other test processes I can see they don't have set path to the log file, browserEnv only goes to the browser, not to the utilities.

So, to make bug 961147 work, we don't need this bug.

Still, I think it's useful to have this in the tree.
No longer blocks: 961147
Comment on attachment 8362159 [details] [diff] [review]
nspr-log-with-pid.patch

Review of attachment 8362159 [details] [diff] [review]:
-----------------------------------------------------------------

Honza:

Thanks for the patch. This change seems useful. I have two
high-level comments.

1. The NSPR_LOG_FILE_MULTIPROCESS variable can be renamed
"NSPR_LOG_FILE_WITH_PID". "Multiprocess" can also be interpreted
as allowing multiple processes to write to the same log file
correctly.

2. I remember I reviewed a similar patch that takes a different
approach. It allows a special token ${PID} in NSPR_LOG_FILE,
which is substituted with the pid by NSPR. However, I can't find
that patch in Bugzilla.

In that approach, you would simply set
    NSPR_LOG_FILE=~/foo-${PID}.nspr

The complication with that approach is to prevent the shell
from substituting ${PID} when you set NSPR_LOG_FILE. So we may
need to use other special characters that do not have a special
meaning in shells, or we may need to use $${PID}.

::: nsprpub/pr/src/io/prlog.c
@@ +11,5 @@
> +#ifdef XP_PC
> +#include <process.h>
> +#else
> +#include <sys/types.h>
> +#include <unistd.h>

Nit: in current versions of Unix, it's no longer necessary to first include <sys/types.h>. See http://pubs.opengroup.org/onlinepubs/009695399/functions/getpid.html

@@ +190,5 @@
>  
>  void _PR_InitLog(void)
>  {
>      char *ev;
> +    int mp = 0;

This variable should be of the PRBool type.

I suggest using a longer variable name, such as "multiProcess".

@@ +253,5 @@
>              return;
>          }
>  #endif /* XP_UNIX */
>  
> +        /* Append pid to the log file name if demanded */

Nit: "demanded" sounds a little strange. I suggest "requested" or "NSPR_LOG_FILE_MULTIPROCES is set".

@@ +262,5 @@
>          if (ev && ev[0]) {
> +            char buf[1024];
> +            char * filename;
> +
> +            if (mp) {

Please add a comment to describe how the pid is added to the base log file name. Give one example for each case (base log file name may or may not have an extension).

@@ +263,5 @@
> +            char buf[1024];
> +            char * filename;
> +
> +            if (mp) {
> +                char * ext = strrchr(ev, '.');

Nit: declare this as "const char *". Remove the space between "*" and "ext".

@@ +272,5 @@
> +                else
> +                    extpos = ext - ev;
> +
> +                filename = buf;
> +                PR_snprintf(buf, 1023, "%*.*s-%u%*.*s",

Why do you pass 1023 instead of 1024?

@@ +278,4 @@
>  #ifdef XP_PC
> +                    _getpid()
> +#else
> +                    getpid()

Nit: add a "(unsigned int)" cast. Place the comma after this line.

@@ +279,5 @@
> +                    _getpid()
> +#else
> +                    getpid()
> +#endif
> +                    , evlen - extpos, evlen - extpos, ext

IMPORTANT: does this work when |ext| is NULL? I am afraid that passing NULL to %s is not portable, even if the width and precision are both 0.
(In reply to Wan-Teh Chang from comment #4)
> Comment on attachment 8362159 [details] [diff] [review]
> nspr-log-with-pid.patch
> 
> 2. I remember I reviewed a similar patch that takes a different
> approach. It allows a special token ${PID} in NSPR_LOG_FILE,
> which is substituted with the pid by NSPR. However, I can't find
> that patch in Bugzilla.
> 
> In that approach, you would simply set
>     NSPR_LOG_FILE=~/foo-${PID}.nspr
> 
> The complication with that approach is to prevent the shell
> from substituting ${PID} when you set NSPR_LOG_FILE. So we may
> need to use other special characters that do not have a special
> meaning in shells, or we may need to use $${PID}.


Thanks Wan-Teh.  It's not clear if you want me to use this approach ($${something}) or the current approach where the pid is added before the extension.
Honza: sorry I didn't clearly state my preference. I would prefer
the magic ${PID} token approach because it is more flexible.

By the way, I found that $$ is a special built-in variable in shell.
On the other hand, $ can be easily escaped with either single quotes
or a backslash, so it's not that bad.
Summary: Improve single nspr log file sharing by multiple processes → Let pid be added to the NSPR log name
Attachment #8362159 - Attachment is obsolete: true
Attachment #8362159 - Flags: review?(wtc)
Component: NSPR → XPCOM
Product: NSPR → Core
Version: 4.10.5 → Trunk
To sum the idea:

with NSPR_LOG_FILE=my_log_${PID}.log you will be getting files like my_log_8734.log for each process.
(In reply to Honza Bambas (:mayhemer) from comment #7)
> with NSPR_LOG_FILE=my_log_${PID}.log you will be getting files like
> my_log_8734.log for each process.

Seems reasonable; I wonder if that would let us remove the hacks we have in place to make NSPR_LOG_FILE work with e10s?
(In reply to Nathan Froyd [:froydnj] from comment #8)
> (In reply to Honza Bambas (:mayhemer) from comment #7)
> > with NSPR_LOG_FILE=my_log_${PID}.log you will be getting files like
> > my_log_8734.log for each process.
> 
> Seems reasonable; I wonder if that would let us remove the hacks we have in
> place to make NSPR_LOG_FILE work with e10s?

I'm not sure.  This is kinda orthogonal.  Sometimes I use it (the now obsolete patch) when running e.g. xpcshell tests in parallel.  There were times I was using this to separate child/parent logs, but that led to just being polluted with huge number of logs.  What we have now (the hacks) is imo better than this, so I would leave it.

I'm not pushing on this feature right now, I stopped using it, except occasionally since we have "fixed" the child logs.
Attached patch v1 (obsolete) — Splinter Review
When there is '%PID' token in the file name, it's replaced with the pid of the application.  So for NSPR_LOG_FILE=/mozilla/log/my-%PID.log you get /mozilla/log/my-1234.log, my-1234.log-child1 etc. log files.

I'm not using any more sophisticated tokenizer here, just plain str* functions.  I think you don't want to use nsString in Logging.cpp.

This has one bad effect, there will be empty log files with '%PID' in the name thanks bug 1248565.
Attachment #8719750 - Flags: review?(nfroyd)
Blocks: 1248711
Comment on attachment 8719750 [details] [diff] [review]
v1

Review of attachment 8719750 [details] [diff] [review]:
-----------------------------------------------------------------

Patch seems reasonable, but I have a few small concerns.  Nit on the reviewer name in the commit message, too. ;)

::: xpcom/base/Logging.cpp
@@ +17,5 @@
>  #include "NSPRLogModulesParser.h"
>  
>  #include "prenv.h"
>  #include "prprf.h"
> +#ifdef XP_PC

Where is XP_PC getting defined?  The only reference I can find is in our moz.build for NSPR; I think we typically use XP_WIN for this sort of thing in Gecko.

@@ +56,5 @@
>  }
>  
> +int log_pid()
> +{
> +#ifdef XP_PC

Here too.

@@ +140,5 @@
>      mIsSync = isSync;
>  
>      const char* logFile = PR_GetEnv("NSPR_LOG_FILE");
>      if (logFile && logFile[0]) {
> +      char const* pidToken = strstr(logFile, "%PID");

|const char*| for consistency with local code, please.

I think we should write this as:

static const char sPIDToken[] = "%PID";
const char* pidTokenPtr = strstr(logFile, sPIDToken);

@@ +144,5 @@
> +      char const* pidToken = strstr(logFile, "%PID");
> +      static size_t const kFileWithPIDBuffer = 2048;
> +      char buf[kFileWithPIDBuffer];
> +
> +      if (pidToken && pidToken - logFile < kFileWithPIDBuffer) {

I applaud this additional check; I wouldn't have thought of doing it.  But this is not quite a sufficient condition for whether we should do the substitution, is it?  Because one could have:

NSPR_LOG_FILE="...2043 characters...%PID.log"

and then this condition would be satisfied, but with a PID of five digits or more, we'd wind up overrunning the bounds of |buf| with the final |strcpy| below.

I think to be really thorough, we'd need to print the PID to a separate temporary buffer, and do additional length checks with the printed PID.

@@ +147,5 @@
> +
> +      if (pidToken && pidToken - logFile < kFileWithPIDBuffer) {
> +        size_t pidPos = pidToken - logFile;
> +        // buf = "/log-file-
> +        strncpy(buf, logFile, pidPos);

Nit: I have a slight preference for |memcpy| here, to make the non-null-termination clearer and to signal that we don't have to care about the pathological cases of |strncpy|.

@@ +152,5 @@
> +        // buf = "/log-file-1234"
> +        int pidSize = snprintf(buf + pidPos, kFileWithPIDBuffer - pidPos,
> +                               "%d", detail::log_pid());
> +        // buf = "/log-file-1234.log"
> +        strcpy(buf + pidPos + pidSize, pidToken + 4);

We can replace this '4' with |strlen(sPIDToken)|, which makes it a little clearer where the '4' is coming from.  Especially since the strings added in the comments ("1234" and ".log") are both of length 4 themselves!
Attachment #8719750 - Flags: review?(nfroyd) → review-
(In reply to Nathan Froyd [:froydnj] from comment #11)
> > +#ifdef XP_PC
> 
> Where is XP_PC getting defined?  

This is nspr stuff.  The patch was originally meant for the nspr logging code.  There is no XP_WIN.  I think XP_WIN will do what's needed.
Attached patch v1.1 (obsolete) — Splinter Review
A bit nicer approach.
Attachment #8719750 - Attachment is obsolete: true
Attachment #8720369 - Flags: review?(nfroyd)
Comment on attachment 8720369 [details] [diff] [review]
v1.1

Review of attachment 8720369 [details] [diff] [review]:
-----------------------------------------------------------------

I always forget about %.*.

::: xpcom/base/Logging.cpp
@@ +147,5 @@
> +      const char* pidTokenPtr = strstr(logFile, kPIDToken);
> +      char buf[kFileWithPIDBufferSize];
> +
> +      if (pidTokenPtr &&
> +          snprintf(buf, kFileWithPIDBufferSize, "%.*s%d%s",

I think you need to #include "mozilla/Snprintf.h" so this will work correctly on MSVC 2013 (it's possible we're bootlegging Snprintf.h from another header, and we should just include it here as well).
Attachment #8720369 - Flags: review?(nfroyd) → review+
Attached patch v1.2Splinter Review
- includes Snprintf
- uses snprintf_literal => removed the ugly wordy kFileWithPIDBufferSize const
Attachment #8720369 - Attachment is obsolete: true
Attachment #8720820 - Flags: review+
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/153e8aa293c5
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla47
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: