]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectBugreport.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectBugreport.cpp
1 //===-- CommandObjectBugreport.cpp ------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "CommandObjectBugreport.h"
11
12 #include <cstdio>
13
14
15 #include "lldb/Interpreter/CommandInterpreter.h"
16 #include "lldb/Interpreter/CommandReturnObject.h"
17 #include "lldb/Interpreter/OptionGroupOutputFile.h"
18 #include "lldb/Target/Thread.h"
19
20 using namespace lldb;
21 using namespace lldb_private;
22
23 //-------------------------------------------------------------------------
24 // "bugreport unwind"
25 //-------------------------------------------------------------------------
26
27 class CommandObjectBugreportUnwind : public CommandObjectParsed {
28 public:
29   CommandObjectBugreportUnwind(CommandInterpreter &interpreter)
30       : CommandObjectParsed(
31             interpreter, "bugreport unwind",
32             "Create a bugreport for a bug in the stack unwinding code.",
33             nullptr),
34         m_option_group(), m_outfile_options() {
35     m_option_group.Append(&m_outfile_options, LLDB_OPT_SET_ALL,
36                           LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
37     m_option_group.Finalize();
38   }
39
40   ~CommandObjectBugreportUnwind() override {}
41
42   Options *GetOptions() override { return &m_option_group; }
43
44 protected:
45   bool DoExecute(Args &command, CommandReturnObject &result) override {
46     StringList commands;
47     commands.AppendString("thread backtrace");
48
49     Thread *thread = m_exe_ctx.GetThreadPtr();
50     if (thread) {
51       char command_buffer[256];
52
53       uint32_t frame_count = thread->GetStackFrameCount();
54       for (uint32_t i = 0; i < frame_count; ++i) {
55         StackFrameSP frame = thread->GetStackFrameAtIndex(i);
56         lldb::addr_t pc = frame->GetStackID().GetPC();
57
58         snprintf(command_buffer, sizeof(command_buffer),
59                  "disassemble --bytes --address 0x%" PRIx64, pc);
60         commands.AppendString(command_buffer);
61
62         snprintf(command_buffer, sizeof(command_buffer),
63                  "image show-unwind --address 0x%" PRIx64, pc);
64         commands.AppendString(command_buffer);
65       }
66     }
67
68     const FileSpec &outfile_spec =
69         m_outfile_options.GetFile().GetCurrentValue();
70     if (outfile_spec) {
71
72       uint32_t open_options =
73           File::eOpenOptionWrite | File::eOpenOptionCanCreate |
74           File::eOpenOptionAppend | File::eOpenOptionCloseOnExec;
75
76       const bool append = m_outfile_options.GetAppend().GetCurrentValue();
77       if (!append)
78         open_options |= File::eOpenOptionTruncate;
79
80       StreamFileSP outfile_stream = std::make_shared<StreamFile>();
81       File &file = outfile_stream->GetFile();
82       Status error =
83           FileSystem::Instance().Open(file, outfile_spec, open_options);
84       if (error.Fail()) {
85         auto path = outfile_spec.GetPath();
86         result.AppendErrorWithFormat("Failed to open file '%s' for %s: %s\n",
87                                      path.c_str(), append ? "append" : "write",
88                                      error.AsCString());
89         result.SetStatus(eReturnStatusFailed);
90         return false;
91       }
92
93       result.SetImmediateOutputStream(outfile_stream);
94     }
95
96     CommandInterpreterRunOptions options;
97     options.SetStopOnError(false);
98     options.SetEchoCommands(true);
99     options.SetPrintResults(true);
100     options.SetAddToHistory(false);
101     m_interpreter.HandleCommands(commands, &m_exe_ctx, options, result);
102
103     return result.Succeeded();
104   }
105
106 private:
107   OptionGroupOptions m_option_group;
108   OptionGroupOutputFile m_outfile_options;
109 };
110
111 #pragma mark CommandObjectMultiwordBugreport
112
113 //-------------------------------------------------------------------------
114 // CommandObjectMultiwordBugreport
115 //-------------------------------------------------------------------------
116
117 CommandObjectMultiwordBugreport::CommandObjectMultiwordBugreport(
118     CommandInterpreter &interpreter)
119     : CommandObjectMultiword(
120           interpreter, "bugreport",
121           "Commands for creating domain-specific bug reports.",
122           "bugreport <subcommand> [<subcommand-options>]") {
123
124   LoadSubCommand(
125       "unwind", CommandObjectSP(new CommandObjectBugreportUnwind(interpreter)));
126 }
127
128 CommandObjectMultiwordBugreport::~CommandObjectMultiwordBugreport() {}