Bug 1133073 - Use PR_DuplicateEnvironment to avoid post-fork malloc on all Linux platforms. r=dhylands

This commit is contained in:
Jed Davis 2016-01-11 14:17:01 -08:00
parent 9d7d84e17e
commit f45414c2f0
5 changed files with 16 additions and 100 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1209344 - Remove debug button from about:addons. r=mossop
Bug 1133073 - Use PR_DuplicateEnvironment from NSPR and remove interim mozglue wrappers.

View File

@ -212,11 +212,14 @@ ifdef WRAP_LDFLAGS
NSS_EXTRA_LDFLAGS += $(WRAP_LDFLAGS)
endif
ifdef MOZ_GLUE_WRAP_LDFLAGS
# The SHARED_LIBS part is needed unconditionally on Android. It's not
# clear why this is the case, but see bug 1133073 (starting around
# comment #8) for context.
ifneq (,$(or $(MOZ_GLUE_WRAP_LDFLAGS), $(filter Android, $(OS_TARGET))))
NSS_EXTRA_LDFLAGS += $(SHARED_LIBS:$(DEPTH)%=$(MOZ_BUILD_ROOT)%) $(MOZ_GLUE_WRAP_LDFLAGS)
endif
ifneq (,$(WRAP_LDFLAGS)$(MOZ_GLUE_WRAP_LDFLAGS))
ifneq (,$(NSS_EXTRA_LDFLAGS))
DEFAULT_GMAKE_FLAGS += \
LDFLAGS='$(LDFLAGS) $(NSS_EXTRA_LDFLAGS)' \
DSO_LDOPTS='$(DSO_LDOPTS) $(LDFLAGS) $(NSS_EXTRA_LDFLAGS)' \

View File

@ -7271,7 +7271,6 @@ fi
dnl We need to wrap dlopen and related functions on Android because we use
dnl our own linker.
if test "$OS_TARGET" = Android; then
MOZ_GLUE_WRAP_LDFLAGS="${MOZ_GLUE_WRAP_LDFLAGS} -Wl,--wrap=PR_GetEnv,--wrap=PR_SetEnv"
if test "$MOZ_WIDGET_TOOLKIT" = gonk -a -n "$MOZ_NUWA_PROCESS"; then
MOZ_GLUE_WRAP_LDFLAGS="${MOZ_GLUE_WRAP_LDFLAGS} -Wl,--wrap=pthread_create,--wrap=epoll_wait,--wrap=poll,--wrap=pthread_cond_timedwait,--wrap=pthread_cond_wait,--wrap=epoll_create,--wrap=epoll_ctl,--wrap=close,--wrap=pthread_key_create,--wrap=pthread_key_delete,--wrap=socketpair,--wrap=pthread_self,--wrap=pthread_mutex_lock,--wrap=pthread_mutex_trylock,--wrap=pthread_join,--wrap=pipe,--wrap=pipe2"
fi

View File

