Files
browser/src/core_dump.zig
Karl Seguin 8e42d63c1c zig: Zig 0.16
Built against https://github.com/lightpanda-io/zig-v8-fork/tree/zig-0.16 but
it doesn't require a new v8 build.

Built against https://github.com/lightpanda-io/boringssl-zig/tree/zig-0.16
since the current fork we point to isn't updated.

A global std.Io instance, lp.io. Way easier this way and requires 0 changes to
our libcurl integration / event loop.

Network code uses a new layer that does what Zig 0.15's posix package used to
do. Again, quicker migration that way. But, as long as we have the global IO,
and given the half-baked nature of networking in std.Io 0.16, this just makes
sense. Things can be migrated as needed.

The std.time.* -> std.Io.Timestamp/Clock/Duration resulted in _a lot_ of
changes. ArrayList = .{} -> ArrayList -> .empty also resulted in a lot of
changes, but that's obviously superficial. As is the trimLeft/trimRight ->
trimStart/trimEnd rename.

Locking adopt the `Uncancelable` variants, e.g. mutex.lockUncancelable() to
preserve the error-free signature (and, because cancellation would be something
we'd have to put more thought into).

std.json.ObjectMap is now unmanaged, so the allocator had to be passed along.
However, there's still a deprecated managed variant of MemoryPool, so I switched
to it (we can do a small follow up PR to move to the unmanaged after).

I tried use_llvm = false, but it locks my computer, consuming RAM until MacOS
gives me a popup I've never seen before, begging me to start killing processes.

Agent and the networking stuff saw the most significant changes.
2026-07-22 13:26:03 +08:00

83 lines
3.1 KiB
Zig

// Copyright (C) 2023-2026 Lightpanda (Selecy SAS)
//
// Francis Bouvier <francis@lightpanda.io>
// Pierre Tachoire <pierre@lightpanda.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//! Opt-in core-dump suppression.
//!
//! Lightpanda has no SIGSEGV handler, so a segfault (or the `abort()` in the
//! panic path) falls through to the kernel and writes a core dump. When many
//! instances run under a shared `core_pattern` crash reporter — e.g. a
//! containerized crawl fleet — those dumps become pure storage and alert
//! noise, and a browser core can capture the contents of arbitrary pages.
//! Crashes are already reported via telemetry, so `LIGHTPANDA_DISABLE_CORE_DUMP`
//! lets an operator drop the cores while leaving the default behavior
//! (and local debugging) untouched.
const std = @import("std");
const builtin = @import("builtin");
const lp = @import("lightpanda.zig");
const log = lp.log;
pub fn disableIfRequested() void {
if (!shouldDisable()) return;
disable() catch |err| {
log.warn(.app, "could not disable core dumps", .{ .err = err });
};
}
fn shouldDisable() bool {
if (builtin.os.tag == .windows) return false;
return std.c.getenv("LIGHTPANDA_DISABLE_CORE_DUMP") != null;
}
// Zeroes only the soft limit; that is what the kernel consults when deciding
// whether to dump (including the piped-`core_pattern` opt-out), and keeping the
// hard limit lets the process raise it again if it ever needs to.
fn disable() !void {
var limit = try std.posix.getrlimit(.CORE);
limit.cur = 0;
try std.posix.setrlimit(.CORE, limit);
}
const testing = @import("testing.zig");
extern fn setenv(name: [*:0]u8, value: [*:0]u8, override: c_int) c_int;
extern fn unsetenv(name: [*:0]u8) c_int;
test "core_dump: disabled only when the env var is set" {
_ = unsetenv(@constCast("LIGHTPANDA_DISABLE_CORE_DUMP"));
try testing.expectEqual(false, shouldDisable());
_ = setenv(@constCast("LIGHTPANDA_DISABLE_CORE_DUMP"), @constCast(""), 1);
defer _ = unsetenv(@constCast("LIGHTPANDA_DISABLE_CORE_DUMP"));
try testing.expectEqual(true, shouldDisable());
}
test "core_dump: disable zeroes the soft RLIMIT_CORE" {
if (builtin.os.tag == .windows) return;
const original = try std.posix.getrlimit(.CORE);
defer std.posix.setrlimit(.CORE, original) catch {};
try disable();
const after = try std.posix.getrlimit(.CORE);
try testing.expectEqual(@as(@TypeOf(after.cur), 0), after.cur);
try testing.expectEqual(original.max, after.max);
}