# HG changeset patch # User Ehsan Akhgari # Date 1547802978 -3600 # Node ID 5f4630838d46dd81dadb13220a4af0da9e23a619 # Parent ff49c0e13e461805bcb14537113b3ed3b5ff0119 Bug 1521000 - Part 2: Adjust our clang-format rules to include spaces after the hash for nested preprocessor directives r=sylvestre # ignore-this-changeset diff --git a/toolkit/crashreporter/LoadLibraryRemote.cpp b/toolkit/crashreporter/LoadLibraryRemote.cpp --- a/toolkit/crashreporter/LoadLibraryRemote.cpp +++ b/toolkit/crashreporter/LoadLibraryRemote.cpp @@ -1,28 +1,28 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef __GNUC__ // disable warnings about pointer <-> DWORD conversions -#pragma warning(disable : 4311 4312) +# pragma warning(disable : 4311 4312) #endif #ifdef _WIN64 -#define POINTER_TYPE ULONGLONG +# define POINTER_TYPE ULONGLONG #else -#define POINTER_TYPE DWORD +# define POINTER_TYPE DWORD #endif #include #include #include #ifdef DEBUG_OUTPUT -#include +# include #endif #include "nsWindowsHelpers.h" typedef const unsigned char *FileView; template <> class nsAutoRefTraits { @@ -32,17 +32,17 @@ class nsAutoRefTraits { static void Release(RawRef aView) { if (nullptr != aView) UnmapViewOfFile(aView); } }; #ifndef IMAGE_SIZEOF_BASE_RELOCATION // Vista SDKs no longer define IMAGE_SIZEOF_BASE_RELOCATION!? -#define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION)) +# define IMAGE_SIZEOF_BASE_RELOCATION (sizeof(IMAGE_BASE_RELOCATION)) #endif #include "LoadLibraryRemote.h" typedef struct { PIMAGE_NT_HEADERS headers; unsigned char *localCodeBase; unsigned char *remoteCodeBase; diff --git a/toolkit/crashreporter/client/crashreporter.cpp b/toolkit/crashreporter/client/crashreporter.cpp --- a/toolkit/crashreporter/client/crashreporter.cpp +++ b/toolkit/crashreporter/client/crashreporter.cpp @@ -2,30 +2,30 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "crashreporter.h" #ifdef _MSC_VER // Disable exception handler warnings. -#pragma warning(disable : 4530) +# pragma warning(disable : 4530) #endif #include #include #include #include #include #include #include #include #ifdef XP_LINUX -#include +# include #endif #include "nss.h" #include "sechash.h" using std::auto_ptr; using std::ifstream; using std::istream; @@ -399,20 +399,20 @@ void SendCompleted(bool success, const s } static string ComputeDumpHash() { #ifdef XP_LINUX // On Linux we rely on the system-provided libcurl which uses nss so we have // to also use the system-provided nss instead of the ones we have bundled. const char* libnssNames[] = { "libnss3.so", -#ifndef HAVE_64BIT_BUILD +# ifndef HAVE_64BIT_BUILD // 32-bit versions on 64-bit hosts "/usr/lib32/libnss3.so", -#endif +# endif }; void* lib = nullptr; for (const char* libname : libnssNames) { lib = dlopen(libname, RTLD_NOW); if (lib) { break; @@ -763,17 +763,17 @@ int main(int argc, char** argv) { } UIShutdown(); return 0; } #if defined(XP_WIN) && !defined(__GNUC__) -#include +# include // We need WinMain in order to not be a console app. This function is unused // if we are a console application. int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR args, int) { // Remove everything except close window from the context menu { HKEY hkApp; RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\Classes\\Applications", 0, diff --git a/toolkit/crashreporter/client/crashreporter.h b/toolkit/crashreporter/client/crashreporter.h --- a/toolkit/crashreporter/client/crashreporter.h +++ b/toolkit/crashreporter/client/crashreporter.h @@ -1,44 +1,44 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef CRASHREPORTER_H__ #define CRASHREPORTER_H__ #ifdef _MSC_VER -#pragma warning(push) +# pragma warning(push) // Disable exception handler warnings. -#pragma warning(disable : 4530) +# pragma warning(disable : 4530) #endif #include #include #include #include #include #include #include #define MAX_COMMENT_LENGTH 500 #if defined(XP_WIN32) -#include +# include -#define UI_SNPRINTF _snprintf -#define UI_DIR_SEPARATOR "\\" +# define UI_SNPRINTF _snprintf +# define UI_DIR_SEPARATOR "\\" std::string WideToUTF8(const std::wstring& wide, bool* success = 0); #else -#define UI_SNPRINTF snprintf -#define UI_DIR_SEPARATOR "/" +# define UI_SNPRINTF snprintf +# define UI_DIR_SEPARATOR "/" #endif #define UI_CRASH_REPORTER_FILENAME "crashreporter" #define UI_MINIDUMP_ANALYZER_FILENAME "minidump-analyzer" typedef std::map StringTable; @@ -145,12 +145,12 @@ void UIPruneSavedDumps(const std::string // otherwise. bool UIRunProgram(const std::string& exename, const std::vector& args, bool wait = false); // Read the environment variable specified by name std::string UIGetEnv(const std::string& name); #ifdef _MSC_VER -#pragma warning(pop) +# pragma warning(pop) #endif #endif diff --git a/toolkit/crashreporter/client/crashreporter_gtk_common.cpp b/toolkit/crashreporter/client/crashreporter_gtk_common.cpp --- a/toolkit/crashreporter/client/crashreporter_gtk_common.cpp +++ b/toolkit/crashreporter/client/crashreporter_gtk_common.cpp @@ -23,17 +23,17 @@ #include #include #include "common/linux/http_upload.h" #include "crashreporter.h" #include "crashreporter_gtk_common.h" #ifndef GDK_KEY_Escape -#define GDK_KEY_Escape GDK_Escape +# define GDK_KEY_Escape GDK_Escape #endif using std::string; using std::vector; using namespace CrashReporter; GtkWidget* gWindow = 0; @@ -103,17 +103,17 @@ static gboolean ReportCompleted(gpointer string str = success ? gStrings[ST_REPORTSUBMITSUCCESS] : gStrings[ST_SUBMITFAILED]; gtk_label_set_text(GTK_LABEL(gProgressLabel), str.c_str()); g_timeout_add(5000, CloseApp, 0); return FALSE; } #ifdef MOZ_ENABLE_GCONF -#define HTTP_PROXY_DIR "/system/http_proxy" +# define HTTP_PROXY_DIR "/system/http_proxy" void LoadProxyinfo() { class GConfClient; typedef GConfClient* (*_gconf_default_fn)(); typedef gboolean (*_gconf_bool_fn)(GConfClient*, const gchar*, GError**); typedef gint (*_gconf_int_fn)(GConfClient*, const gchar*, GError**); typedef gchar* (*_gconf_string_fn)(GConfClient*, const gchar*, GError**); diff --git a/toolkit/crashreporter/client/crashreporter_win.cpp b/toolkit/crashreporter/client/crashreporter_win.cpp --- a/toolkit/crashreporter/client/crashreporter_win.cpp +++ b/toolkit/crashreporter/client/crashreporter_win.cpp @@ -1,15 +1,15 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifdef WIN32_LEAN_AND_MEAN -#undef WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN #endif #include "crashreporter.h" #include #include #include #include diff --git a/toolkit/crashreporter/client/resource.h b/toolkit/crashreporter/client/resource.h --- a/toolkit/crashreporter/client/resource.h +++ b/toolkit/crashreporter/client/resource.h @@ -23,15 +23,15 @@ #define IDC_DESCRIPTIONLABEL 1013 #define IDC_PROGRESSTEXT 1014 #define IDC_THROBBER 1015 #define IDC_VIEWREPORTTEXT 1016 // Next default values for new objects // #ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 106 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1017 -#define _APS_NEXT_SYMED_VALUE 101 +# ifndef APSTUDIO_READONLY_SYMBOLS +# define _APS_NEXT_RESOURCE_VALUE 106 +# define _APS_NEXT_COMMAND_VALUE 40001 +# define _APS_NEXT_CONTROL_VALUE 1017 +# define _APS_NEXT_SYMED_VALUE 101 +# endif #endif -#endif diff --git a/toolkit/crashreporter/minidump-analyzer/MinidumpAnalyzerUtils.h b/toolkit/crashreporter/minidump-analyzer/MinidumpAnalyzerUtils.h --- a/toolkit/crashreporter/minidump-analyzer/MinidumpAnalyzerUtils.h +++ b/toolkit/crashreporter/minidump-analyzer/MinidumpAnalyzerUtils.h @@ -2,17 +2,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MinidumpAnalyzerUtils_h #define MinidumpAnalyzerUtils_h #ifdef XP_WIN -#include +# include #endif #include #include #include #include namespace CrashReporter { diff --git a/toolkit/crashreporter/minidump-analyzer/MozStackFrameSymbolizer.cpp b/toolkit/crashreporter/minidump-analyzer/MozStackFrameSymbolizer.cpp --- a/toolkit/crashreporter/minidump-analyzer/MozStackFrameSymbolizer.cpp +++ b/toolkit/crashreporter/minidump-analyzer/MozStackFrameSymbolizer.cpp @@ -1,24 +1,24 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #if XP_WIN && HAVE_64BIT_BUILD -#include "MozStackFrameSymbolizer.h" +# include "MozStackFrameSymbolizer.h" -#include "MinidumpAnalyzerUtils.h" +# include "MinidumpAnalyzerUtils.h" -#include "processor/cfi_frame_info.h" +# include "processor/cfi_frame_info.h" -#include -#include -#include +# include +# include +# include namespace CrashReporter { extern MinidumpAnalyzerOptions gMinidumpAnalyzerOptions; using google_breakpad::CFIFrameInfo; MozStackFrameSymbolizer::MozStackFrameSymbolizer() diff --git a/toolkit/crashreporter/minidump-analyzer/MozStackFrameSymbolizer.h b/toolkit/crashreporter/minidump-analyzer/MozStackFrameSymbolizer.h --- a/toolkit/crashreporter/minidump-analyzer/MozStackFrameSymbolizer.h +++ b/toolkit/crashreporter/minidump-analyzer/MozStackFrameSymbolizer.h @@ -3,22 +3,22 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MozStackFrameSymbolizer_h #define MozStackFrameSymbolizer_h #if XP_WIN && HAVE_64BIT_BUILD -#include "Win64ModuleUnwindMetadata.h" +# include "Win64ModuleUnwindMetadata.h" -#include "google_breakpad/processor/stack_frame_symbolizer.h" -#include "google_breakpad/processor/stack_frame.h" +# include "google_breakpad/processor/stack_frame_symbolizer.h" +# include "google_breakpad/processor/stack_frame.h" -#include +# include namespace CrashReporter { using google_breakpad::CodeModule; using google_breakpad::CodeModules; using google_breakpad::SourceLineResolverInterface; using google_breakpad::StackFrame; using google_breakpad::StackFrameSymbolizer; diff --git a/toolkit/crashreporter/minidump-analyzer/Win64ModuleUnwindMetadata.cpp b/toolkit/crashreporter/minidump-analyzer/Win64ModuleUnwindMetadata.cpp --- a/toolkit/crashreporter/minidump-analyzer/Win64ModuleUnwindMetadata.cpp +++ b/toolkit/crashreporter/minidump-analyzer/Win64ModuleUnwindMetadata.cpp @@ -1,26 +1,26 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #if XP_WIN && HAVE_64BIT_BUILD -#include "Win64ModuleUnwindMetadata.h" +# include "Win64ModuleUnwindMetadata.h" -#include "MinidumpAnalyzerUtils.h" +# include "MinidumpAnalyzerUtils.h" -#include -#include -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include +# include +# include namespace CrashReporter { union UnwindCode { struct { uint8_t offset_in_prolog; uint8_t unwind_operation_code : 4; uint8_t operation_info : 4; diff --git a/toolkit/crashreporter/minidump-analyzer/Win64ModuleUnwindMetadata.h b/toolkit/crashreporter/minidump-analyzer/Win64ModuleUnwindMetadata.h --- a/toolkit/crashreporter/minidump-analyzer/Win64ModuleUnwindMetadata.h +++ b/toolkit/crashreporter/minidump-analyzer/Win64ModuleUnwindMetadata.h @@ -3,23 +3,23 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef Win64ModuleUnwindMetadata_h #define Win64ModuleUnwindMetadata_h #if XP_WIN && HAVE_64BIT_BUILD -#include -#include -#include +# include +# include +# include -#include -#include -#include +# include +# include +# include namespace CrashReporter { struct UnwindCFI { uint32_t beginAddress; uint32_t size; uint32_t stackSize; uint32_t ripOffset; diff --git a/toolkit/crashreporter/minidump-analyzer/minidump-analyzer.cpp b/toolkit/crashreporter/minidump-analyzer/minidump-analyzer.cpp --- a/toolkit/crashreporter/minidump-analyzer/minidump-analyzer.cpp +++ b/toolkit/crashreporter/minidump-analyzer/minidump-analyzer.cpp @@ -21,31 +21,31 @@ #include "google_breakpad/processor/stack_frame.h" #include "processor/pathname_stripper.h" #include "mozilla/FStream.h" #include "mozilla/Unused.h" #if defined(XP_WIN32) -#include -#include "mozilla/glue/WindowsDllServices.h" +# include +# include "mozilla/glue/WindowsDllServices.h" #elif defined(XP_UNIX) || defined(XP_MACOSX) -#include -#include -#include +# include +# include +# include #endif #include "MinidumpAnalyzerUtils.h" #if XP_WIN && HAVE_64BIT_BUILD && defined(_M_X64) -#include "MozStackFrameSymbolizer.h" +# include "MozStackFrameSymbolizer.h" #endif namespace CrashReporter { #if defined(XP_WIN) static mozilla::glue::BasicDllServices gDllServices; @@ -413,19 +413,19 @@ bool GenerateStacks(const string& aDumpP return UpdateExtraDataFile(aDumpPath, stackTraces, certSubjects); } } // namespace CrashReporter using namespace CrashReporter; #if defined(XP_WIN) -#define XP_LITERAL(s) L##s +# define XP_LITERAL(s) L##s #else -#define XP_LITERAL(s) s +# define XP_LITERAL(s) s #endif template struct CharTraits; template <> struct CharTraits { static int compare(const char* left, const char* right) { diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp b/toolkit/crashreporter/nsExceptionHandler.cpp --- a/toolkit/crashreporter/nsExceptionHandler.cpp +++ b/toolkit/crashreporter/nsExceptionHandler.cpp @@ -25,64 +25,64 @@ #include "nsThreadUtils.h" #include "nsXULAppAPI.h" #include "jsfriendapi.h" #include "ThreadAnnotation.h" #include "private/pprio.h" #if defined(XP_WIN32) -#ifdef WIN32_LEAN_AND_MEAN -#undef WIN32_LEAN_AND_MEAN -#endif - -#include "nsXULAppAPI.h" -#include "nsIXULAppInfo.h" -#include "nsIWindowsRegKey.h" -#include "breakpad-client/windows/crash_generation/client_info.h" -#include "breakpad-client/windows/crash_generation/crash_generation_server.h" -#include "breakpad-client/windows/handler/exception_handler.h" -#include -#include -#include "nsDirectoryServiceUtils.h" - -#include "nsWindowsDllInterceptor.h" -#include "mozilla/WindowsVersion.h" +# ifdef WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN +# endif + +# include "nsXULAppAPI.h" +# include "nsIXULAppInfo.h" +# include "nsIWindowsRegKey.h" +# include "breakpad-client/windows/crash_generation/client_info.h" +# include "breakpad-client/windows/crash_generation/crash_generation_server.h" +# include "breakpad-client/windows/handler/exception_handler.h" +# include +# include +# include "nsDirectoryServiceUtils.h" + +# include "nsWindowsDllInterceptor.h" +# include "mozilla/WindowsVersion.h" #elif defined(XP_MACOSX) -#include "breakpad-client/mac/crash_generation/client_info.h" -#include "breakpad-client/mac/crash_generation/crash_generation_server.h" -#include "breakpad-client/mac/handler/exception_handler.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "mac_utils.h" +# include "breakpad-client/mac/crash_generation/client_info.h" +# include "breakpad-client/mac/crash_generation/crash_generation_server.h" +# include "breakpad-client/mac/handler/exception_handler.h" +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include "mac_utils.h" #elif defined(XP_LINUX) -#include "nsIINIParser.h" -#include "common/linux/linux_libc_support.h" -#include "third_party/lss/linux_syscall_support.h" -#include "breakpad-client/linux/crash_generation/client_info.h" -#include "breakpad-client/linux/crash_generation/crash_generation_server.h" -#include "breakpad-client/linux/handler/exception_handler.h" -#include "common/linux/eintr_wrapper.h" -#include -#include -#include -#include +# include "nsIINIParser.h" +# include "common/linux/linux_libc_support.h" +# include "third_party/lss/linux_syscall_support.h" +# include "breakpad-client/linux/crash_generation/client_info.h" +# include "breakpad-client/linux/crash_generation/crash_generation_server.h" +# include "breakpad-client/linux/handler/exception_handler.h" +# include "common/linux/eintr_wrapper.h" +# include +# include +# include +# include #else -#error "Not yet implemented for this platform" +# error "Not yet implemented for this platform" #endif // defined(XP_WIN32) #ifdef MOZ_CRASHREPORTER_INJECTOR -#include "InjectCrashReporter.h" +# include "InjectCrashReporter.h" using mozilla::InjectCrashRunnable; #endif #include #include #include #include #include "mozilla/Mutex.h" @@ -95,17 +95,17 @@ using mozilla::InjectCrashRunnable; #include "mozilla/IOInterposer.h" #include "mozilla/mozalloc_oom.h" #include "mozilla/WindowsDllBlocklist.h" #if defined(XP_MACOSX) CFStringRef reporterClientAppID = CFSTR("org.mozilla.crashreporter"); #endif #if defined(MOZ_WIDGET_ANDROID) -#include "common/linux/file_id.h" +# include "common/linux/file_id.h" #endif using google_breakpad::ClientInfo; using google_breakpad::CrashGenerationServer; #ifdef XP_LINUX using google_breakpad::MinidumpDescriptor; #endif #if defined(MOZ_WIDGET_ANDROID) @@ -117,66 +117,68 @@ using google_breakpad::PageAllocator; using namespace mozilla; using mozilla::ipc::CrashReporterClient; namespace CrashReporter { #ifdef XP_WIN32 typedef wchar_t XP_CHAR; typedef std::wstring xpstring; -#define XP_TEXT(x) L##x -#define CONVERT_XP_CHAR_TO_UTF16(x) x -#define XP_STRLEN(x) wcslen(x) -#define my_strlen strlen -#define CRASH_REPORTER_FILENAME "crashreporter.exe" -#define MINIDUMP_ANALYZER_FILENAME "minidump-analyzer.exe" -#define PATH_SEPARATOR "\\" -#define XP_PATH_SEPARATOR L"\\" -#define XP_PATH_SEPARATOR_CHAR L'\\' -#define XP_PATH_MAX (MAX_PATH + 1) +# define XP_TEXT(x) L##x +# define CONVERT_XP_CHAR_TO_UTF16(x) x +# define XP_STRLEN(x) wcslen(x) +# define my_strlen strlen +# define CRASH_REPORTER_FILENAME "crashreporter.exe" +# define MINIDUMP_ANALYZER_FILENAME "minidump-analyzer.exe" +# define PATH_SEPARATOR "\\" +# define XP_PATH_SEPARATOR L"\\" +# define XP_PATH_SEPARATOR_CHAR L'\\' +# define XP_PATH_MAX (MAX_PATH + 1) // "" "" -#define CMDLINE_SIZE ((XP_PATH_MAX * 2) + 6) -#ifdef _USE_32BIT_TIME_T -#define XP_TTOA(time, buffer, base) ltoa(time, buffer, base) -#else -#define XP_TTOA(time, buffer, base) _i64toa(time, buffer, base) -#endif -#define XP_STOA(size, buffer, base) _ui64toa(size, buffer, base) +# define CMDLINE_SIZE ((XP_PATH_MAX * 2) + 6) +# ifdef _USE_32BIT_TIME_T +# define XP_TTOA(time, buffer, base) ltoa(time, buffer, base) +# else +# define XP_TTOA(time, buffer, base) _i64toa(time, buffer, base) +# endif +# define XP_STOA(size, buffer, base) _ui64toa(size, buffer, base) #else typedef char XP_CHAR; typedef std::string xpstring; -#define XP_TEXT(x) x -#define CONVERT_XP_CHAR_TO_UTF16(x) NS_ConvertUTF8toUTF16(x) -#define CRASH_REPORTER_FILENAME "crashreporter" -#define MINIDUMP_ANALYZER_FILENAME "minidump-analyzer" -#define PATH_SEPARATOR "/" -#define XP_PATH_SEPARATOR "/" -#define XP_PATH_SEPARATOR_CHAR '/' -#define XP_PATH_MAX PATH_MAX -#ifdef XP_LINUX -#define XP_STRLEN(x) my_strlen(x) -#define XP_TTOA(time, buffer, base) my_inttostring(time, buffer, sizeof(buffer)) -#define XP_STOA(size, buffer, base) my_inttostring(size, buffer, sizeof(buffer)) -#else -#define XP_STRLEN(x) strlen(x) -#define XP_TTOA(time, buffer, base) sprintf(buffer, "%ld", time) -#define XP_STOA(size, buffer, base) sprintf(buffer, "%zu", (size_t)size) -#define my_strlen strlen -#define sys_close close -#define sys_fork fork -#define sys_open open -#define sys_read read -#define sys_write write -#endif +# define XP_TEXT(x) x +# define CONVERT_XP_CHAR_TO_UTF16(x) NS_ConvertUTF8toUTF16(x) +# define CRASH_REPORTER_FILENAME "crashreporter" +# define MINIDUMP_ANALYZER_FILENAME "minidump-analyzer" +# define PATH_SEPARATOR "/" +# define XP_PATH_SEPARATOR "/" +# define XP_PATH_SEPARATOR_CHAR '/' +# define XP_PATH_MAX PATH_MAX +# ifdef XP_LINUX +# define XP_STRLEN(x) my_strlen(x) +# define XP_TTOA(time, buffer, base) \ + my_inttostring(time, buffer, sizeof(buffer)) +# define XP_STOA(size, buffer, base) \ + my_inttostring(size, buffer, sizeof(buffer)) +# else +# define XP_STRLEN(x) strlen(x) +# define XP_TTOA(time, buffer, base) sprintf(buffer, "%ld", time) +# define XP_STOA(size, buffer, base) sprintf(buffer, "%zu", (size_t)size) +# define my_strlen strlen +# define sys_close close +# define sys_fork fork +# define sys_open open +# define sys_read read +# define sys_write write +# endif #endif // XP_WIN32 #if defined(__GNUC__) -#define MAYBE_UNUSED __attribute__((unused)) +# define MAYBE_UNUSED __attribute__((unused)) #else -#define MAYBE_UNUSED +# define MAYBE_UNUSED #endif // defined(__GNUC__) #ifndef XP_LINUX static const XP_CHAR dumpFileExtension[] = XP_TEXT(".dmp"); #endif static const XP_CHAR childCrashAnnotationBaseName[] = XP_TEXT("GeckoChildCrash"); @@ -247,22 +249,22 @@ static std::terminate_handler oldTermina // child process and don't attempt to connect to a parent server. static const char kNullNotifyPipe[] = "-"; static char* childCrashNotifyPipe; #elif defined(XP_LINUX) static int serverSocketFd = -1; static int clientSocketFd = -1; static int gMagicChildCrashReportFd = -#if defined(MOZ_WIDGET_ANDROID) +# if defined(MOZ_WIDGET_ANDROID) // On android the fd is set at the time of child creation. -1 -#else +# else 4 -#endif // defined(MOZ_WIDGET_ANDROID) +# endif // defined(MOZ_WIDGET_ANDROID) ; #endif #if defined(MOZ_WIDGET_ANDROID) static int gChildCrashAnnotationReportFd = -1; #endif // |dumpMapLock| must protect all access to |pidToMinidump|. @@ -345,31 +347,31 @@ static LPTOP_LEVEL_EXCEPTION_FILTER WINA stub_SetUnhandledExceptionFilter(lpTopLevelExceptionFilter); return previousUnhandledExceptionFilter; } // intercept attempts to change the filter return nullptr; } -#if defined(HAVE_64BIT_BUILD) && defined(_M_X64) +# if defined(HAVE_64BIT_BUILD) && defined(_M_X64) static LPTOP_LEVEL_EXCEPTION_FILTER sUnhandledExceptionFilter = nullptr; static long JitExceptionHandler(void *exceptionRecord, void *context) { EXCEPTION_POINTERS pointers = {(PEXCEPTION_RECORD)exceptionRecord, (PCONTEXT)context}; return sUnhandledExceptionFilter(&pointers); } static void SetJitExceptionHandler() { sUnhandledExceptionFilter = GetUnhandledExceptionFilter(); if (sUnhandledExceptionFilter) js::SetJitExceptionHandler(JitExceptionHandler); } -#endif +# endif /** * Reserve some VM space. In the event that we crash because VM space is * being leaked without leaking memory, freeing this space before taking * the minidump will allow us to collect a minidump. * * This size is bigger than xul.dll plus some extra for MinidumpWriteDump * allocations. @@ -586,17 +588,17 @@ class PlatformWriter { Unused << sys_write(mFD, buffer, len); } private: int mFD; }; #else -#error "Need implementation of PlatformWrite for this platform" +# error "Need implementation of PlatformWrite for this platform" #endif template static void WriteLiteral(PlatformWriter& pw, const char (&str)[N]) { pw.WriteBuffer(str, N - 1); } static void WriteString(PlatformWriter& pw, const char* str) { @@ -650,56 +652,56 @@ static void OpenAPIData(PlatformWriter& static void WriteGlobalMemoryStatus(PlatformWriter* apiData, PlatformWriter* eventFile) { char buffer[128]; // Try to get some information about memory. MEMORYSTATUSEX statex; statex.dwLength = sizeof(statex); if (GlobalMemoryStatusEx(&statex)) { -#define WRITE_STATEX_FIELD(field, name, conversionFunc) \ - conversionFunc(statex.field, buffer, 10); \ - if (apiData) { \ - WriteAnnotation(*apiData, name, buffer); \ - } \ - if (eventFile) { \ - WriteAnnotation(*eventFile, name, buffer); \ - } +# define WRITE_STATEX_FIELD(field, name, conversionFunc) \ + conversionFunc(statex.field, buffer, 10); \ + if (apiData) { \ + WriteAnnotation(*apiData, name, buffer); \ + } \ + if (eventFile) { \ + WriteAnnotation(*eventFile, name, buffer); \ + } WRITE_STATEX_FIELD(dwMemoryLoad, Annotation::SystemMemoryUsePercentage, ltoa); WRITE_STATEX_FIELD(ullTotalVirtual, Annotation::TotalVirtualMemory, _ui64toa); WRITE_STATEX_FIELD(ullAvailVirtual, Annotation::AvailableVirtualMemory, _ui64toa); WRITE_STATEX_FIELD(ullTotalPageFile, Annotation::TotalPageFile, _ui64toa); WRITE_STATEX_FIELD(ullAvailPageFile, Annotation::AvailablePageFile, _ui64toa); WRITE_STATEX_FIELD(ullTotalPhys, Annotation::TotalPhysicalMemory, _ui64toa); WRITE_STATEX_FIELD(ullAvailPhys, Annotation::AvailablePhysicalMemory, _ui64toa); -#undef WRITE_STATEX_FIELD +# undef WRITE_STATEX_FIELD } } #endif #if !defined(MOZ_WIDGET_ANDROID) /** * Launches the program specified in aProgramPath with aMinidumpPath as its * sole argument. * * @param aProgramPath The path of the program to be launched * @param aMinidumpPath The path of the minidump file, passed as an argument * to the launched program */ static bool LaunchProgram(const XP_CHAR* aProgramPath, const XP_CHAR* aMinidumpPath) { -#ifdef XP_WIN +# ifdef XP_WIN XP_CHAR cmdLine[CMDLINE_SIZE]; XP_CHAR* p; size_t size = CMDLINE_SIZE; p = Concat(cmdLine, L"\"", &size); p = Concat(p, aProgramPath, &size); p = Concat(p, L"\" \"", &size); p = Concat(p, aMinidumpPath, &size); @@ -711,17 +713,17 @@ static bool LaunchProgram(const XP_CHAR* // If CreateProcess() fails don't do anything if (CreateProcess(nullptr, (LPWSTR)cmdLine, nullptr, nullptr, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi)) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } -#elif defined(XP_MACOSX) +# elif defined(XP_MACOSX) // Needed to locate NSS and its dependencies setenv("DYLD_LIBRARY_PATH", libraryPath, /* overwrite */ 1); pid_t pid = 0; char* const my_argv[] = {const_cast(aProgramPath), const_cast(aMinidumpPath), nullptr}; char** env = nullptr; @@ -730,30 +732,30 @@ static bool LaunchProgram(const XP_CHAR* env = *nsEnv; } int rv = posix_spawnp(&pid, my_argv[0], nullptr, nullptr, my_argv, env); if (rv != 0) { return false; } -#else // !XP_MACOSX +# else // !XP_MACOSX pid_t pid = sys_fork(); if (pid == -1) { return false; } else if (pid == 0) { // need to clobber this, as libcurl might load NSS, // and we want it to load the system NSS. unsetenv("LD_LIBRARY_PATH"); Unused << execl(aProgramPath, aProgramPath, aMinidumpPath, nullptr); _exit(1); } -#endif // XP_MACOSX +# endif // XP_MACOSX return true; } #else /** * Launch the crash reporter activity on Android @@ -1009,22 +1011,22 @@ static bool MinidumpCallback( #ifdef XP_WIN if (gBreakpadReservedVM) { _ui64toa(uintptr_t(gBreakpadReservedVM), buffer, 10); WriteAnnotation(apiData, Annotation::BreakpadReserveAddress, buffer); _ui64toa(kReserveSize, buffer, 10); WriteAnnotation(apiData, Annotation::BreakpadReserveSize, buffer); } -#ifdef HAS_DLL_BLOCKLIST +# ifdef HAS_DLL_BLOCKLIST if (apiData.Valid()) { DllBlocklist_WriteNotes(apiData.Handle()); DllBlocklist_WriteNotes(eventFile.Handle()); } -#endif +# endif WriteGlobalMemoryStatus(&apiData, &eventFile); #endif // XP_WIN WriteEscapedMozCrashReason(apiData); WriteEscapedMozCrashReason(eventFile); if (oomAllocationSizeBuffer[0]) { WriteAnnotation(apiData, Annotation::OOMAllocationSize, @@ -1060,19 +1062,19 @@ static bool MinidumpCallback( return returnValue; } #if defined(MOZ_WIDGET_ANDROID) // Android returnValue = LaunchCrashReporterActivity(crashReporterPath, minidumpPath, succeeded); #else // Windows, Mac, Linux, etc... returnValue = LaunchProgram(crashReporterPath, minidumpPath); -#ifdef XP_WIN +# ifdef XP_WIN TerminateProcess(GetCurrentProcess(), 1); -#endif +# endif #endif return returnValue; } #if defined(XP_MACOSX) || defined(__ANDROID__) || defined(XP_LINUX) static size_t EnsureTrailingSlash(XP_CHAR* aBuf, size_t aBufLen) { size_t len = XP_STRLEN(aBuf); @@ -1146,17 +1148,17 @@ static size_t BuildTempPath(char* aBuf, tempenv = tmpPath; } size_t size = aBufLen; Concat(aBuf, tempenv, &size); return EnsureTrailingSlash(aBuf, aBufLen); } #else -#error "Implement this for your platform" +# error "Implement this for your platform" #endif template static size_t BuildTempPath(CharT (&aBuf)[N]) { static_assert(N >= XP_PATH_MAX, "char array length is too small"); return BuildTempPath(&aBuf[0], N); } @@ -1219,17 +1221,17 @@ static void ReserveBreakpadVM() { } static void FreeBreakpadVM() { if (gBreakpadReservedVM) { VirtualFree(gBreakpadReservedVM, 0, MEM_RELEASE); } } -#if defined(XP_WIN) +# if defined(XP_WIN) /** * Filters out floating point exceptions which are handled by nsSigHandlers.cpp * and should not be handled as crashes. * * Also calls FreeBreakpadVM if appropriate. */ static bool FPEFilter(void* context, EXCEPTION_POINTERS* exinfo, @@ -1262,38 +1264,38 @@ static bool ChildFPEFilter(void* context MDRawAssertionInfo* assertion) { bool result = FPEFilter(context, exinfo, assertion); if (result) { PrepareChildExceptionTimeAnnotations(context); } return result; } -#endif // defined(XP_WIN) +# endif // defined(XP_WIN) static MINIDUMP_TYPE GetMinidumpType() { MINIDUMP_TYPE minidump_type = static_cast( MiniDumpWithFullMemoryInfo | MiniDumpWithUnloadedModules); -#ifdef NIGHTLY_BUILD +# ifdef NIGHTLY_BUILD // This is Nightly only because this doubles the size of minidumps based // on the experimental data. minidump_type = static_cast(minidump_type | MiniDumpWithProcessThreadData); // dbghelp.dll on Win7 can't handle overlapping memory regions so we only // enable this feature on Win8 or later. if (IsWin8OrLater()) { minidump_type = static_cast( minidump_type | // This allows us to examine heap objects referenced from stack objects // at the cost of further doubling the size of minidumps. MiniDumpWithIndirectlyReferencedMemory); } -#endif +# endif const char* e = PR_GetEnv("MOZ_CRASHREPORTER_FULLDUMP"); if (e && *e) { minidump_type = MiniDumpWithFullMemory; } return minidump_type; } @@ -1342,22 +1344,22 @@ static void TerminateHandler() { // Locate the specified executable and store its path as a native string in // the |aPathPtr| so we can later invoke it from within the exception handler. static nsresult LocateExecutable(nsIFile* aXREDirectory, const nsACString& aName, nsAString& aPath) { nsCOMPtr exePath; nsresult rv = aXREDirectory->Clone(getter_AddRefs(exePath)); NS_ENSURE_SUCCESS(rv, rv); -#ifdef XP_MACOSX +# ifdef XP_MACOSX exePath->SetNativeLeafName(NS_LITERAL_CSTRING("MacOS")); exePath->Append(NS_LITERAL_STRING("crashreporter.app")); exePath->Append(NS_LITERAL_STRING("Contents")); exePath->Append(NS_LITERAL_STRING("MacOS")); -#endif +# endif exePath->AppendNative(aName); exePath->GetPath(aPath); return NS_OK; } #endif // !defined(MOZ_WIDGET_ANDROID) @@ -1401,39 +1403,39 @@ nsresult SetExceptionHandler(nsIFile* aX nsAutoString crashReporterPath_temp; nsresult rv = LocateExecutable(aXREDirectory, NS_LITERAL_CSTRING(CRASH_REPORTER_FILENAME), crashReporterPath_temp); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } -#ifdef XP_MACOSX +# ifdef XP_MACOSX nsCOMPtr libPath; rv = aXREDirectory->Clone(getter_AddRefs(libPath)); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } nsAutoString libraryPath_temp; rv = libPath->GetPath(libraryPath_temp); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } -#endif // XP_MACOSX - -#ifdef XP_WIN32 +# endif // XP_MACOSX + +# ifdef XP_WIN32 crashReporterPath = reinterpret_cast(ToNewUnicode(crashReporterPath_temp)); -#else +# else crashReporterPath = ToNewCString(crashReporterPath_temp); -#ifdef XP_MACOSX +# ifdef XP_MACOSX libraryPath = ToNewCString(libraryPath_temp); -#endif -#endif // XP_WIN32 +# endif +# endif // XP_WIN32 #else // On Android, we launch using the application package name instead of a // filename, so use the dynamically set MOZ_ANDROID_PACKAGE_NAME, or fall // back to the static ANDROID_PACKAGE_NAME. const char* androidPackageName = PR_GetEnv("MOZ_ANDROID_PACKAGE_NAME"); if (androidPackageName != nullptr) { nsCString package(androidPackageName); package.AppendLiteral("/org.mozilla.gecko.CrashReporterService"); @@ -1499,53 +1501,53 @@ nsresult SetExceptionHandler(nsIFile* aX Filter, #endif MinidumpCallback, nullptr, #ifdef XP_WIN32 google_breakpad::ExceptionHandler::HANDLER_ALL, GetMinidumpType(), (const wchar_t*) nullptr, nullptr); #else true -#ifdef XP_MACOSX +# ifdef XP_MACOSX , nullptr -#endif -#ifdef XP_LINUX +# endif +# ifdef XP_LINUX , -1 -#endif +# endif ); #endif // XP_WIN32 if (!gExceptionHandler) return NS_ERROR_OUT_OF_MEMORY; #ifdef XP_WIN gExceptionHandler->set_handle_debug_exceptions(true); // Initially set sIncludeContextHeap to true for debugging startup crashes // even if the controlling pref value is false. SetIncludeContextHeap(true); -#if defined(HAVE_64BIT_BUILD) && defined(_M_X64) +# if defined(HAVE_64BIT_BUILD) && defined(_M_X64) // Tell JS about the new filter before we disable SetUnhandledExceptionFilter SetJitExceptionHandler(); -#endif +# endif // protect the crash reporter from being unloaded gBlockUnhandledExceptionFilter = true; gKernel32Intercept.Init("kernel32.dll"); DebugOnly ok = stub_SetUnhandledExceptionFilter.Set( gKernel32Intercept, "SetUnhandledExceptionFilter", &patched_SetUnhandledExceptionFilter); -#ifdef DEBUG +# ifdef DEBUG if (!ok) printf_stderr( "SetUnhandledExceptionFilter hook failed; crash reporter is " "vulnerable.\n"); -#endif +# endif #endif // store application start time char timeString[32]; time_t startupTime = time(nullptr); XP_TTOA(startupTime, timeString, 10); AnnotateCrashReport(Annotation::StartupTime, nsDependentCString(timeString)); @@ -3140,21 +3142,21 @@ void UnregisterInjectorCallback(DWORD pr MutexAutoLock lock(*dumpMapLock); pidToMinidump->RemoveEntry(processID); } #endif // MOZ_CRASHREPORTER_INJECTOR #if !defined(XP_WIN) int GetAnnotationTimeCrashFd() { -#if defined(MOZ_WIDGET_ANDROID) +# if defined(MOZ_WIDGET_ANDROID) return gChildCrashAnnotationReportFd; -#else +# else return 7; -#endif // defined(MOZ_WIDGET_ANDROID) +# endif // defined(MOZ_WIDGET_ANDROID) } #endif void RegisterChildCrashAnnotationFileDescriptor(ProcessId aProcess, PRFileDesc* aFd) { processToCrashFd[aProcess] = aFd; } @@ -3178,19 +3180,19 @@ bool SetRemoteExceptionHandler(const nsA gExceptionHandler = new google_breakpad::ExceptionHandler( L"", ChildFPEFilter, nullptr, // no minidump callback reinterpret_cast(aCrashTimeAnnotationFile), google_breakpad::ExceptionHandler::HANDLER_ALL, GetMinidumpType(), NS_ConvertASCIItoUTF16(crashPipe).get(), nullptr); gExceptionHandler->set_handle_debug_exceptions(true); -#if defined(HAVE_64BIT_BUILD) && defined(_M_X64) +# if defined(HAVE_64BIT_BUILD) && defined(_M_X64) SetJitExceptionHandler(); -#endif +# endif mozalloc_set_oom_abort_handler(AnnotateOOMAllocationSize); oldTerminateHandler = std::set_terminate(&TerminateHandler); // we either do remote or nothing, no fallback to regular crash reporting return gExceptionHandler->IsOutOfProcess(); } @@ -3372,17 +3374,17 @@ ThreadId CurrentThreadId() { if (task_threads(mach_task_self(), &threads_for_task, &thread_count)) return -1; for (unsigned int i = 0; i < thread_count; ++i) { if (threads_for_task[i] == mach_thread_self()) return i; } abort(); #else -#error "Unsupported platform" +# error "Unsupported platform" #endif } #ifdef XP_MACOSX static mach_port_t GetChildThread(ProcessHandle childPid, ThreadId childBlamedThread) { mach_port_t childThread = MACH_PORT_NULL; thread_act_port_array_t threads_for_task; diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp.1521000-2-crashreporter.later b/toolkit/crashreporter/nsExceptionHandler.cpp.1521000-2-crashreporter.later new file mode 100644 --- /dev/null +++ b/toolkit/crashreporter/nsExceptionHandler.cpp.1521000-2-crashreporter.later @@ -0,0 +1,68 @@ +--- nsExceptionHandler.cpp ++++ nsExceptionHandler.cpp +@@ -1243,19 +1245,19 @@ static void ReserveBreakpadVM() { + * and should not be handled as crashes. + * + * Also calls FreeBreakpadVM if appropriate. + */ + static bool FPEFilter(void* context, EXCEPTION_POINTERS* exinfo, + MDRawAssertionInfo* assertion) { + if (!exinfo) { + mozilla::IOInterposer::Disable(); +-#if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST) ++# if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST) + DllBlocklist_Shutdown(); +-#endif ++# endif + FreeBreakpadVM(); + return true; + } + + PEXCEPTION_RECORD e = (PEXCEPTION_RECORD)exinfo->ExceptionRecord; + switch (e->ExceptionCode) { + case STATUS_FLOAT_DENORMAL_OPERAND: + case STATUS_FLOAT_DIVIDE_BY_ZERO: +@@ -1276,19 +1278,19 @@ static bool FPEFilter(void* context, EXC + case STATUS_FLOAT_OVERFLOW: + case STATUS_FLOAT_STACK_CHECK: + case STATUS_FLOAT_UNDERFLOW: + case STATUS_FLOAT_MULTIPLE_FAULTS: + case STATUS_FLOAT_MULTIPLE_TRAPS: + return false; // Don't write minidump, continue exception search + } + mozilla::IOInterposer::Disable(); +-#if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST) ++# if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST) + DllBlocklist_Shutdown(); +-#endif ++# endif + FreeBreakpadVM(); + return true; + } + + static bool ChildFPEFilter(void* context, EXCEPTION_POINTERS* exinfo, + MDRawAssertionInfo* assertion) { + bool result = FPEFilter(context, exinfo, assertion); + if (result) { +@@ -1345,19 +1347,19 @@ static bool ShouldReport() { + + return true; + } + + #if !defined(XP_WIN) + + static bool Filter(void* context) { + mozilla::IOInterposer::Disable(); +-#if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST) ++# if defined(DEBUG) && defined(HAS_DLL_BLOCKLIST) + DllBlocklist_Shutdown(); +-#endif ++# endif + return true; + } + + static bool ChildFilter(void* context) { + bool result = Filter(context); + if (result) { + PrepareChildExceptionTimeAnnotations(context); + } diff --git a/toolkit/crashreporter/nsExceptionHandler.h b/toolkit/crashreporter/nsExceptionHandler.h --- a/toolkit/crashreporter/nsExceptionHandler.h +++ b/toolkit/crashreporter/nsExceptionHandler.h @@ -19,28 +19,28 @@ #include #include #include "nsError.h" #include "nsString.h" #include "prio.h" #if defined(XP_WIN32) -#ifdef WIN32_LEAN_AND_MEAN -#undef WIN32_LEAN_AND_MEAN -#endif -#include +# ifdef WIN32_LEAN_AND_MEAN +# undef WIN32_LEAN_AND_MEAN +# endif +# include #endif #if defined(XP_MACOSX) -#include +# include #endif #if defined(XP_LINUX) -#include +# include #endif class nsIFile; namespace CrashReporter { /** * Returns true if the crash reporter is using the dummy implementation. @@ -234,17 +234,17 @@ bool CreateAdditionalChildMinidump(Proce ThreadId childBlamedThread, nsIFile* parentMinidump, const nsACString& name); #if defined(XP_WIN32) || defined(XP_MACOSX) // Parent-side API for children const char* GetChildNotificationPipe(); -#ifdef MOZ_CRASHREPORTER_INJECTOR +# ifdef MOZ_CRASHREPORTER_INJECTOR // Inject a crash report client into an arbitrary process, and inform the // callback object when it crashes. Parent process only. class InjectorCrashCallback { public: InjectorCrashCallback() {} /** @@ -255,25 +255,25 @@ class InjectorCrashCallback { * TakeMinidumpForChild for this process ID. */ virtual void OnCrash(DWORD processID) = 0; }; // This method implies OOPInit void InjectCrashReporterIntoProcess(DWORD processID, InjectorCrashCallback* cb); void UnregisterInjectorCallback(DWORD processID); -#endif +# endif // Child-side API -#if defined(XP_WIN32) +# if defined(XP_WIN32) bool SetRemoteExceptionHandler(const nsACString& crashPipe, uintptr_t aCrashTimeAnnotationFile); -#else +# else bool SetRemoteExceptionHandler(const nsACString& crashPipe); -#endif +# endif #else // Parent-side API for children // Set the outparams for crash reporter server's fd (|childCrashFd|) // and the magic fd number it should be remapped to // (|childCrashRemapFd|) before exec() in the child process. // |SetRemoteExceptionHandler()| in the child process expects to find diff --git a/toolkit/crashreporter/test/nsTestCrasher.cpp b/toolkit/crashreporter/test/nsTestCrasher.cpp --- a/toolkit/crashreporter/test/nsTestCrasher.cpp +++ b/toolkit/crashreporter/test/nsTestCrasher.cpp @@ -3,18 +3,18 @@ #include #include #include "nscore.h" #include "mozilla/Unused.h" #include "ExceptionThrower.h" #ifdef XP_WIN -#include -#include +# include +# include #endif /* * This pure virtual call example is from MSDN */ class A; void fcn(A*);