summaryrefslogtreecommitdiff
path: root/src/vm/eventreporter.h
blob: abd35befc48f1fad23eab8c3f37f5ac1bc3f7f28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

//
//*****************************************************************************
// EventReporter.h:
// A utility to log an entry in event log.
//*****************************************************************************


#ifndef _eventreporter_h_
#define _eventreporter_h_

#include "contract.h"
#include "sstring.h"

// Maximum size for a string in event log entry
#define MAX_SIZE_EVENTLOG_ENTRY_STRING 0x8000 // decimal 32768

// The (approx.) maximum size that Vista appears to allow. Post discussion with the OS event log team,
// it has been identified that Vista has taken a breaking change in ReportEventW API implementation
// without getting it publicly documented.
//
// An event entry comprises of string to be written and event header information. Prior to Vista,
// 32K length strings were allowed and event header size was over it. Vista onwards, the total
// permissible length of the string and event header became 32K, resulting in strings becoming
// shorter in length. Hence, the change in size.
#define MAX_SIZE_EVENTLOG_ENTRY_STRING_WINVISTA 0x7C62 // decimal 31842 

class EventReporter
{
public:
    enum EventReporterType
    {
        ERT_UnhandledException,
        ERT_ManagedFailFast,
        ERT_UnmanagedFailFast,
        ERT_StackOverflow,
        ERT_CodeContractFailed,
    };
private:
    EventReporterType m_eventType;
    // We use 2048 which is large enough for most task.  This allows us to avoid
    // unnecessary memory allocation.
    InlineSString<2048> m_Description;

    // Flag to indicate if the buffer is full
    BOOL fBufferFull;

    static void GetCoreCLRInstanceProductVersion(DWORD * pdwMajor, DWORD * pdwMinor, DWORD * pdwBuild, DWORD * pdwRevision);

public:
    // Construct 
    EventReporter(EventReporterType type);
    // Add extra info into description part of the log
    void AddDescription(__in WCHAR *pString);
    void AddDescription(SString& s);
    // Start callstack record
    void BeginStackTrace();
    // Add one frame to the callstack part
    void AddStackTrace(SString& s);
    // Add failfast stack trace
    void AddFailFastStackTrace(SString& s);
    // Report to the EventLog
    void Report();
};

// return TRUE if we need to log in EventLog.
BOOL ShouldLogInEventLog();
// Record managed callstack in EventReporter.
void LogCallstackForEventReporter(EventReporter& reporter);
// Record unhandled native exceptions.
void DoReportForUnhandledNativeException(PEXCEPTION_POINTERS pExceptionInfo);
// Helper method for logging stack trace in EventReporter
void ReportExceptionStackHelper(OBJECTREF exObj, EventReporter& reporter, SmallStackSString& wordAt, int recursionLimit);
#endif // _eventreporter_h_