bug 514188 - fix nsProfileLock to use SA_SIGINFO style signal handler, so it can chain to Breakpad's signal handler properly. r=bsmedberg

--HG--
extra : rebase_source : 4684665d9c32a76ad7fffdf9e305b5b617fca58c
This commit is contained in:
Ted Mielczarek 2009-12-14 06:44:27 -05:00
parent 8a69df66d1
commit 4f3a2496ae
5 changed files with 56 additions and 4 deletions

View File

@ -159,7 +159,8 @@ static struct sigaction SIGABRT_oldact;
static struct sigaction SIGSEGV_oldact;
static struct sigaction SIGTERM_oldact;
void nsProfileLock::FatalSignalHandler(int signo)
void nsProfileLock::FatalSignalHandler(int signo, siginfo_t *info,
void *context)
{
// Remove any locks still held.
RemovePidLockFiles();
@ -211,6 +212,10 @@ void nsProfileLock::FatalSignalHandler(int signo)
raise(signo);
}
else if (oldact->sa_sigaction &&
(oldact->sa_flags & SA_SIGINFO) == SA_SIGINFO) {
oldact->sa_sigaction(signo, info, context);
}
else if (oldact->sa_handler && oldact->sa_handler != SIG_IGN)
{
oldact->sa_handler(signo);
@ -387,8 +392,8 @@ nsresult nsProfileLock::LockWithSymlink(const nsACString& lockFilePath, PRBool a
// because mozilla is run via nohup.
if (!sDisableSignalHandling) {
struct sigaction act, oldact;
act.sa_handler = FatalSignalHandler;
act.sa_flags = 0;
act.sa_sigaction = FatalSignalHandler;
act.sa_flags = SA_SIGINFO;
sigfillset(&act.sa_mask);
#define CATCH_SIGNAL(signame) \

View File

@ -55,6 +55,7 @@ class nsIProfileUnlocker;
#endif
#if defined (XP_UNIX)
#include <signal.h>
#include "prclist.h"
#endif
@ -92,7 +93,8 @@ private:
LHANDLE mLockFileHandle;
#elif defined (XP_UNIX)
static void RemovePidLockFiles();
static void FatalSignalHandler(int signo);
static void FatalSignalHandler(int signo, siginfo_t *info,
void *context);
static PRCList mPidLockList;
nsresult LockWithFcntl(const nsACString& lockFilePath);

View File

@ -1,7 +1,17 @@
#include "nsISupports.idl"
interface nsILocalFile;
[scriptable, uuid(95464a04-6949-46cb-b621-d167790704a0)]
interface nsITestCrasher : nsISupports
{
void crash();
/**
* Lock a directory using XRE_LockProfileDirectory.
*
* @param directory The directory to lock
* @return An opaque lock object.
*/
nsISupports lockDir(in nsILocalFile directory);
};

View File

@ -2,6 +2,7 @@
#include "nsIComponentManager.h"
#include "nsIGenericFactory.h"
#include "nsITestCrasher.h"
#include "nsXULAppAPI.h"
class nsTestCrasher : public nsITestCrasher
{
@ -27,6 +28,13 @@ NS_IMETHODIMP nsTestCrasher::Crash()
return NS_OK;
}
/* nsISupports LockDir (in nsILocalFile directory); */
NS_IMETHODIMP nsTestCrasher::LockDir(nsILocalFile *directory,
nsISupports **_retval NS_OUTPARAM)
{
return XRE_LockProfileDirectory(directory, _retval);
}
// 54afce51-38d7-4df0-9750-2f90f9ffbca2
#define NS_TESTCRASHER_CID \
{ 0x54afce51, 0x38d7, 0x4df0, {0x97, 0x50, 0x2f, 0x90, 0xf9, 0xff, 0xbc, 0xa2} }

View File

@ -0,0 +1,27 @@
function run_test()
{
if (!("@mozilla.org/toolkit/crash-reporter;1" in Components.classes)) {
dump("INFO | test_crashreporter.js | Can't test crashreporter in a non-libxul build.\n");
return;
}
// lock a profile directory, crash, and ensure that
// the profile lock signal handler doesn't interfere with
// writing a minidump
do_crash(function() {
let env = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
// the python harness sets this in the environment for us
let profd = env.get("XPCSHELL_TEST_PROFILE_DIR");
let dir = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
dir.initWithPath(profd);
let mycrasher = Components.classes["@mozilla.org/testcrasher;1"].createInstance(Components.interfaces.nsITestCrasher);
let lock = mycrasher.lockDir(dir);
// when we crash, the lock file should be cleaned up
},
function(mdump, extra) {
// if we got here, we have a minidump, so that's all we wanted
do_check_true(true);
});
}