Drop sentry-native/tests/ directly

MSVC keeps finding the C# files in-tree and starts to much with them
This commit is contained in:
Mark Roszko
2026-01-21 07:51:10 -05:00
parent 22ea2d2855
commit f4512b2919
188 changed files with 0 additions and 16978 deletions
-380
View File
@@ -1,380 +0,0 @@
import gzip
import subprocess
import os
import io
import json
import sys
import urllib
import pytest
import pprint
import textwrap
import socket
sourcedir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
# https://docs.pytest.org/en/latest/assert.html#assert-details
pytest.register_assert_rewrite("tests.assertions")
SENTRY_VERSION = "0.12.3"
def make_dsn(httpserver, auth="uiaeosnrtdy", id=123456, proxy_host=False):
url = urllib.parse.urlsplit(httpserver.url_for("/{}".format(id)))
# We explicitly use `127.0.0.1` here, because on Windows, `localhost` will
# first try `::1` (the ipv6 loopback), retry a couple times and give up
# after a timeout of 2 seconds, falling back to the ipv4 loopback instead.
host = url.netloc.replace("localhost", "127.0.0.1")
if proxy_host:
# To avoid bypassing the proxy for requests to localhost, we need to add this mapping
# to the hosts file & make the DSN using this alternate hostname
# see https://learn.microsoft.com/en-us/windows/win32/wininet/enabling-internet-functionality#listing-the-proxy-bypass
host = host.replace("127.0.0.1", "sentry.native.test")
_check_sentry_native_resolves_to_localhost()
return urllib.parse.urlunsplit(
(
url.scheme,
"{}@{}".format(auth, host),
url.path,
url.query,
url.fragment,
)
)
def _check_sentry_native_resolves_to_localhost():
try:
resolved_ip = socket.gethostbyname("sentry.native.test")
assert resolved_ip == "127.0.0.1"
except socket.gaierror:
pytest.skip("sentry.native.test does not resolve to localhost")
def is_session_envelope(data):
return b'"type":"session"' in data
def is_logs_envelope(data):
return b'"type":"log"' in data
def is_feedback_envelope(data):
return b'"type":"feedback"' in data
def split_log_request_cond(httpserver_log, cond):
return (
(httpserver_log[0][0], httpserver_log[1][0])
if cond(httpserver_log[0][0].get_data())
else (httpserver_log[1][0], httpserver_log[0][0])
)
def extract_request(httpserver_log, cond):
"""
Extract a request matching the condition from the httpserver log.
Returns (matching_request, remaining_log_entries)
The remaining_log_entries preserves the original format so it can be
chained with subsequent extract_request calls.
"""
for i, entry in enumerate(httpserver_log):
if cond(entry[0].get_data()):
others = [httpserver_log[j] for j in range(len(httpserver_log)) if j != i]
return (entry[0], others)
return (None, httpserver_log)
def run(cwd, exe, args, expect_failure=False, env=None, **kwargs):
if env is None:
env = dict(os.environ)
if kwargs.get("check"):
raise pytest.fail.Exception(
"`check` is inferred from `expect_failure`, and should not be passed in the kwargs"
)
check = expect_failure == False
__tracebackhide__ = True
if os.environ.get("ANDROID_API"):
# older android emulators do not correctly pass down the returncode
# so we basically echo the return code, and parse it manually
is_pipe = kwargs.get("stdout") == subprocess.PIPE
kwargs["stdout"] = subprocess.PIPE
child = subprocess.run(
[
"{}/platform-tools/adb".format(os.environ["ANDROID_HOME"]),
"shell",
# Android by default only searches for libraries in system
# directories and the app directory, and only supports RUNPATH
# since API-24.
# Since we are no "app" in that sense, we can use
# `LD_LIBRARY_PATH` to force the android dynamic loader to
# load `libsentry.so` from the correct library.
# See https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md#dt_runpath-support-available-in-api-level-24
"cd /data/local/tmp && LD_LIBRARY_PATH=. ./{} {}; echo -n ret:$?".format(
exe, " ".join(args)
),
],
check=check,
**kwargs,
)
stdout = child.stdout
child.returncode = int(stdout[stdout.rfind(b"ret:") :][4:])
child.stdout = stdout[: stdout.rfind(b"ret:")]
if not is_pipe:
sys.stdout.buffer.write(child.stdout)
if expect_failure:
assert child.returncode != 0, (
f"command unexpectedly successful: {exe} {" ".join(args)}"
)
else:
assert child.returncode == 0, (
f"command failed unexpectedly: {exe} {" ".join(args)}"
)
if check and child.returncode:
raise subprocess.CalledProcessError(
child.returncode, child.args, output=child.stdout, stderr=child.stderr
)
return child
cmd = [
"./{}".format(exe) if sys.platform != "win32" else "{}\\{}.exe".format(cwd, exe)
]
if "asan" in os.environ.get("RUN_ANALYZER", ""):
env["ASAN_OPTIONS"] = "detect_leaks=1:detect_invalid_join=0"
env["LSAN_OPTIONS"] = "suppressions={}".format(
os.path.join(sourcedir, "tests", "leaks.txt")
)
if "llvm-cov" in os.environ.get("RUN_ANALYZER", ""):
# continuous mode is only supported on mac right now
continuous = "%c" if sys.platform == "darwin" else ""
env["LLVM_PROFILE_FILE"] = f"coverage-%p{continuous}.profraw"
if "kcov" in os.environ.get("RUN_ANALYZER", ""):
coverage_dir = os.path.join(cwd, "coverage")
cmd = [
"kcov",
"--include-path={}".format(os.path.join(sourcedir, "src")),
coverage_dir,
*cmd,
]
if "valgrind" in os.environ.get("RUN_ANALYZER", ""):
cmd = [
"valgrind",
"--suppressions={}".format(
os.path.join(sourcedir, "tests", "valgrind.txt")
),
"--error-exitcode=33",
"--leak-check=yes",
*cmd,
]
try:
result = subprocess.run([*cmd, *args], cwd=cwd, env=env, check=check, **kwargs)
if expect_failure:
assert result.returncode != 0, (
f"command unexpectedly successful: {cmd} {" ".join(args)}"
)
else:
assert result.returncode == 0, (
f"command failed unexpectedly: {cmd} {" ".join(args)}"
)
return result
except subprocess.CalledProcessError:
raise pytest.fail.Exception(
"running command failed: {cmd} {args}".format(
cmd=" ".join(cmd), args=" ".join(args)
)
) from None
def check_output(*args, **kwargs):
stdout = run(*args, stdout=subprocess.PIPE, **kwargs).stdout
# capturing stdout on windows actually encodes "\n" as "\r\n", which we
# revert, because it messes with envelope decoding
stdout = stdout.replace(b"\r\n", b"\n")
return stdout
# Adapted from: https://raw.githubusercontent.com/getsentry/sentry-python/276acae955ee13f7ac3a7728003626eff6d943a8/sentry_sdk/envelope.py
class Envelope(object):
def __init__(
self,
headers=None, # type: Optional[Dict[str, str]]
items=None, # type: Optional[List[Item]]
):
# type: (...) -> None
if headers is not None:
headers = dict(headers)
self.headers = headers or {}
if items is None:
items = []
else:
items = list(items)
self.items = items
def get_event(self):
# type: (...) -> Optional[Event]
for item in self.items:
event = item.get_event()
if event is not None:
return event
return None
def __iter__(self):
# type: (...) -> Iterator[Item]
return iter(self.items)
@classmethod
def deserialize_from(
cls, f # type: Any
):
# type: (...) -> Envelope
headers = json.loads(f.readline())
items = []
while 1:
item = Item.deserialize_from(f)
if item is None:
break
items.append(item)
return cls(headers=headers, items=items)
@classmethod
def deserialize(
cls, data # type: bytes
):
# type: (...) -> Envelope
# check if the data is gzip encoded and extract it before deserialization.
# 0x1f8b: gzip-magic, 0x08: `DEFLATE` compression method.
if data[:3] == b"\x1f\x8b\x08":
with gzip.open(io.BytesIO(data), "rb") as output:
return cls.deserialize_from(output)
return cls.deserialize_from(io.BytesIO(data))
def print_verbose(self, indent=0):
"""Pretty prints the envelope."""
print(" " * indent + "Envelope:")
indent += 2
print(" " * indent + "Headers:")
indent += 2
print(textwrap.indent(pprint.pformat(self.headers), " " * indent))
indent -= 2
print(" " * indent + "Items:")
indent += 2
for item in self.items:
item.print_verbose(indent)
def __repr__(self):
# type: (...) -> str
return "<Envelope headers=%r items=%r>" % (self.headers, self.items)
class PayloadRef(object):
def __init__(
self,
bytes=None, # type: Optional[bytes]
json=None, # type: Optional[Any]
):
# type: (...) -> None
self.json = json
self.bytes = bytes
def print_verbose(self, indent=0):
"""Pretty prints the item."""
print(" " * indent + "Payload:")
indent += 2
if self.bytes:
payload = self.bytes.encode("utf-8", errors="replace")
if self.json:
payload = pprint.pformat(self.json)
try:
print(textwrap.indent(payload, " " * indent))
except UnicodeEncodeError:
# Windows CI appears fickle, and we put emojis in the json
payload = payload.encode("ascii", errors="replace").decode()
print(textwrap.indent(payload, " " * indent))
def __repr__(self):
# type: (...) -> str
return "<Payload bytes=%r json=%r>" % (self.bytes, self.json)
class Item(object):
def __init__(
self,
payload, # type: Union[bytes, text_type, PayloadRef]
headers=None, # type: Optional[Dict[str, str]]
):
if headers is not None:
headers = dict(headers)
elif headers is None:
headers = {}
self.headers = headers
if isinstance(payload, bytes):
payload = PayloadRef(bytes=payload)
else:
payload = payload
self.payload = payload
def get_event(self):
# type: (...) -> Optional[Event]
# Transactions are events with a few extra fields, so return them as well.
if (
self.headers.get("type") in ["event", "transaction"]
and self.payload.json is not None
):
return self.payload.json
return None
@classmethod
def deserialize_from(
cls, f # type: Any
):
# type: (...) -> Optional[Item]
line = f.readline().rstrip()
if not line:
return None
headers = json.loads(line)
length = headers["length"]
payload = f.read(length)
if headers.get("type") in [
"event",
"feedback",
"session",
"transaction",
"user_report",
"log",
]:
rv = cls(headers=headers, payload=PayloadRef(json=json.loads(payload)))
else:
rv = cls(headers=headers, payload=payload)
f.readline()
return rv
@classmethod
def deserialize(
cls, bytes # type: bytes
):
# type: (...) -> Optional[Item]
return cls.deserialize_from(io.BytesIO(bytes))
def print_verbose(self, indent=0):
"""Pretty prints the item."""
item_type = self.headers.get("type", "?").capitalize()
print(" " * indent + f"{item_type}:")
indent += 2
print(" " * indent + "Headers:")
indent += 2
headers = pprint.pformat(self.headers)
print(textwrap.indent(headers, " " * indent))
indent -= 2
self.payload.print_verbose(indent)
def __repr__(self):
# type: (...) -> str
return "<Item headers=%r payload=%r>" % (
self.headers,
self.payload,
)
-497
View File
@@ -1,497 +0,0 @@
import email
import gzip
import json
import platform
import re
import sys
from dataclasses import dataclass
from datetime import datetime, UTC
from pathlib import Path
import msgpack
from . import SENTRY_VERSION
from .conditions import is_android
VERSION_RE = re.compile(r"(\d+\.\d+\.\d+)[-.]?(.*)")
def matches(actual, expected):
return {k: v for (k, v) in actual.items() if k in expected.keys()} == expected
def assert_matches(actual, expected):
"""Assert two objects for equality, ignoring extra keys in ``actual``."""
assert {k: v for (k, v) in actual.items() if k in expected.keys()} == expected
def assert_session(envelope, extra_assertion=None):
session = None
for item in envelope:
if item.headers.get("type") == "session" and item.payload.json is not None:
session = item.payload.json
assert session is not None
assert session["did"] == "42"
assert session["attrs"] == {
"release": "test-example-release",
"environment": "development",
}
if extra_assertion:
assert_matches(session, extra_assertion)
def assert_user_feedback(envelope):
user_feedback = None
for item in envelope:
if item.headers.get("type") == "feedback" and item.payload.json is not None:
user_feedback = item.payload.json["contexts"]["feedback"]
assert user_feedback is not None
assert user_feedback["name"] == "some-name"
assert user_feedback["contact_email"] == "some-email"
assert user_feedback["message"] == "some-message"
def assert_user_report(envelope):
user_report = None
for item in envelope:
if item.headers.get("type") == "user_report" and item.payload.json is not None:
user_report = item.payload.json
assert user_report is not None
assert user_report["name"] == "some-name"
assert user_report["email"] == "some-email"
assert user_report["comments"] == "some-comment"
def assert_meta(
envelope,
release="test-example-release",
integration=None,
transaction="test-transaction",
transaction_data=None,
sdk_override=None,
):
assert envelope.headers["event_id"]
event = envelope.get_event()
assert_event_meta(
event, release, integration, transaction, transaction_data, sdk_override
)
def assert_event_meta(
event,
release="test-example-release",
integration=None,
transaction="test-transaction",
transaction_data=None,
sdk_override=None,
):
assert event["event_id"]
extra = {
"extra stuff": "some value",
"…unicode key…": "őá…–🤮🚀¿ 한글 테스트",
}
if transaction_data:
extra.update(transaction_data)
expected = {
"platform": "native",
"environment": "development",
"release": release,
"user": {"id": "42", "username": "some_name"},
"transaction": transaction,
"tags": {"expected-tag": "some value"},
"extra": extra,
}
expected_sdk = {
"name": "sentry.native",
"version": SENTRY_VERSION,
"packages": [
{"name": "github:getsentry/sentry-native", "version": SENTRY_VERSION},
],
}
if is_android:
expected_sdk["name"] = "sentry.native.android"
else:
if sys.platform == "win32":
assert_matches(
event["contexts"]["os"],
{"name": "Windows", "version": platform.version()},
)
assert event["contexts"]["os"]["build"] is not None
elif sys.platform == "linux":
version = platform.release()
match = VERSION_RE.match(version)
version = match.group(1)
build = match.group(2)
assert_matches(
event["contexts"]["os"],
{"name": "Linux", "version": version, "build": build},
)
assert "distribution_name" in event["contexts"]["os"]
assert "distribution_version" in event["contexts"]["os"]
elif sys.platform == "darwin":
version = platform.mac_ver()[0].split(".")
if len(version) < 3:
version.append("0")
version = ".".join(version)
assert_matches(
event["contexts"]["os"],
{
"name": "macOS",
"version": version,
"kernel_version": platform.release(),
},
)
assert event["contexts"]["os"]["build"] is not None
if sdk_override is not None:
expected_sdk["name"] = sdk_override
assert_matches(event, expected)
assert_matches(event["sdk"], expected_sdk)
assert_matches(
event["contexts"], {"runtime": {"type": "runtime", "name": "testing-runtime"}}
)
if integration is None:
assert event["sdk"].get("integrations") is None
else:
assert event["sdk"]["integrations"] == [integration]
if event.get("type") == "event":
assert any(
"sentry_example" in image["code_file"]
for image in event["debug_meta"]["images"]
)
def assert_stacktrace(
envelope, inside_exception=False, check_size=True, check_package=False
):
event = envelope.get_event()
parent = event["exception"] if inside_exception else event["threads"]
frames = parent["values"][0]["stacktrace"]["frames"]
assert isinstance(frames, list)
if check_size:
assert len(frames) > 0
assert all(frame["instruction_addr"].startswith("0x") for frame in frames)
assert any(
frame.get("function") is not None and frame.get("package") is not None
for frame in frames
)
if check_package:
for frame in frames:
frame_package = frame.get("package")
if frame_package is not None:
frame_package_path = Path(frame_package)
# only assert on absolute paths, since letting pathlib resolve relative paths is cheating
if frame_package_path.is_absolute():
assert (
frame_package_path.is_file()
), f"package is not a valid file path: '{frame_package}'"
def assert_breadcrumb_inner(breadcrumbs, message="debug crumb"):
expected = {
"type": "http",
"message": message,
"category": "example!",
"level": "debug",
"data": {
"url": "https://example.com/api/1.0/users",
"method": "GET",
"status_code": 200,
"reason": "OK",
},
}
assert any(matches(b, expected) for b in breadcrumbs)
def assert_breadcrumb(envelope, message="debug crumb"):
event = envelope.get_event()
assert_breadcrumb_inner(event["breadcrumbs"], message)
def assert_attachment(envelope):
expected = {
"type": "attachment",
"filename": "CMakeCache.txt",
}
assert any(
matches(item.headers, expected)
and b"This is the CMakeCache file." in item.payload.bytes
for item in envelope
)
expected = {
"type": "attachment",
"filename": "bytes.bin",
"content_type": "application/octet-stream",
}
assert any(
matches(item.headers, expected) and item.payload.bytes == b"\xc0\xff\xee"
for item in envelope
)
def assert_logs(envelope, expected_item_count=1, expected_trace_id=None):
logs = None
for item in envelope:
assert item.headers.get("type") == "log"
# >= because of random #lost logs in test_logs_threaded
assert item.headers.get("item_count") >= expected_item_count
assert (
item.headers.get("content_type") == "application/vnd.sentry.items.log+json"
)
logs = item.payload.json
assert isinstance(logs, dict)
assert "items" in logs
# >= because of random #lost logs in test_logs_threaded
assert len(logs["items"]) >= expected_item_count
for i in range(expected_item_count):
log_item = logs["items"][i]
assert "body" in log_item
assert "level" in log_item
assert "timestamp" in log_item # TODO do we need to validate the timestamp?
assert "trace_id" in log_item
assert "attributes" in log_item
assert "os.name" in log_item["attributes"]
assert "os.version" in log_item["attributes"]
assert "sentry.environment" in log_item["attributes"]
assert "sentry.release" in log_item["attributes"]
assert "sentry.sdk.name" in log_item["attributes"]
assert "sentry.sdk.version" in log_item["attributes"]
if expected_trace_id:
assert log_item["trace_id"] == expected_trace_id
def assert_attachment_view_hierarchy(envelope):
expected = {
"type": "attachment",
"filename": "view-hierarchy.json",
"attachment_type": "event.view_hierarchy",
"content_type": "application/json",
}
assert any(matches(item.headers, expected) for item in envelope)
def assert_attachment_content_view_hierarchy(attachment):
expected = {
"rendering_system": "android_view_system",
"windows": [
{
"alpha": 1.0,
"height": 1280.0,
"type": "com.android.internal.policy.DecorView",
"visibility": "visible",
"width": 768.0,
"x": 0.0,
"y": 0.0,
}
],
}
assert matches(attachment, expected)
def assert_minidump(envelope):
expected = {
"type": "attachment",
"attachment_type": "event.minidump",
}
minidump = next(item for item in envelope if matches(item.headers, expected))
assert minidump.headers["length"] > 4
assert minidump.payload.bytes.startswith(b"MDMP")
def assert_timestamp(ts):
elapsed_time = datetime.now(UTC) - datetime.fromisoformat(ts)
assert elapsed_time.total_seconds() < 10
def assert_event(envelope, message="Hello World!", expected_trace_id=""):
event = envelope.get_event()
expected = {
"level": "info",
"logger": "my-logger",
"message": {"formatted": message},
}
assert_matches(event, expected)
assert_timestamp(event["timestamp"])
assert_trace_id(event, expected_trace_id)
# if expected_trace is "" we just expect any value to exist
def assert_trace_id(event, expected_trace_id):
if expected_trace_id == "":
assert len(event["contexts"]["trace"]["trace_id"]) == 32
else:
assert event["contexts"]["trace"]["trace_id"] == expected_trace_id
def assert_breakpad_crash(envelope):
event = envelope.get_event()
expected = {
"level": "fatal",
}
assert_matches(event, expected)
def assert_exception(envelope):
event = envelope.get_event()
exception = {
"type": "ParseIntError",
"value": "invalid digit found in string",
}
assert_matches(event["exception"]["values"][0], exception)
assert_timestamp(event["timestamp"])
def assert_inproc_crash(envelope):
event = envelope.get_event()
assert_matches(event, {"level": "fatal"})
# depending on the unwinder, we currently dont get any stack frames from
# a `ucontext`
assert_stacktrace(envelope, inside_exception=True, check_size=False)
def assert_crash_timestamp(has_files, tmp_path):
# The crash file should survive a `sentry_init` and should still be there
# even after restarts.
if has_files:
with open("{}/.sentry-native/last_crash".format(tmp_path)) as f:
crash_timestamp = f.read()
assert_timestamp(crash_timestamp)
def assert_before_send(envelope):
event = envelope.get_event()
assert_matches(event, {"adapted_by": "before_send"})
def assert_no_before_send(envelope):
event = envelope.get_event()
assert ("adapted_by", "before_send") not in event.items()
@dataclass(frozen=True)
class CrashpadAttachments:
event: dict
breadcrumb1: list
breadcrumb2: list
view_hierarchy: dict
cmake_cache: int
bytes_bin: bytes = None
def _unpack_breadcrumbs(payload):
unpacker = msgpack.Unpacker()
unpacker.feed(payload)
return [unpacked for unpacked in unpacker]
def _load_crashpad_attachments(msg):
event = {}
breadcrumb1 = []
breadcrumb2 = []
view_hierarchy = {}
cmake_cache = -1
bytes_bin = None
for part in msg.walk():
if part.get_filename() is not None:
assert part.get("Content-Type") is None
match part.get_filename():
case "__sentry-event":
event = msgpack.unpackb(part.get_payload(decode=True))
case "__sentry-breadcrumb1":
breadcrumb1 = _unpack_breadcrumbs(part.get_payload(decode=True))
case "__sentry-breadcrumb2":
breadcrumb2 = _unpack_breadcrumbs(part.get_payload(decode=True))
case "view-hierarchy.json":
view_hierarchy = json.loads(part.get_payload(decode=True))
case "CMakeCache.txt":
cmake_cache = len(part.get_payload(decode=True))
case "bytes.bin":
bytes_bin = part.get_payload(decode=True)
return CrashpadAttachments(
event, breadcrumb1, breadcrumb2, view_hierarchy, cmake_cache, bytes_bin
)
def is_valid_timestamp(timestamp):
try:
datetime.fromisoformat(timestamp)
return True
except ValueError:
return False
def _validate_breadcrumb_seq(seq, breadcrumb_func):
for i in seq:
breadcrumb = breadcrumb_func(i)
assert breadcrumb["message"] == str(i)
assert is_valid_timestamp(breadcrumb["timestamp"])
def assert_overflowing_breadcrumb(attachments):
if len(attachments.breadcrumb1) > 3:
_validate_breadcrumb_seq(range(97), lambda i: attachments.breadcrumb1[3 + i])
_validate_breadcrumb_seq(
range(97, 101), lambda i: attachments.breadcrumb2[i - 97]
)
else:
assert_breadcrumb_inner(attachments.breadcrumb1)
def assert_crashpad_upload(req, expect_attachment=False, expect_view_hierarchy=False):
multipart = gzip.decompress(req.get_data())
msg = email.message_from_bytes(bytes(str(req.headers), encoding="utf8") + multipart)
attachments = _load_crashpad_attachments(msg)
assert_overflowing_breadcrumb(attachments)
assert_event_meta(attachments.event, integration="crashpad")
if expect_attachment:
assert attachments.cmake_cache > 0
else:
assert attachments.cmake_cache == -1
if expect_attachment and (sys.platform == "win32" or sys.platform == "linux"):
assert attachments.bytes_bin == b"\xc0\xff\xee"
else:
assert attachments.bytes_bin == None
if expect_view_hierarchy:
assert_attachment_content_view_hierarchy(attachments.view_hierarchy)
assert any(
b'name="upload_file_minidump"' in part.as_bytes()
and b"\n\nMDMP" in part.as_bytes()
for part in msg.walk()
)
def assert_gzip_file_header(output):
assert output[:3] == b"\x1f\x8b\x08"
def assert_gzip_content_encoding(req):
assert req.content_encoding == "gzip"
def assert_no_proxy_request(stdout):
assert "POST" not in stdout
def assert_failed_proxy_auth_request(stdout):
assert (
"POST" in stdout
and "407 Proxy Authentication Required" in stdout
and "200 OK" not in stdout
)
-54
View File
@@ -1,54 +0,0 @@
import os
import shutil
import pytest
from . import make_dsn, run
def run_benchmark(target, backend, cmake, httpserver, gbenchmark, label):
tmp_path = cmake(
["sentry_benchmark"],
{
"SENTRY_BACKEND": backend,
"SENTRY_BUILD_BENCHMARKS": "ON",
"CMAKE_BUILD_TYPE": "Release",
},
)
env = dict(os.environ, SENTRY_DSN=make_dsn(httpserver))
benchmark_out = tmp_path / "benchmark.json"
for i in range(6):
# make sure we are isolated from previous runs
shutil.rmtree(tmp_path / ".sentry-native", ignore_errors=True)
run(
tmp_path,
"sentry_benchmark",
[f"--benchmark_filter={target}", f"--benchmark_out={benchmark_out}"],
env=env,
)
# ignore warmup run
if i > 0:
gbenchmark(benchmark_out, label)
@pytest.mark.parametrize("backend", ["inproc", "breakpad", "crashpad"])
def test_benchmark_init(backend, cmake, httpserver, gbenchmark):
run_benchmark(
"init", backend, cmake, httpserver, gbenchmark, f"SDK init ({backend})"
)
@pytest.mark.parametrize("backend", ["inproc", "breakpad", "crashpad"])
def test_benchmark_backend(backend, cmake, httpserver, gbenchmark):
run_benchmark(
"backend",
backend,
cmake,
httpserver,
gbenchmark,
f"Backend startup ({backend})",
)
-53
View File
@@ -1,53 +0,0 @@
function(sentry_get_property NAME)
get_target_property(prop sentry "${NAME}")
if(NOT prop)
set(prop)
endif()
set("SENTRY_${NAME}" "${prop}" PARENT_SCOPE)
endfunction()
sentry_get_property(SOURCES)
sentry_get_property(COMPILE_DEFINITIONS)
sentry_get_property(INTERFACE_INCLUDE_DIRECTORIES)
sentry_get_property(INCLUDE_DIRECTORIES)
sentry_get_property(LINK_LIBRARIES)
sentry_get_property(INTERFACE_LINK_LIBRARIES)
list(FILTER SENTRY_SOURCES EXCLUDE REGEX "\\.rc$")
add_executable(sentry_benchmark
${SENTRY_SOURCES}
benchmark_init.cpp
benchmark_backend.cpp
)
if(SENTRY_BACKEND_CRASHPAD)
add_dependencies(sentry_benchmark crashpad::handler)
if(WIN32)
add_dependencies(sentry_benchmark crashpad::wer)
endif()
endif()
target_link_libraries(sentry_benchmark PRIVATE
${SENTRY_LINK_LIBRARIES}
${SENTRY_INTERFACE_LINK_LIBRARIES}
"$<$<PLATFORM_ID:Linux>:rt>"
benchmark::benchmark benchmark::benchmark_main
)
target_compile_definitions(sentry_benchmark PRIVATE ${SENTRY_COMPILE_DEFINITIONS})
target_include_directories(sentry_benchmark PRIVATE
${SENTRY_INTERFACE_INCLUDE_DIRECTORIES}
${SENTRY_INCLUDE_DIRECTORIES}
)
if(MSVC)
target_compile_options(sentry_benchmark PRIVATE $<BUILD_INTERFACE:/wd5105>)
endif()
# set static runtime if enabled
if(SENTRY_BUILD_RUNTIMESTATIC AND MSVC)
set_property(TARGET sentry_benchmark PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
endif()
add_test(NAME sentry_benchmark COMMAND sentry_benchmark)
@@ -1,44 +0,0 @@
#include <benchmark/benchmark.h>
extern "C" {
#include "sentry_backend.h"
#include "sentry_database.h"
#include "sentry_logger.h"
#include "sentry_options.h"
#include "sentry_path.h"
}
static void
benchmark_backend_startup(benchmark::State &state)
{
sentry_options_t *options = sentry_options_new();
sentry_backend_t *backend = sentry__backend_new();
if (!backend || !backend->startup_func) {
state.SkipWithMessage("no backend/startup_func");
} else {
// support SENTRY_DEBUG=1
sentry_logger_t logger = { NULL, NULL, SENTRY_LEVEL_DEBUG };
if (options->debug) {
logger = options->logger;
}
sentry__logger_set_global(logger);
sentry__path_create_dir_all(options->database_path);
sentry_path_t *database_path = options->database_path;
options->database_path = sentry__path_absolute(database_path);
sentry__path_free(database_path);
options->run = sentry__run_new(options->database_path);
for (auto s : state) {
backend->startup_func(backend, options);
}
}
sentry__backend_free(backend);
sentry_options_free(options);
}
BENCHMARK(benchmark_backend_startup)
->Iterations(1)
->Unit(benchmark::kMillisecond);
@@ -1,14 +0,0 @@
#include <benchmark/benchmark.h>
#include <sentry.h>
static void
benchmark_init(benchmark::State &state)
{
sentry_options_t *options = sentry_options_new();
for (auto _ : state) {
sentry_init(options);
}
sentry_close();
}
BENCHMARK(benchmark_init)->Iterations(1)->Unit(benchmark::kMillisecond);
-319
View File
@@ -1,319 +0,0 @@
import json
import os
import shutil
import subprocess
import sys
import platform
from pathlib import Path
import pytest
class CMake:
def __init__(self, factory):
self.runs = dict()
self.factory = factory
def compile(self, targets, options=None, cflags=None):
# We build in tmp for all of our tests. Disable the warning MSVC generates to not clutter the build logs.
if cflags is None:
cflags = []
if sys.platform == "win32":
os.environ["IgnoreWarnIntDirInTempDetected"] = "True"
if options is None:
options = dict()
key = (
";".join(targets),
";".join(f"{k}={v}" for k, v in options.items()),
)
# cache the build configuration
if key not in self.runs:
cwd = self.factory.mktemp("cmake")
self.runs[key] = cwd
cmake(cwd, targets, options, cflags)
build_tmp_path = self.runs[key]
# ensure that there are no left-overs from previous runs
shutil.rmtree(build_tmp_path / ".sentry-native", ignore_errors=True)
# Inject a sub-path into the temporary build directory as the CWD for all tests to verify UTF-8 path handling.
if os.environ.get("UTF8_TEST_CWD"):
# this is Thai and translates to "this is a test directory"
utf8_subpath = build_tmp_path / "นี่คือไดเร็กทอรีทดสอบ"
shutil.rmtree(utf8_subpath, ignore_errors=True)
shutil.copytree(build_tmp_path, utf8_subpath, dirs_exist_ok=True)
return utf8_subpath
return build_tmp_path
def destroy(self):
sourcedir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
coveragedir = os.path.join(sourcedir, "coverage")
shutil.rmtree(coveragedir, ignore_errors=True)
os.mkdir(coveragedir)
if "llvm-cov" in os.environ.get("RUN_ANALYZER", ""):
for i, d in enumerate(self.runs.values()):
# first merge the raw profiling runs
files = [f for f in os.listdir(d) if f.endswith(".profraw")]
if len(files) == 0:
continue
cmd = [
"llvm-profdata",
"merge",
"-sparse",
"-o=sentry.profdata",
*files,
]
print("{} > {}".format(d, " ".join(cmd)))
subprocess.run(cmd, cwd=d)
# then export lcov from the profiling data, since this needs access
# to the object files, we need to do it per-test
objects = [
"sentry_example",
"sentry_test_unit",
"libsentry.dylib" if sys.platform == "darwin" else "libsentry.so",
]
cmd = [
"llvm-cov",
"export",
"-format=lcov",
"-instr-profile=sentry.profdata",
"--ignore-filename-regex=(external|vendor|tests|examples)",
*[f"-object={o}" for o in objects if d.joinpath(o).exists()],
]
lcov = os.path.join(coveragedir, f"run-{i}.lcov")
with open(lcov, "w") as lcov_file:
print("{} > {} > {}".format(d, " ".join(cmd), lcov))
subprocess.run(cmd, stdout=lcov_file, cwd=d)
if "kcov" in os.environ.get("RUN_ANALYZER", ""):
coverage_dirs = [
d
for d in [d.joinpath("coverage") for d in self.runs.values()]
if d.exists()
]
if len(coverage_dirs) > 0:
subprocess.run(
[
"kcov",
"--clean",
"--merge",
coveragedir,
*coverage_dirs,
]
)
def cmake(cwd, targets, options=None, cflags=None):
if cflags is None:
cflags = []
__tracebackhide__ = True
if options is None:
options = {}
options.update(
{
"CMAKE_RUNTIME_OUTPUT_DIRECTORY": cwd,
"CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG": cwd,
"CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE": cwd,
}
)
if os.environ.get("ANDROID_API") and os.environ.get("ANDROID_NDK"):
# See: https://developer.android.com/ndk/guides/cmake
toolchain = "{}/ndk/{}/build/cmake/android.toolchain.cmake".format(
os.environ["ANDROID_HOME"], os.environ["ANDROID_NDK"]
)
options.update(
{
"CMAKE_TOOLCHAIN_FILE": toolchain,
"ANDROID_ABI": os.environ.get("ANDROID_ARCH") or "x86",
"ANDROID_NATIVE_API_LEVEL": os.environ["ANDROID_API"],
}
)
source_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
cmake = ["cmake"]
if "scan-build" in os.environ.get("RUN_ANALYZER", ""):
cc = os.environ.get("CC")
cxx = os.environ.get("CXX")
cmake = [
"scan-build",
*(["--use-cc", cc] if cc else []),
*(["--use-c++", cxx] if cxx else []),
"--status-bugs",
"--exclude",
os.path.join(source_dir, "external"),
"cmake",
]
config_cmd = cmake.copy()
if os.environ.get("VS_GENERATOR_TOOLSET") == "ClangCL":
config_cmd.append("-G Visual Studio 17 2022")
config_cmd.append("-A x64")
config_cmd.append("-T ClangCL")
for key, value in options.items():
config_cmd.append("-D{}={}".format(key, value))
if sys.platform == "win32" and os.environ.get("TEST_X86"):
config_cmd.append("-AWin32")
elif sys.platform == "linux" and os.environ.get("TEST_X86"):
config_cmd.append("-DSENTRY_BUILD_FORCE32=ON")
if "asan" in os.environ.get("RUN_ANALYZER", ""):
config_cmd.append("-DWITH_ASAN_OPTION=ON")
if "tsan" in os.environ.get("RUN_ANALYZER", ""):
module_dir = Path(__file__).resolve().parent
tsan_options = {
"verbosity": 2,
"detect_deadlocks": 1,
"second_deadlock_stack": 1,
"suppressions": module_dir / "tsan.supp",
}
os.environ["TSAN_OPTIONS"] = ":".join(
f"{key}={value}" for key, value in tsan_options.items()
)
config_cmd.append("-DWITH_TSAN_OPTION=ON")
# we have to set `-Werror` for this cmake invocation only, otherwise
# completely unrelated things will break
if os.environ.get("ERROR_ON_WARNINGS"):
cflags.append("-Werror")
if sys.platform == "win32" and not os.environ.get("TEST_MINGW"):
# MP = object level parallelism, WX = warnings as errors
cpus = os.cpu_count()
cflags.append("/WX /MP{}".format(cpus))
if "gcc" in os.environ.get("RUN_ANALYZER", ""):
cflags.append("-fanalyzer")
if "llvm-cov" in os.environ.get("RUN_ANALYZER", ""):
if False and os.environ.get("VS_GENERATOR_TOOLSET") == "ClangCL":
# for clang-cl in CI we have to use `--coverage` rather than `fprofile-instr-generate` and provide an
# architecture-specific profiling library for it work:
# TODO: This currently doesn't work due to https://gitlab.kitware.com/cmake/cmake/-/issues/24025
# The issue describes a behavior where generated object-name is specified via `/fo` using a target
# directory, rather than a file-name (this is CMake behavior). While the `clang-cl` suggest that this
# is supported the flag produces `.gcda` and `.gcno` files, which have no relation with the object-
# file and which leads to failure to accumulate coverage data.
# This would have to be fixed in clang-cl: https://github.com/llvm/llvm-project/issues/87304
# Let's leave this in here for posterity, it would be great to get coverage analysis on Windows.
flags = "--coverage"
profile_lib = "clang_rt.profile-x86_64.lib"
config_cmd.append(f"-DCMAKE_EXE_LINKER_FLAGS='{profile_lib}'")
config_cmd.append(f"-DCMAKE_SHARED_LINKER_FLAGS='{profile_lib}'")
config_cmd.append(f"-DCMAKE_MODULE_LINKER_FLAGS='{profile_lib}'")
else:
flags = "-fprofile-instr-generate -fcoverage-mapping"
config_cmd.append("-DCMAKE_C_FLAGS='{}'".format(flags))
# Since we overwrite `CXXFLAGS` below, we must add the experimental library here for the GHA runner that builds
# sentry-native with LLVM clang for macOS (to run ASAN on macOS) rather than the version coming with XCode.
# TODO: remove this if the GHA runner image for macOS ever updates beyond llvm15.
if (
sys.platform == "darwin"
and os.environ.get("CC", "") == "clang"
and shutil.which("clang") == "/usr/local/opt/llvm@15/bin/clang"
):
flags = (
flags
+ " -L/usr/local/opt/llvm@15/lib/c++ -fexperimental-library -Wno-unused-command-line-argument"
)
config_cmd.append("-DCMAKE_CXX_FLAGS='{}'".format(flags))
if "CMAKE_DEFINES" in os.environ:
config_cmd.extend(os.environ.get("CMAKE_DEFINES").split())
env = dict(os.environ)
env["CFLAGS"] = env["CXXFLAGS"] = " ".join(cflags)
config_cmd.append(source_dir)
print("\n{} > {}".format(cwd, " ".join(config_cmd)), flush=True)
try:
subprocess.run(config_cmd, cwd=cwd, env=env, check=True)
except subprocess.CalledProcessError:
raise pytest.fail.Exception("cmake configure failed") from None
# CodeChecker invocations and options are documented here:
# https://github.com/Ericsson/codechecker/blob/master/docs/analyzer/user_guide.md
buildcmd = [*cmake, "--build", "."]
for target in targets:
buildcmd.extend(["--target", target])
buildcmd.append("--parallel")
if "CMAKE_BUILD_TYPE" in options:
buildcmd.extend(["--config", options["CMAKE_BUILD_TYPE"]])
if "code-checker" in os.environ.get("RUN_ANALYZER", ""):
buildcmd = [
"codechecker",
"log",
"--output",
"compilation.json",
"--build",
" ".join(buildcmd),
]
print("{} > {}".format(cwd, " ".join(buildcmd)), flush=True)
try:
subprocess.run(buildcmd, cwd=cwd, check=True)
except subprocess.CalledProcessError:
raise pytest.fail.Exception("cmake build failed") from None
# check if the DLL and EXE artifacts contain version-information
if platform.system() == "Windows":
from tests.win_utils import check_binary_version
check_binary_version(Path(cwd) / "sentry.dll")
check_binary_version(Path(cwd) / "crashpad_wer.dll")
check_binary_version(Path(cwd) / "crashpad_handler.exe")
if "code-checker" in os.environ.get("RUN_ANALYZER", ""):
# For whatever reason, the compilation summary contains duplicate entries,
# one with the correct absolute path, and the other one just with the basename,
# which would fail.
with open(os.path.join(cwd, "compilation.json")) as f:
compilation = json.load(f)
compilation = list(filter(lambda c: c["file"].startswith("/"), compilation))
with open(os.path.join(cwd, "compilation.json"), "w") as f:
json.dump(compilation, f)
disable = [
"readability-magic-numbers",
"cppcoreguidelines-avoid-magic-numbers",
"readability-else-after-return",
]
disables = ["--disable={}".format(d) for d in disable]
checkcmd = [
"codechecker",
"check",
"--jobs",
str(os.cpu_count()),
# NOTE: The clang version on CI does not support CTU :-(
# Also, when testing locally, CTU spews a ton of (possibly) false positives
# "--ctu-all",
# TODO: we currently get >300 reports with `enable-all`
# "--enable-all",
*disables,
"--print-steps",
"--ignore",
os.path.join(source_dir, ".codechecker-ignore"),
"--logfile",
"compilation.json",
]
print("{} > {}".format(cwd, " ".join(checkcmd)), flush=True)
subprocess.run(checkcmd, cwd=cwd, check=True)
if os.environ.get("ANDROID_API"):
# copy the output to the android image via adb
subprocess.run(
[
"{}/platform-tools/adb".format(os.environ["ANDROID_HOME"]),
"push",
"./",
"/data/local/tmp",
],
cwd=cwd,
check=True,
)
-36
View File
@@ -1,36 +0,0 @@
import sys
import os
is_aix = sys.platform == "aix" or sys.platform == "os400"
is_android = os.environ.get("ANDROID_API")
is_x86 = os.environ.get("TEST_X86")
is_asan = "asan" in os.environ.get("RUN_ANALYZER", "")
is_tsan = "tsan" in os.environ.get("RUN_ANALYZER", "")
is_kcov = "kcov" in os.environ.get("RUN_ANALYZER", "")
is_valgrind = "valgrind" in os.environ.get("RUN_ANALYZER", "")
has_http = not is_android and not (sys.platform == "linux" and is_x86)
# breakpad does not work correctly when using kcov or valgrind
# also, asan reports a `stack-buffer-underflow` in breakpad itself,
# and says this may be a false positive due to a custom stack unwinding mechanism
has_breakpad = (
not is_valgrind
and not is_kcov
# Needs porting
and not is_aix
# XXX: we support building breakpad, and it captures minidumps when run through sentry-android,
# however running it from an `adb shell` does not work correctly :-(
and not is_android
and not (is_asan and sys.platform == "darwin")
)
# crashpad requires http, needs porting to AIX, and doesnt work with kcov/valgrind/tsan either
has_crashpad = (
has_http
and not is_valgrind
and not is_kcov
and not is_android
and not is_aix
and not is_tsan
)
# android has no local filesystem
has_files = not is_android
-142
View File
@@ -1,142 +0,0 @@
import json
import os
import pytest
import re
import statistics
import sys
from . import run
from .cmake import CMake
LABEL = "label"
TIME_UNIT = "time_unit"
REAL_TIME = "real_time"
CPU_TIME = "cpu_time"
gbenchmarks = {}
def enumerate_unittests():
regexp = re.compile(r"XX\((.*?)\)")
# TODO: actually generate the `tests.inc` file with python
curdir = os.path.dirname(os.path.realpath(__file__))
with open(os.path.join(curdir, "unit/tests.inc"), "r") as testsfile:
for line in testsfile:
match = regexp.match(line)
if match:
yield match.group(1)
def pytest_generate_tests(metafunc):
if "unittest" in metafunc.fixturenames:
metafunc.parametrize("unittest", enumerate_unittests())
@pytest.fixture(scope="session")
def cmake(tmp_path_factory):
cmake = CMake(tmp_path_factory)
yield cmake.compile
cmake.destroy()
def pytest_addoption(parser):
parser.addoption(
"--with_crashpad_wer",
action="store_true",
help="Enables tests for the crashpad WER module on Windows",
)
parser.addoption(
"--benchmark_out",
action="store",
help="Output file for benchmark results",
)
def pytest_runtest_setup(item):
if "with_crashpad_wer" in item.keywords and not item.config.getoption(
"--with_crashpad_wer"
):
pytest.skip("need --with_crashpad_wer to run this test")
def pytest_configure(config):
config.addinivalue_line(
"markers",
"with_crashpad_wer: mark test to only run when WER testing is enabled",
)
@pytest.fixture
def gbenchmark():
def _load(json_path, label, test_name=None):
if test_name is None:
test_name = os.environ.get("PYTEST_CURRENT_TEST").split(" ")[0]
with open(json_path, "r") as f:
data = json.load(f)
if test_name not in gbenchmarks:
gbenchmarks[test_name] = {
LABEL: label,
TIME_UNIT: "",
REAL_TIME: [],
CPU_TIME: [],
}
for benchmark in data["benchmarks"]:
if benchmark.get("skipped", False) == True:
pytest.skip(benchmark.get("skip_message", "skipped"))
break
gbenchmarks[test_name][TIME_UNIT] = benchmark[TIME_UNIT]
gbenchmarks[test_name][REAL_TIME].append(benchmark[REAL_TIME])
gbenchmarks[test_name][CPU_TIME].append(benchmark[CPU_TIME])
return _load
def _get_benchmark(name, separator):
data = gbenchmarks.get(name)
if data is None:
return None
unit = data[TIME_UNIT]
real_time = data[REAL_TIME] if data[REAL_TIME] else []
cpu_time = data[CPU_TIME] if data[CPU_TIME] else []
extra = [
f"Min {min(real_time):.3f}{unit}",
f"Max {max(real_time):.3f}{unit}",
f"Mean {statistics.mean(real_time):.3f}{unit}",
f"StdDev {statistics.stdev(real_time):.3f}{unit}",
f"Median {statistics.median(real_time):.3f}{unit}",
f"CPU {statistics.mean(cpu_time):.3f}{unit}" if sys.platform != "win32" else "",
]
return {
"name": data[LABEL],
"unit": unit,
"value": statistics.median(real_time),
"extra": separator.join(e for e in extra if e),
}
def pytest_report_teststatus(report, config):
if report.when == "call" and report.passed:
benchmark = _get_benchmark(report.nodeid, ", ")
if benchmark:
return (
"passed",
None,
f"PASSED\n{benchmark['extra']}",
)
return None
def pytest_sessionfinish(session, exitstatus):
json_path = session.config.getoption("--benchmark_out")
if json_path:
with open(json_path, "w") as f:
benchmarks = [_get_benchmark(name, "\n") for name in gbenchmarks.keys()]
json.dump(benchmarks, f, indent=2)
-24
View File
@@ -1,24 +0,0 @@
The files here are created like this:
$ gcc -shared -o with-buildid.so test.c
$ gcc -Wl,--build-id=none -shared -o without-buildid.so test.c
For `with-buildid.so`, `sentry-cli difutil check` outputs the following:
> debug_id: 4247301c-14f1-5421-53a8-a777f6cdb3a2 (x86_64)
> code_id: 1c304742f114215453a8a777f6cdb3a2b8505e11 (x86_64)
For `without-buildid.so`:
> debug_id: 29271919-a2ef-129d-9aac-be85a0948d9c (x86_64)
This is the value we want to replicate with our fallback hashing
Similarly for `libstdc++.so`, which is taken from the x86 Android API-16 image.
> debug_id: 7fa824da-38f1-b87c-04df-718fda64990c (x86)
And `sentry_example`, which is from an x86 Android API-16 build.
> debug_id: 6c4ac2b4-95c9-7fc1-b18a-65184a65863c (x86)
> code_id: b4c24a6cc995c17fb18a65184a65863cfc01c673 (x86)
@@ -1,5 +0,0 @@
cmake_minimum_required(VERSION 3.10)
project(sentry_crash_reporter LANGUAGES C)
add_executable(sentry_crash_reporter crash_reporter.c)
target_link_libraries(sentry_crash_reporter PRIVATE sentry)
@@ -1,77 +0,0 @@
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif
# define NOMINMAX
# define _CRT_SECURE_NO_WARNINGS
#endif
#include "sentry.h"
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32) && defined(_MSC_VER)
# include <windows.h>
int
wmain(int argc, wchar_t *argv[])
{
// Set console output to UTF-8 so `fwprintf` outputs the wides correctly
SetConsoleOutputCP(CP_UTF8);
if (argc != 2) {
fwprintf(stderr, L"Usage: %ls <envelope>\n", argv[0]);
return EXIT_FAILURE;
}
wchar_t *path = argv[1];
sentry_envelope_t *envelope = sentry_envelope_read_from_filew(path);
if (!envelope) {
fwprintf(stderr, L"ERROR: %ls (%ls)\n", path, _wcserror(errno));
return EXIT_FAILURE;
}
#else
int
main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "Usage: %s <envelope>\n", argv[0]);
return EXIT_FAILURE;
}
char *path = argv[1];
sentry_envelope_t *envelope = sentry_envelope_read_from_file(path);
if (!envelope) {
fprintf(stderr, "ERROR: %s (%s)\n", path, strerror(errno));
return EXIT_FAILURE;
}
#endif
sentry_value_t dsn = sentry_envelope_get_header(envelope, "dsn");
sentry_value_t event_id = sentry_envelope_get_header(envelope, "event_id");
sentry_options_t *options = sentry_options_new();
sentry_options_set_backend(options, NULL);
sentry_options_set_dsn(options, sentry_value_as_string(dsn));
sentry_options_set_debug(options, true);
sentry_init(options);
sentry_uuid_t uuid
= sentry_uuid_from_string(sentry_value_as_string(event_id));
sentry_value_t feedback = sentry_value_new_feedback(
"some-message", "some-email", "some-name", &uuid);
sentry_capture_envelope(envelope);
sentry_capture_feedback(feedback);
sentry_close();
#if defined(_WIN32) && defined(_MSC_VER)
_wremove(path);
#else
remove(path);
#endif
}
@@ -1,67 +0,0 @@
namespace dotnet_signal;
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("crash", EntryPoint = "native_crash")]
static extern void native_crash();
[DllImport("crash", EntryPoint = "enable_sigaltstack")]
static extern void enable_sigaltstack();
[DllImport("sentry", EntryPoint = "sentry_options_new")]
static extern IntPtr sentry_options_new();
[DllImport("sentry", EntryPoint = "sentry_options_set_handler_strategy")]
static extern IntPtr sentry_options_set_handler_strategy(IntPtr options, int strategy);
[DllImport("sentry", EntryPoint = "sentry_options_set_debug")]
static extern IntPtr sentry_options_set_debug(IntPtr options, int debug);
[DllImport("sentry", EntryPoint = "sentry_init")]
static extern int sentry_init(IntPtr options);
static void Main(string[] args)
{
var githubActions = Environment.GetEnvironmentVariable("GITHUB_ACTIONS") ?? string.Empty;
if (githubActions == "true") {
// Set up our own `sigaltstack` for this thread if we're running on GHA because of a failure to run any
// signal handler after the initial setup. This behavior is locally non-reproducible and likely runner-related.
// I ran this against .net7/8/9 on at least 10 different Linux setups, and it worked on all, but on GHA
// it only works if we __don't__ accept the already installed `sigaltstack`.
enable_sigaltstack();
}
// setup minimal sentry-native
var options = sentry_options_new();
sentry_options_set_handler_strategy(options, 1);
sentry_options_set_debug(options, 1);
sentry_init(options);
var doNativeCrash = args is ["native-crash"];
if (doNativeCrash)
{
native_crash();
}
else if (args.Contains("managed-exception"))
{
try
{
Console.WriteLine("dereference a NULL object from managed code");
var s = default(string);
var c = s.Length;
}
catch (NullReferenceException exception)
{
}
}
else if (args.Contains("unhandled-managed-exception"))
{
Console.WriteLine("dereference a NULL object from managed code (unhandled)");
var s = default(string);
var c = s.Length;
}
}
}
@@ -1,19 +0,0 @@
#include <signal.h>
#include <stdlib.h>
void native_crash(void)
{
*(int *)10 = 100;
}
void enable_sigaltstack(void)
{
const size_t signal_stack_size = 16384;
stack_t signal_stack;
signal_stack.ss_sp = malloc(signal_stack_size);
if (!signal_stack.ss_sp) {
return;
}
signal_stack.ss_size = signal_stack_size;
signal_stack.ss_flags = 0;
sigaltstack(&signal_stack, 0);
}
@@ -1,4 +0,0 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
@@ -1,23 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("test_dotnet")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+562915408265dde9642268d95c826c3bce2af759")]
[assembly: System.Reflection.AssemblyProductAttribute("test_dotnet")]
[assembly: System.Reflection.AssemblyTitleAttribute("test_dotnet")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -1 +0,0 @@
72b5807093301cd306bb97058fbc13b22fc751402c9ceed444d85a32b7191dfa
@@ -1,17 +0,0 @@
is_global = true
build_property.TargetFramework = net10.0
build_property.TargetFrameworkIdentifier = .NETCoreApp
build_property.TargetFrameworkVersion = v10.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = test_dotnet
build_property.ProjectDir = E:\kicad\kicad\thirdparty\sentry-native\tests\fixtures\dotnet_signal\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.EffectiveAnalysisLevelStyle = 10.0
build_property.EnableCodeStyleSeverity =
@@ -1,8 +0,0 @@
// <auto-generated/>
global using System;
global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Net.Http;
global using System.Threading;
global using System.Threading.Tasks;
@@ -1,4 +0,0 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
@@ -1,23 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("test_dotnet")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+562915408265dde9642268d95c826c3bce2af759")]
[assembly: System.Reflection.AssemblyProductAttribute("test_dotnet")]
[assembly: System.Reflection.AssemblyTitleAttribute("test_dotnet")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -1 +0,0 @@
e89b5e72a0730bcaba20dbc1a090cf4a4cd7877bd47b0602865297c99edfb1b1
@@ -1,17 +0,0 @@
is_global = true
build_property.TargetFramework = net10.0
build_property.TargetFrameworkIdentifier = .NETCoreApp
build_property.TargetFrameworkVersion = v10.0
build_property.TargetPlatformMinVersion =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = test_dotnet
build_property.ProjectDir = E:\kicad\kicad\thirdparty\sentry-native\tests\fixtures\dotnet_signal\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.EffectiveAnalysisLevelStyle = 10.0
build_property.EnableCodeStyleSeverity =
@@ -1,8 +0,0 @@
// <auto-generated/>
global using System;
global using System.Collections.Generic;
global using System.IO;
global using System.Linq;
global using System.Net.Http;
global using System.Threading;
global using System.Threading.Tasks;
@@ -1,8 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
Binary file not shown.
@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@@ -1,13 +0,0 @@
# os_release
Adapted from https://github.com/chef/os_release as data for unit-testing.
This repo contains the /etc/os-release file from Linux distros.
## About os-release
/etc/os-release is a standard Linux file used to identify the OS, os release, and similar distros. It's now a standard file in systemd distros, but it can be found in just about every Linux distro released over the last 3-4 years.
## Why collect them
The fields in /etc/os-release are standardized, but the values are not. The only way to know that Redhat Enterprise Linux is 'rhel' or that openSUSE 15 is 'opensuse-leap' is to install the distros and check the file. This repo is a large collection of os-release files so you don't need to install each and every distro.
@@ -1,18 +0,0 @@
NAME="AlmaLinux"
VERSION="8.7 (Stone Smilodon)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="8.7"
PLATFORM_ID="platform:el8"
PRETTY_NAME="AlmaLinux 8.7 (Stone Smilodon)"
ANSI_COLOR="0;34"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:almalinux:almalinux:8::baseos"
HOME_URL="https://almalinux.org/"
DOCUMENTATION_URL="https://wiki.almalinux.org/"
BUG_REPORT_URL="https://bugs.almalinux.org/"
ALMALINUX_MANTISBT_PROJECT="AlmaLinux-8"
ALMALINUX_MANTISBT_PROJECT_VERSION="8.7"
REDHAT_SUPPORT_PRODUCT="AlmaLinux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.7"
@@ -1,18 +0,0 @@
NAME="AlmaLinux"
VERSION="9.1 (Lime Lynx)"
ID="almalinux"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.1"
PLATFORM_ID="platform:el9"
PRETTY_NAME="AlmaLinux 9.1 (Lime Lynx)"
ANSI_COLOR="0;34"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:almalinux:almalinux:9::baseos"
HOME_URL="https://almalinux.org/"
DOCUMENTATION_URL="https://wiki.almalinux.org/"
BUG_REPORT_URL="https://bugs.almalinux.org/"
ALMALINUX_MANTISBT_PROJECT="AlmaLinux-9"
ALMALINUX_MANTISBT_PROJECT_VERSION="9.1"
REDHAT_SUPPORT_PRODUCT="AlmaLinux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.1"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.10.9
PRETTY_NAME="Alpine Linux v3.10"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.11.13
PRETTY_NAME="Alpine Linux v3.11"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.12.12
PRETTY_NAME="Alpine Linux v3.12"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.13.12
PRETTY_NAME="Alpine Linux v3.13"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.14.9
PRETTY_NAME="Alpine Linux v3.14"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.15.7
PRETTY_NAME="Alpine Linux v3.15"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.16.4
PRETTY_NAME="Alpine Linux v3.16"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.17.2
PRETTY_NAME="Alpine Linux v3.17"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.8.5
PRETTY_NAME="Alpine Linux v3.8"
HOME_URL="http://alpinelinux.org"
BUG_REPORT_URL="http://bugs.alpinelinux.org"
@@ -1,6 +0,0 @@
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.9.6
PRETTY_NAME="Alpine Linux v3.9"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
@@ -1,9 +0,0 @@
NAME="Amazon Linux"
VERSION="2"
ID="amzn"
ID_LIKE="centos rhel fedora"
VERSION_ID="2"
PRETTY_NAME="Amazon Linux 2"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2"
HOME_URL="https://amazonlinux.com/"
@@ -1,9 +0,0 @@
NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
@@ -1,12 +0,0 @@
NAME="Amazon Linux"
VERSION="2022"
ID="amzn"
ID_LIKE="fedora"
VERSION_ID="2022"
PLATFORM_ID="platform:al2022"
PRETTY_NAME="Amazon Linux 2022"
ANSI_COLOR="0;33"
CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2022"
HOME_URL="https://aws.amazon.com/linux/"
BUG_REPORT_URL="https://github.com/amazonlinux/amazon-linux-2022"
SUPPORT_END="2027-11-01"
@@ -1,10 +0,0 @@
NAME="Antergos Linux"
VERSION="18.11-ISO-Rolling"
ID="antergos"
ID_LIKE="arch"
PRETTY_NAME="Antergos Linux"
CPE_NAME="cpe:/o:antergosproject:antergos:18.11"
ANSI_COLOR="1;34;40"
HOME_URL="https://antergos.com/"
SUPPORT_URL="https://forum.antergos.com/"
BUG_REPORT_URL="https://github.com/antergos"
@@ -1,11 +0,0 @@
NAME="Arch Linux"
PRETTY_NAME="Arch Linux"
ID=arch
BUILD_ID=rolling
VERSION_ID=TEMPLATE_VERSION_ID
ANSI_COLOR="38;2;23;147;209"
HOME_URL="https://archlinux.org/"
DOCUMENTATION_URL="https://wiki.archlinux.org/"
SUPPORT_URL="https://bbs.archlinux.org/"
BUG_REPORT_URL="https://bugs.archlinux.org/"
PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/"
@@ -1,11 +0,0 @@
NAME="Arch Linux ARM"
PRETTY_NAME="Arch Linux ARM"
ID=archarm
ID_LIKE=arch
BUILD_ID=rolling
ANSI_COLOR="0;36"
HOME_URL="https://archlinuxarm.org/"
DOCUMENTATION_URL="https://archlinuxarm.org/wiki"
SUPPORT_URL="https://archlinuxarm.org/forum"
BUG_REPORT_URL="https://github.com/archlinuxarm/PKGBUILDs/issues"
LOGO=archlinux
@@ -1,9 +0,0 @@
NAME=ArcoLinux
ID=arcolinux
ID_LIKE=arch
BUILD_ID=rolling
ANSI_COLOR="0;36"
HOME_URL="https://arcolinux.info/"
SUPPORT_URL="https://arcolinuxforum.com/"
BUG_REPORT_URL="https://github.com/arcolinux"
LOGO=arcolinux-hello
@@ -1,15 +0,0 @@
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
@@ -1,13 +0,0 @@
NAME="CentOS Linux"
VERSION="8"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
@@ -1,13 +0,0 @@
NAME="CentOS Stream"
VERSION="8"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Stream 8"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_SUPPORT_PRODUCT_VERSION="CentOS Stream"
@@ -1,12 +0,0 @@
NAME="Clear Linux OS"
VERSION=1
ID=clear-linux-os
ID_LIKE=clear-linux-os
VERSION_ID=38250
PRETTY_NAME="Clear Linux OS"
ANSI_COLOR="1;35"
HOME_URL="https://clearlinux.org"
SUPPORT_URL="https://clearlinux.org"
BUG_REPORT_URL="mailto:dev@lists.clearlinux.org"
PRIVACY_POLICY_URL="http://www.intel.com/privacy"
BUILD_ID=38250
@@ -1,10 +0,0 @@
NAME="ClearOS"
VERSION="7 (Final)"
ID="clearos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="ClearOS 7 (Final)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:clearos:clearos:7"
HOME_URL="https://www.clearos.com/"
BUG_REPORT_URL="https://tracker.clearos.com/"
@@ -1,9 +0,0 @@
NAME="Cumulus Linux"
VERSION_ID=3.7.2
VERSION="Cumulus Linux 3.7.2"
PRETTY_NAME="Cumulus Linux"
ID=cumulus-linux
ID_LIKE=debian
CPE_NAME=cpe:/o:cumulusnetworks:cumulus_linux:3.7.2
HOME_URL="http://www.cumulusnetworks.com/"
SUPPORT_URL="http://support.cumulusnetworks.com/"
@@ -1,9 +0,0 @@
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
@@ -1,9 +0,0 @@
PRETTY_NAME="Debian GNU/Linux 11 (bullseye)"
NAME="Debian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
@@ -1,9 +0,0 @@
PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
NAME="Debian GNU/Linux"
VERSION_ID="7"
VERSION="7 (wheezy)"
ID=debian
ANSI_COLOR="1;31"
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support/"
BUG_REPORT_URL="http://bugs.debian.org/"
@@ -1,8 +0,0 @@
PRETTY_NAME="Debian GNU/Linux 8 (jessie)"
NAME="Debian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=debian
HOME_URL="http://www.debian.org/"
SUPPORT_URL="http://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
@@ -1,9 +0,0 @@
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
VERSION_CODENAME=stretch
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
@@ -1,41 +0,0 @@
almalinux (AlmaLinux)
alpine (Alpine Linux)
amzn (Amazon Linux)
antergos (Antergos Linux)
arch (Arch Linux)
archarm (Arch Linux ARM)
arcolinux (ArcoLinux)
centos (CentOS Linux)
clear-linux-os (Clear Linux OS)
clearos (ClearOS)
cumulus-linux (Cumulus Linux)
debian (Debian GNU/Linux)
elementary (elementary OS)
endeavouros (EndeavourOS)
fedora (Fedora Linux)
gentoo (Gentoo)
ios_xr (IOS XR)
kali (Kali GNU/Linux)
linuxmint (Linux Mint)
mageia (Mageia)
manjaro (Manjaro Linux)
manjaro-arm (Manjaro ARM)
nexus (Nexus)
nixos (NixOS)
ol (Oracle Linux Server)
opensuse (openSUSE Leap)
opensuse-leap (openSUSE Leap)
pop (Pop!_OS)
rancheros (RancherOS)
raspbian (Raspbian GNU/Linux)
rhel (Red Hat Enterprise Linux)
rocky (Rocky Linux)
scientific (Scientific Linux)
slackware (Slackware)
sled (SLED)
sles (SLES)
sles_sap (SLES_SAP)
ubuntu (Ubuntu)
virtuozzo (Virtuozzo)
xcp-ng (XCP-ng)
xenenterprise (XenServer)
@@ -1,12 +0,0 @@
NAME="elementary OS"
VERSION="5.0 Juno"
ID=elementary
ID_LIKE=ubuntu
PRETTY_NAME="elementary OS 5.0 Juno"
VERSION_ID="5.0"
HOME_URL="https://elementary.io/"
SUPPORT_URL="https://elementary.io/support"
BUG_REPORT_URL="https://github.com/elementary/appcenter/issues/new"
PRIVACY_POLICY_URL="https://elementary.io/privacy-policy"
VERSION_CODENAME=juno
UBUNTU_CODENAME=juno
@@ -1,14 +0,0 @@
NAME="elementary OS"
VERSION="6 Odin"
ID=elementary
ID_LIKE=ubuntu
PRETTY_NAME="elementary OS 6 Odin"
LOGO=distributor-logo
VERSION_ID="6"
HOME_URL="https://elementary.io/"
DOCUMENTATION_URL="https://elementary.io/docs/learning-the-basics"
SUPPORT_URL="https://elementary.io/support"
BUG_REPORT_URL="https://github.com/elementary/os/issues/new"
PRIVACY_POLICY_URL="https://elementary.io/privacy-policy"
VERSION_CODENAME=odin
UBUNTU_CODENAME=focal
@@ -1,12 +0,0 @@
NAME=EndeavourOS
PRETTY_NAME=EndeavourOS
ID=endeavouros
ID_LIKE=arch
BUILD_ID=rolling
ANSI_COLOR="38;2;23;147;209"
HOME_URL='https://endeavouros.com'
DOCUMENTATION_URL='https://discovery.endeavouros.com'
SUPPORT_URL='https://forum.endeavouros.com'
BUG_REPORT_URL='https://forum.endeavouros.com/c/arch-based-related-questions/bug-reports'
PRIVACY_POLICY_URL="https://terms.archlinux.org/docs/privacy-policy/"
LOGO=endeavouros
@@ -1,18 +0,0 @@
NAME=Fedora
VERSION="28 (Cloud Edition)"
ID=fedora
VERSION_ID=28
PLATFORM_ID="platform:f28"
PRETTY_NAME="Fedora 28 (Cloud Edition)"
ANSI_COLOR="0;34"
CPE_NAME="cpe:/o:fedoraproject:fedora:28"
HOME_URL="https://fedoraproject.org/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=28
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=28
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Cloud Edition"
VARIANT_ID=cloud
@@ -1,21 +0,0 @@
NAME=Fedora
VERSION="29 (Container Image)"
ID=fedora
VERSION_ID=29
VERSION_CODENAME=""
PLATFORM_ID="platform:f29"
PRETTY_NAME="Fedora 29 (Container Image)"
ANSI_COLOR="0;34"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:29"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f29/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=29
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=29
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Container Image"
VARIANT_ID=container
@@ -1,21 +0,0 @@
NAME=Fedora
VERSION="30 (Container Image)"
ID=fedora
VERSION_ID=30
VERSION_CODENAME=""
PLATFORM_ID="platform:f30"
PRETTY_NAME="Fedora 30 (Container Image)"
ANSI_COLOR="0;34"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:30"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f30/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=30
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=30
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Container Image"
VARIANT_ID=container
@@ -1,21 +0,0 @@
NAME=Fedora
VERSION="31 (Container Image)"
ID=fedora
VERSION_ID=31
VERSION_CODENAME=""
PLATFORM_ID="platform:f31"
PRETTY_NAME="Fedora 31 (Container Image)"
ANSI_COLOR="0;34"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:31"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f31/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=31
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=31
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Container Image"
VARIANT_ID=container
@@ -1,21 +0,0 @@
NAME=Fedora
VERSION="32 (Container Image)"
ID=fedora
VERSION_ID=32
VERSION_CODENAME=""
PLATFORM_ID="platform:f32"
PRETTY_NAME="Fedora 32 (Container Image)"
ANSI_COLOR="0;34"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:32"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f32/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=32
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=32
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Container Image"
VARIANT_ID=container
@@ -1,20 +0,0 @@
VERSION="33 (Container Image)"
ID=fedora
VERSION_ID=33
VERSION_CODENAME=""
PLATFORM_ID="platform:f33"
PRETTY_NAME="Fedora 33 (Container Image)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:33"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f33/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=33
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=33
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Container Image"
VARIANT_ID=container
@@ -1,21 +0,0 @@
NAME=Fedora
VERSION="34 (Container Image)"
ID=fedora
VERSION_ID=34
VERSION_CODENAME=""
PLATFORM_ID="platform:f34"
PRETTY_NAME="Fedora 34 (Container Image)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:34"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f34/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=34
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=34
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Container Image"
VARIANT_ID=container
@@ -1,21 +0,0 @@
NAME="Fedora Linux"
VERSION="35 (Container Image)"
ID=fedora
VERSION_ID=35
VERSION_CODENAME=""
PLATFORM_ID="platform:f35"
PRETTY_NAME="Fedora Linux 35 (Container Image)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:35"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f35/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=35
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=35
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Container Image"
VARIANT_ID=container
@@ -1,22 +0,0 @@
NAME="Fedora Linux"
VERSION="36 (Container Image)"
ID=fedora
VERSION_ID=36
VERSION_CODENAME=""
PLATFORM_ID="platform:f36"
PRETTY_NAME="Fedora Linux 36 (Container Image)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:36"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f36/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=36
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=36
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
SUPPORT_END=2023-05-16
VARIANT="Container Image"
VARIANT_ID=container
@@ -1,22 +0,0 @@
NAME="Fedora Linux"
VERSION="37 (Container Image)"
ID=fedora
VERSION_ID=37
VERSION_CODENAME=""
PLATFORM_ID="platform:f37"
PRETTY_NAME="Fedora Linux 37 (Container Image)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:37"
DEFAULT_HOSTNAME="fedora"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f37/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=37
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=37
SUPPORT_END=2023-11-14
VARIANT="Container Image"
VARIANT_ID=container
@@ -1,22 +0,0 @@
NAME="Fedora Linux"
VERSION="38 (Workstation Edition)"
ID=fedora
VERSION_ID=38
VERSION_CODENAME=""
PLATFORM_ID="platform:f38"
PRETTY_NAME="Fedora Linux 38 (Workstation Edition)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:38"
DEFAULT_HOSTNAME="fedora"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f38/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=38
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=38
SUPPORT_END=2024-05-14
VARIANT="Workstation Edition"
VARIANT_ID=workstation
@@ -1,7 +0,0 @@
NAME=Gentoo
ID=gentoo
PRETTY_NAME="Gentoo/Linux"
ANSI_COLOR="1;32"
HOME_URL="https://www.gentoo.org/"
SUPPORT_URL="https://www.gentoo.org/support/"
BUG_REPORT_URL="https://bugs.gentoo.org/"
@@ -1,9 +0,0 @@
ID="ios_xr"
ID_LIKE="cisco-wrlinux wrlinux"
NAME="IOS XR"
VERSION="6.0.0.14I"
VERSION_ID="6.0.0.14I"
PRETTY_NAME="Cisco IOS XR Software, Version 6.0.0.14I"
BUILD_ID="2015-09-10-15-50-17"
HOME_URL="http://www.cisco.com"
CISCO_RELEASE_INFO="/etc/os-release"
@@ -1,10 +0,0 @@
PRETTY_NAME="Kali GNU/Linux Rolling"
NAME="Kali GNU/Linux"
ID=kali
VERSION="2018.4"
VERSION_ID="2018.4"
ID_LIKE=debian
ANSI_COLOR="1;31"
HOME_URL="https://www.kali.org/"
SUPPORT_URL="https://forums.kali.org/"
BUG_REPORT_URL="https://bugs.kali.org/"
@@ -1,11 +0,0 @@
NAME="Linux Mint"
VERSION="18.2 (Sonya)"
ID=linuxmint
ID_LIKE=ubuntu
PRETTY_NAME="Linux Mint 18.2"
VERSION_ID="18.2"
HOME_URL="http://www.linuxmint.com/"
SUPPORT_URL="http://forums.linuxmint.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/linuxmint/"
VERSION_CODENAME=sonya
UBUNTU_CODENAME=xenial
@@ -1,12 +0,0 @@
NAME="Linux Mint"
VERSION="19 (Tara)"
ID=linuxmint
ID_LIKE=ubuntu
PRETTY_NAME="Linux Mint 19"
VERSION_ID="19"
HOME_URL="https://www.linuxmint.com/"
SUPPORT_URL="https://forums.ubuntu.com/"
BUG_REPORT_URL="http://linuxmint-troubleshooting-guide.readthedocs.io/en/latest/"
PRIVACY_POLICY_URL="https://www.linuxmint.com/"
VERSION_CODENAME=tara
UBUNTU_CODENAME=bionic
@@ -1,11 +0,0 @@
NAME="Mageia"
VERSION="6"
ID=mageia
VERSION_ID=6
ID_LIKE="mandriva fedora"
PRETTY_NAME="Mageia 6"
ANSI_COLOR="1;36"
HOME_URL="http://www.mageia.org/"
SUPPORT_URL="http://www.mageia.org/support/"
BUG_REPORT_URL="https://bugs.mageia.org/"
PRIVACY_POLICY_URL="https://wiki.mageia.org/en/Privacy_policy"
@@ -1,12 +0,0 @@
NAME="Manjaro Linux"
PRETTY_NAME="Manjaro Linux"
ID=manjaro
ID_LIKE=arch
BUILD_ID=rolling
ANSI_COLOR="1;32"
HOME_URL="https://www.manjaro.org/"
DOCUMENTATION_URL="https://wiki.manjaro.org/"
SUPPORT_URL="https://forum.manjaro.org/"
BUG_REPORT_URL="https://docs.manjaro.org/reporting-bugs/"
PRIVACY_POLICY_URL="https://manjaro.org/privacy-policy/"
LOGO=manjarolinux
@@ -1,8 +0,0 @@
NAME="Manjaro ARM"
ID="manjaro-arm"
ID_LIKE="manjaro arch"
PRETTY_NAME="Manjaro ARM"
ANSI_COLOR="1;32"
HOME_URL="https://www.manjaro.org/"
SUPPORT_URL="https://forum.manjaro.org/c/arm/"
LOGO=manjarolinux
@@ -1,8 +0,0 @@
ID=nexus
ID_LIKE=wrlinux
NAME=Nexus
HOME_URL=http://www.cisco.com
BUILD_ID=TBD
VERSION="7.0(BUILDER)"
VERSION_ID="7.0(BUILDER)"
CISCO_RELEASE_INFO="/etc/os-release"
@@ -1,9 +0,0 @@
NAME=NixOS
ID=nixos
VERSION="18.09.1436.a7fd4310c0c (Jellyfish)"
VERSION_CODENAME=jellyfish
VERSION_ID="18.09.1436.a7fd4310c0c"
PRETTY_NAME="NixOS 18.09.1436.a7fd4310c0c (Jellyfish)"
HOME_URL="https://nixos.org/"
SUPPORT_URL="https://nixos.org/nixos/support.html"
BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues"
@@ -1,12 +0,0 @@
NAME="openSUSE Leap"
VERSION="15.4"
ID="opensuse-leap"
ID_LIKE="suse opensuse"
VERSION_ID="15.4"
PRETTY_NAME="openSUSE Leap 15.4"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap:15.4"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
DOCUMENTATION_URL="https://en.opensuse.org/Portal:Leap"
LOGO="distributor-logo-Leap"
@@ -1,10 +0,0 @@
NAME="openSUSE Leap"
VERSION="42.3"
ID=opensuse
ID_LIKE="suse"
VERSION_ID="42.3"
PRETTY_NAME="openSUSE Leap 42.3"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:opensuse:leap:42.3"
BUG_REPORT_URL="https://bugs.opensuse.org"
HOME_URL="https://www.opensuse.org/"
@@ -1,17 +0,0 @@
NAME="Oracle Linux Server"
VERSION="7.9"
ID="ol"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="7.9"
PRETTY_NAME="Oracle Linux Server 7.9"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:oracle:linux:7:9:server"
HOME_URL="https://linux.oracle.com/"
BUG_REPORT_URL="https://bugzilla.oracle.com/"
ORACLE_BUGZILLA_PRODUCT="Oracle Linux 7"
ORACLE_BUGZILLA_PRODUCT_VERSION=7.9
ORACLE_SUPPORT_PRODUCT="Oracle Linux"
ORACLE_SUPPORT_PRODUCT_VERSION=7.9
@@ -1,18 +0,0 @@
NAME="Oracle Linux Server"
VERSION="8.7"
ID="ol"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="8.7"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Oracle Linux Server 8.7"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:oracle:linux:8:7:server"
HOME_URL="https://linux.oracle.com/"
BUG_REPORT_URL="https://bugzilla.oracle.com/"
ORACLE_BUGZILLA_PRODUCT="Oracle Linux 8"
ORACLE_BUGZILLA_PRODUCT_VERSION=8.7
ORACLE_SUPPORT_PRODUCT="Oracle Linux"
ORACLE_SUPPORT_PRODUCT_VERSION=8.7
@@ -1,18 +0,0 @@
NAME="Oracle Linux Server"
VERSION="9.1"
ID="ol"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="9.1"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Oracle Linux Server 9.1"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:oracle:linux:9:1:server"
HOME_URL="https://linux.oracle.com/"
BUG_REPORT_URL="https://github.com/oracle/oracle-linux"
ORACLE_BUGZILLA_PRODUCT="Oracle Linux 9"
ORACLE_BUGZILLA_PRODUCT_VERSION=9.1
ORACLE_SUPPORT_PRODUCT="Oracle Linux"
ORACLE_SUPPORT_PRODUCT_VERSION=9.1
@@ -1,13 +0,0 @@
NAME="Pop!_OS"
VERSION="22.04 LTS"
ID=pop
ID_LIKE="ubuntu debian"
PRETTY_NAME="Pop!_OS 22.04 LTS"
VERSION_ID="22.04"
HOME_URL="https://pop.system76.com"
SUPPORT_URL="https://support.system76.com"
BUG_REPORT_URL="https://github.com/pop-os/pop/issues"
PRIVACY_POLICY_URL="https://system76.com/privacy"
VERSION_CODENAME=jammy
UBUNTU_CODENAME=jammy
LOGO=distributor-logo-pop-os
@@ -1,10 +0,0 @@
NAME="RancherOS"
VERSION=v1.4.2
ID=rancheros
ID_LIKE=
VERSION_ID=v1.4.2
PRETTY_NAME="RancherOS v1.4.2"
HOME_URL="http://rancher.com/rancher-os/"
SUPPORT_URL="https://forums.rancher.com/c/rancher-os"
BUG_REPORT_URL="https://github.com/rancher/os/issues"
BUILD_ID=
@@ -1,10 +0,0 @@
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
@@ -1,9 +0,0 @@
PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)"
NAME="Raspbian GNU/Linux"
VERSION_ID="8"
VERSION="8 (jessie)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
@@ -1,17 +0,0 @@
NAME="Red Hat Enterprise Linux Server"
VERSION="7.5 (Maipo)"
ID="rhel"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="7.5"
PRETTY_NAME="Red Hat Enterprise Linux Server 7.5 (Maipo)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:7.5:GA:server"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7"
REDHAT_BUGZILLA_PRODUCT_VERSION=7.5
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="7.5"
@@ -1,16 +0,0 @@
NAME="Red Hat Enterprise Linux"
VERSION="8.0 (Ootpa)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="8.0"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Red Hat Enterprise Linux 8.0 (Ootpa)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:8.0:GA"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8"
REDHAT_BUGZILLA_PRODUCT_VERSION=8.0
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.0"
@@ -1,18 +0,0 @@
NAME="Red Hat Enterprise Linux"
VERSION="9.1 (Plow)"
ID="rhel"
ID_LIKE="fedora"
VERSION_ID="9.1"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Red Hat Enterprise Linux 9.1 (Plow)"
ANSI_COLOR="0;31"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:redhat:enterprise_linux:9::baseos"
HOME_URL="https://www.redhat.com/"
DOCUMENTATION_URL="https://access.redhat.com/documentation/red_hat_enterprise_linux/9/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 9"
REDHAT_BUGZILLA_PRODUCT_VERSION=9.1
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.1"
@@ -1,16 +0,0 @@
NAME="Rocky Linux"
VERSION="8.7 (Green Obsidian)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="8.7"
PLATFORM_ID="platform:el8"
PRETTY_NAME="Rocky Linux 8.7 (Green Obsidian)"
ANSI_COLOR="0;32"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:rocky:rocky:8:GA"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
ROCKY_SUPPORT_PRODUCT="Rocky-Linux-8"
ROCKY_SUPPORT_PRODUCT_VERSION="8.7"
REDHAT_SUPPORT_PRODUCT="Rocky Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="8.7"
@@ -1,16 +0,0 @@
NAME="Rocky Linux"
VERSION="9.1 (Blue Onyx)"
ID="rocky"
ID_LIKE="rhel centos fedora"
VERSION_ID="9.1"
PLATFORM_ID="platform:el9"
PRETTY_NAME="Rocky Linux 9.1 (Blue Onyx)"
ANSI_COLOR="0;32"
LOGO="fedora-logo-icon"
CPE_NAME="cpe:/o:rocky:rocky:9::baseos"
HOME_URL="https://rockylinux.org/"
BUG_REPORT_URL="https://bugs.rockylinux.org/"
ROCKY_SUPPORT_PRODUCT="Rocky-Linux-9"
ROCKY_SUPPORT_PRODUCT_VERSION="9.1"
REDHAT_SUPPORT_PRODUCT="Rocky Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="9.1"
@@ -1,15 +0,0 @@
NAME="Scientific Linux"
VERSION="7.5 (Nitrogen)"
ID="scientific"
ID_LIKE="rhel centos fedora"
VERSION_ID="7.5"
PRETTY_NAME="Scientific Linux 7.5 (Nitrogen)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:scientificlinux:scientificlinux:7.5:GA"
HOME_URL="http://www.scientificlinux.org//"
BUG_REPORT_URL="mailto:scientific-linux-devel@listserv.fnal.gov"
REDHAT_BUGZILLA_PRODUCT="Scientific Linux 7"
REDHAT_BUGZILLA_PRODUCT_VERSION=7.5
REDHAT_SUPPORT_PRODUCT="Scientific Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="7.5"
@@ -1,10 +0,0 @@
NAME=Slackware
VERSION="14.2"
ID=slackware
VERSION_ID=14.2
PRETTY_NAME="Slackware 14.2"
ANSI_COLOR="0;34"
CPE_NAME="cpe:/o:slackware:slackware_linux:14.2"
HOME_URL="http://slackware.com/"
SUPPORT_URL="http://www.linuxquestions.org/questions/slackware-14/"
BUG_REPORT_URL="http://www.linuxquestions.org/questions/slackware-14/"
@@ -1,7 +0,0 @@
NAME="SLED"
VERSION="12-SP3"
VERSION_ID="12.3"
PRETTY_NAME="SUSE Linux Enterprise Desktop 12 SP3"
ID="sled"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:suse:sled:12:sp3"

Some files were not shown because too many files have changed in this diff Show More