@ -22,6 +22,9 @@
#include "nsLiteralString.h"
#include "mozilla/UniquePtr.h"
#include "prenv.h"
#include "prmem.h"
#ifdef MOZ_B2G_LOADER
#include "ProcessUtils.h"
@ -47,21 +50,6 @@ using namespace mozilla::ipc;
# define CHILD_UNPRIVILEGED_GID 65534
#endif
#ifdef ANDROID
#include <pthread.h>
/*
* Currently, PR_DuplicateEnvironment is implemented in
* mozglue/build/BionicGlue.cpp
*/
#define HAVE_PR_DUPLICATE_ENVIRONMENT
#include "plstr.h"
#include "prenv.h"
#include "prmem.h"
/* Temporary until we have PR_DuplicateEnvironment in prenv.h */
extern "C" { NSPR_API(pthread_mutex_t *)PR_GetEnvLock(void); }
#endif
namespace {
enum ParsingState {
@ -75,38 +63,13 @@ static mozilla::EnvironmentLog gProcessLog("MOZ_PROCESS_LOG");
namespace base {
#ifdef HAVE_PR_DUPLICATE_ENVIRONMENT
/*
* I tried to put PR_DuplicateEnvironment down in mozglue, but on android
* this winds up failing because the strdup/free calls wind up mismatching.
*/
static char **
PR_DuplicateEnvironment(void)
{
char **result = NULL;
char **s;
char **d;
pthread_mutex_lock(PR_GetEnvLock());
for (s = environ; *s != NULL; s++)
;
if ((result = (char **)PR_Malloc(sizeof(char *) * (s - environ + 1))) != NULL) {
for (s = environ, d = result; *s != NULL; s++, d++) {
*d = PL_strdup(*s);
}
*d = NULL;
}
pthread_mutex_unlock(PR_GetEnvLock());
return result;
}
class EnvironmentEnvp
{
public:
EnvironmentEnvp()
: mEnvp(PR_DuplicateEnvironment()) {}
EnvironmentEnvp(const environment_map &em)
explicit EnvironmentEnvp(const environment_map &em)
{
mEnvp = (char **)PR_Malloc(sizeof(char *) * (em.size() + 1));
if (!mEnvp) {
@ -118,7 +81,9 @@ public:
std::string str = it->first;
str += "=";
str += it->second;
*e = PL_strdup(str.c_str());
size_t len = str.length() + 1;
*e = static_cast<char*>(PR_Malloc(len));
memcpy(*e, str.c_str(), len);
}
*e = NULL;
}
@ -129,7 +94,7 @@ public:
return;
}
for (char **e = mEnvp; *e; ++e) {
PL_strfree(*e);
PR_Free(*e);
}
PR_Free(mEnvp);
}
@ -178,7 +143,6 @@ public:
private:
std::auto_ptr<EnvironmentEnvp> mEnvp;
};
#endif // HAVE_PR_DUPLICATE_ENVIRONMENT
bool LaunchApp(const std::vector<std::string>& argv,
const file_handle_mapping_vector& fds_to_remap,
@ -268,7 +232,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
fd_shuffle1.reserve(fds_to_remap.size());
fd_shuffle2.reserve(fds_to_remap.size());
#ifdef HAVE_PR_DUPLICATE_ENVIRONMENT
Environment env;
env.Merge(env_vars_to_set);
char * const *envp = env.AsEnvp();
@ -276,7 +239,6 @@ bool LaunchApp(const std::vector<std::string>& argv,
DLOG(ERROR) << "FAILED to duplicate environment for: " << argv_cstr[0];
return false;
}
#endif
pid_t pid = fork();
if (pid < 0)
@ -300,17 +262,10 @@ bool LaunchApp(const std::vector<std::string>& argv,
SetCurrentProcessPrivileges(privs);
#ifdef HAVE_PR_DUPLICATE_ENVIRONMENT
execve(argv_cstr[0], argv_cstr.get(), envp);
#else
for (environment_map::const_iterator it = env_vars_to_set.begin();
it != env_vars_to_set.end(); ++it) {
if (setenv(it->first.c_str(), it->second.c_str(), 1/*overwrite*/))
_exit(127);
}
execv(argv_cstr[0], argv_cstr.get());
#endif
// if we get here, we're in serious trouble and should complain loudly
// NOTE: This is async signal unsafe; it could deadlock instead. (But
// only on debug builds; otherwise it's a signal-safe no-op.)
DLOG(ERROR) << "FAILED TO exec() CHILD PROCESS, path: " << argv_cstr[0];
_exit(127);
} else {

View File

@ -139,47 +139,6 @@ raise(int sig)
return syscall(__NR_tgkill, getpid(), gettid(), sig);
}
/*
* The following wrappers for PR_Xxx are needed until we can get
* PR_DuplicateEnvironment landed in NSPR.
* See see bug 772734 and bug 773414.
*
* We can't #include the pr headers here, and we can't call any of the
* PR/PL functions either, so we just reimplemnt using native code.
*/
static pthread_mutex_t _pr_envLock = PTHREAD_MUTEX_INITIALIZER;
extern "C" NS_EXPORT char*
__wrap_PR_GetEnv(const char *var)
{
char *ev;
pthread_mutex_lock(&_pr_envLock);
ev = getenv(var);
pthread_mutex_unlock(&_pr_envLock);
return ev;
}
extern "C" NS_EXPORT int
__wrap_PR_SetEnv(const char *string)
{
int result;
if ( !strchr(string, '=')) return(-1);
pthread_mutex_lock(&_pr_envLock);
result = putenv(const_cast<char*>(string));
pthread_mutex_unlock(&_pr_envLock);
return (result)? -1 : 0;
}
extern "C" NS_EXPORT pthread_mutex_t *
PR_GetEnvLock(void)
{
return &_pr_envLock;
}
/* Flash plugin uses symbols that are not present in Android >= 4.4 */
#ifndef MOZ_WIDGET_GONK
namespace android {