[Go to site: main page, start]

LLDB mainline
GitHubReporter.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "lldb/Host/Host.h"
12
13#include "llvm/Support/FormatVariadic.h"
14#include "llvm/Support/raw_ostream.h"
15
16using namespace lldb_private;
17
19
20// A GitHub "new issue" URL is fetched with GET, so its length is bounded (the
21// server rejects very long URLs). Keep the pre-filled body well under that so
22// the rest of the URL always fits. The full payload lives in the bundle.
23static constexpr size_t g_max_body_size = 6000;
24
30
34
35std::unique_ptr<BugReporter> GitHubReporter::CreateInstance() {
36 return std::make_unique<GitHubReporter>();
37}
38
39llvm::Error GitHubReporter::File(const Diagnostics::Report &report) {
40 std::string body;
41 llvm::raw_string_ostream os(body);
42 // Lead with the questions: an oversized body is truncated from the end.
43 os << "### Please answer these questions\n\n";
44 for (llvm::StringRef question : GetBugReportQuestions())
45 os << "- " << question << "\n";
46 os << "\n\n";
47 os << "### LLDB version\n" << report.version << "\n\n";
48 os << "### Host\n" << report.os << "\n\n";
49 if (!report.invocation.empty())
50 os << "### Invocation\n`" << report.invocation << "`\n\n";
51 os << "### Diagnostics\n"
52 << "Full diagnostics were written to:\n`" << report.attachments.directory
53 << "`\nPlease attach the contents of that directory to this issue.\n";
54
55 if (body.size() > g_max_body_size) {
56 // Back up off any UTF-8 continuation bytes so truncation lands on a
57 // character boundary rather than splitting a multi-byte sequence.
58 size_t cut = g_max_body_size;
59 while (cut > 0 && (static_cast<unsigned char>(body[cut]) & 0xC0) == 0x80)
60 --cut;
61 body.resize(cut);
62 body += "\n\n...(truncated, see the attached diagnostics directory)";
63 }
64
65 // No title parameter: GitHub blocks submission until the field is filled in,
66 // so an empty one yields a title describing this bug instead of a generic
67 // default nobody edits.
68 std::string url = llvm::formatv("https://github.com/llvm/llvm-project/issues/"
69 "new?body={0}&labels=lldb",
70 Host::URLEncode(body));
71
72 return Host::OpenURL(url);
73}
static constexpr size_t g_max_body_size
#define LLDB_PLUGIN_DEFINE(PluginName)
Opens a pre-filled github.com/llvm/llvm-project "new issue" page.
static llvm::StringRef GetPluginNameStatic()
llvm::Error File(const Diagnostics::Report &report) override
static std::unique_ptr< BugReporter > CreateInstance()
static llvm::Error OpenURL(llvm::StringRef url)
Open a URL with the host's default handler (Launch Services on macOS, xdg-open on other Unix).
static std::string URLEncode(llvm::StringRef str)
Percent-encode a string for use in a URL query component, per RFC 3986 (alphanumerics and "-_....
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
A class that represents a running process on the host machine.
llvm::ArrayRef< llvm::StringRef > GetBugReportQuestions()
The questions only the person filing the report can answer.
The state a triager needs to make sense of a bug report.
Definition Diagnostics.h:63