ProcessPOSIXLog.cpp revision e5eaa30f62c697d649966c86acd4e3c52b39b355
1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//===-- ProcessPOSIXLog.cpp ---------------------------------------*- C++ -*-===//
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//                     The LLVM Compiler Infrastructure
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// This file is distributed under the University of Illinois Open Source
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// License. See LICENSE.TXT for details.
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//===----------------------------------------------------------------------===//
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ProcessPOSIXLog.h"
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "lldb/Interpreter/Args.h"
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "lldb/Core/StreamFile.h"
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ProcessPOSIX.h"
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "ProcessPOSIXLog.h"
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverusing namespace lldb;
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverusing namespace lldb_private;
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// We want to avoid global constructors where code needs to be run so here we
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// control access to our static g_log_sp by hiding it in a singleton function
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// that will construct the static g_lob_sp the first time this function is
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// called.
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic LogSP &
27324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverGetLog ()
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    static LogSP g_log_sp;
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return g_log_sp;
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
33324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverLogSP
34324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverProcessPOSIXLog::GetLogIfAllCategoriesSet (uint32_t mask)
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    LogSP log(GetLog ());
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (log && mask)
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        uint32_t log_mask = log->GetMask().Get();
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ((log_mask & mask) != mask)
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return LogSP();
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return log;
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid
47324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverProcessPOSIXLog::DisableLog (const char **args, Stream *feedback_strm)
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    LogSP log (GetLog ());
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (log)
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        uint32_t flag_bits = 0;
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        flag_bits = log->GetMask().Get();
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for (; args[0]; args++)
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            const char *arg = args[0];
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if      (::strcasecmp (arg, "all")        == 0 ) flag_bits &= ~POSIX_LOG_ALL;
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "async")      == 0 ) flag_bits &= ~POSIX_LOG_ASYNC;
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strncasecmp (arg, "break", 5)  == 0 ) flag_bits &= ~POSIX_LOG_BREAKPOINTS;
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strncasecmp (arg, "comm", 4)   == 0 ) flag_bits &= ~POSIX_LOG_COMM;
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "default")    == 0 ) flag_bits &= ~POSIX_LOG_DEFAULT;
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "packets")    == 0 ) flag_bits &= ~POSIX_LOG_PACKETS;
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "memory")     == 0 ) flag_bits &= ~POSIX_LOG_MEMORY;
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_SHORT;
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "data-long")  == 0 ) flag_bits &= ~POSIX_LOG_MEMORY_DATA_LONG;
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "process")    == 0 ) flag_bits &= ~POSIX_LOG_PROCESS;
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "ptrace")     == 0 ) flag_bits &= ~POSIX_LOG_PTRACE;
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "registers")  == 0 ) flag_bits &= ~POSIX_LOG_REGISTERS;
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "step")       == 0 ) flag_bits &= ~POSIX_LOG_STEP;
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "thread")     == 0 ) flag_bits &= ~POSIX_LOG_THREAD;
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "verbose")    == 0 ) flag_bits &= ~POSIX_LOG_VERBOSE;
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strncasecmp (arg, "watch", 5)  == 0 ) flag_bits &= ~POSIX_LOG_WATCHPOINTS;
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ListLogCategories (feedback_strm);
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (flag_bits == 0)
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            GetLog ().reset();
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        else
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            log->GetMask().Reset (flag_bits);
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return;
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
91324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverLogSP
92324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverProcessPOSIXLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm)
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Try see if there already is a log - that way we can reuse its settings.
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // We could reuse the log in toto, but we don't know that the stream is the same.
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    uint32_t flag_bits = 0;
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    LogSP log(GetLog ());
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (log)
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        flag_bits = log->GetMask().Get();
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    // Now make a new log with this stream if one was provided
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (log_stream_sp)
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log = LogSP(new Log(log_stream_sp));
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        GetLog () = log;
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (log)
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        bool got_unknown_category = false;
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        for (; args[0]; args++)
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            const char *arg = args[0];
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if      (::strcasecmp (arg, "all")        == 0 ) flag_bits |= POSIX_LOG_ALL;
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "async")      == 0 ) flag_bits |= POSIX_LOG_ASYNC;
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strncasecmp (arg, "break", 5)  == 0 ) flag_bits |= POSIX_LOG_BREAKPOINTS;
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strncasecmp (arg, "comm", 4)   == 0 ) flag_bits |= POSIX_LOG_COMM;
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "default")    == 0 ) flag_bits |= POSIX_LOG_DEFAULT;
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "packets")    == 0 ) flag_bits |= POSIX_LOG_PACKETS;
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "memory")     == 0 ) flag_bits |= POSIX_LOG_MEMORY;
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "data-short") == 0 ) flag_bits |= POSIX_LOG_MEMORY_DATA_SHORT;
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "data-long")  == 0 ) flag_bits |= POSIX_LOG_MEMORY_DATA_LONG;
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "process")    == 0 ) flag_bits |= POSIX_LOG_PROCESS;
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "ptrace")     == 0 ) flag_bits |= POSIX_LOG_PTRACE;
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "registers")  == 0 ) flag_bits |= POSIX_LOG_REGISTERS;
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "step")       == 0 ) flag_bits |= POSIX_LOG_STEP;
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "thread")     == 0 ) flag_bits |= POSIX_LOG_THREAD;
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strcasecmp (arg, "verbose")    == 0 ) flag_bits |= POSIX_LOG_VERBOSE;
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else if (::strncasecmp (arg, "watch", 5)  == 0 ) flag_bits |= POSIX_LOG_WATCHPOINTS;
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (got_unknown_category == false)
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    got_unknown_category = true;
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    ListLogCategories (feedback_strm);
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if (flag_bits == 0)
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            flag_bits = POSIX_LOG_DEFAULT;
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log->GetMask().Reset(flag_bits);
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log->GetOptions().Reset(log_options);
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    return log;
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid
150324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverProcessPOSIXLog::ListLogCategories (Stream *strm)
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    strm->Printf ("Logging categories for '%s':\n"
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  all - turn on all available logging categories\n"
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  async - log asynchronous activity\n"
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  break - log breakpoints\n"
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  communication - log communication activity\n"
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  default - enable the default set of logging categories for liblldb\n"
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  packets - log gdb remote packets\n"
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  memory - log memory reads and writes\n"
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  data-short - log memory bytes for memory reads and writes for short transactions only\n"
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  data-long - log memory bytes for memory reads and writes for all transactions\n"
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  process - log process events and activities\n"
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  ptrace - log all calls to ptrace\n"
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#endif
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  registers - log register read/writes\n"
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  thread - log thread events and activities\n"
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  step - log step related activities\n"
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  verbose - enable verbose logging\n"
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                  "  watch - log watchpoint related activities\n", ProcessPOSIXLog::m_pluginname);
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvervoid
175324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverProcessPOSIXLog::LogIf (uint32_t mask, const char *format, ...)
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver{
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (mask));
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    if (log)
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        va_list args;
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        va_start (args, format);
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        log->VAPrintf (format, args);
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        va_end (args);
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverint ProcessPOSIXLog::m_nestinglevel;
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverconst char *ProcessPOSIXLog::m_pluginname = "";
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver