Skip to content

Commit

Permalink
Audit and overhaul postgrestd internals (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
workingjubilee authored Mar 13, 2023
2 parents 1368785 + 7337d19 commit 7b38505
Show file tree
Hide file tree
Showing 40 changed files with 1,022 additions and 870 deletions.
21 changes: 21 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,24 @@ jobs:
CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER: x86_64-linux-gnu-gcc
CARGO_TARGET_AARCH64_POSTGRES_LINUX_GNU_LINKER: cc

test_macos:
name: "macos build & test (experimental)"
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'

- name: Install rust
run: |
export RUSTUP_HOME="$HOME/.rustup"
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
rustup toolchain install 1.67.1
cargo --version
- name: Print env
run: env

- name: Build/install both apple targets
run: ./run install
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ members = [
exclude = [
# stdarch has its own Cargo workspace
"library/stdarch",
# "postbuild",
]

[profile.release]
Expand Down Expand Up @@ -59,7 +60,7 @@ object.debug = 0
debug = 0
[profile.dev.package]
# Only use debuginfo=1 to further reduce compile times.
bootstrap.debug = 1
# bootstrap.debug = 1



Expand Down
69 changes: 69 additions & 0 deletions aarch64-apple-darwin-postgres.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"abi-return-struct-as-int": true,
"arch": "aarch64",
"archive-format": "darwin",
"cpu": "apple-a14",
"data-layout": "e-m:o-i64:64-i128:128-n32:64-S128",
"debuginfo-kind": "dwarf-dsym",
"default-dwarf-version": 2,
"dll-suffix": ".dylib",
"dynamic-linking": true,
"eh-frame-header": false,
"emit-debug-gdb-scripts": false,
"frame-pointer": "non-leaf",
"function-sections": false,
"has-rpath": true,
"has-thread-local": true,
"is-like-osx": true,
"link-env": [
"ZERO_AR_DATE=1"
],
"link-env-remove": [
"IPHONEOS_DEPLOYMENT_TARGET"
],
"linker-is-gnu": false,
"lld-flavor": "darwin",
"llvm-target": "arm64-apple-macosx11.0.0",
"max-atomic-width": 128,
"os": "macos",
"pre-link-args": {
"gcc": [
"-arch",
"arm64"
],
"ld": [
"-arch",
"arm64",
"-platform_version",
"macos",
"11.0",
"11.0"
],
"ld64.lld": [
"-arch",
"arm64",
"-platform_version",
"macos",
"11.0",
"11.0"
]
},
"split-debuginfo": "packed",
"supported-sanitizers": [
"address",
"cfi",
"thread"
],
"supported-split-debuginfo": [
"packed",
"unpacked",
"off"
],
"target-family": [
"unix",
"postgres"
],
"target-mcount": "\u0001mcount",
"target-pointer-width": "64",
"vendor": "apple"
}
22 changes: 16 additions & 6 deletions block.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Rust `std` modules with impacted functionality:
- arch - SIMD and vendor intrinsics module.
- Technically available but in practice unusable (it is almost entirely `unsafe`)
- backtrace - Support for capturing a stack backtrace of an OS thread
- Backtraces are currently always disabled.
- env - Inspection and manipulation of the process’s environment.
- May panic, return `Err("unsupported operation")`, or have arbitrary results.
- fs - Filesystem manipulation operations.
- May panic, return `Err("unsupported operation")`, or have arbitrary results (e.g. `is_file` always returns `false`)
- io - Traits, helpers, and type definitions for core I/O functionality.
Expand All @@ -9,20 +13,31 @@ Rust `std` modules with impacted functionality:
- May panic, return `Err("unsupported operation")`, or have arbitrary results.
- os - OS-specific functionality.
- May panic, return `Err("unsupported operation")`, or have arbitrary results.
- Some infrequently used OS-specific submodules with complex APIs we would need to disable are entirely missing (`std::os::unix::net`, for example), although this will hopefully be improved.
- panic - Panic support in the standard library.
- Some functionality, like changing the panic handler, is unsupported.
- Panic information is not output to stderr (because writing to standard streams is not possible).
- path - Cross-platform path manipulation.
- Path operations that do not rely on the filesystem or current working directory should work.
- process - A module for working with processes.
- May panic, return `Err("unsupported operation")`, or have arbitrary results.
- ptr - Manually manage memory through raw pointers.
- Technically available but in practice unusable (it is almost entirely `unsafe`)
- sync - "Useful" synchronization primitives.
- Not actually very useful without threading.
- Atomics function as normal, as does Arc. Anything backed by syscalls will fail.
- thread - Native threads.
- May panic, return `Err("unsupported operation")`, or have arbitrary results.
- time - Temporal quantification.
- `SystemTime` and `Instant` may panic, return `Err("unsupported operation")`, or have arbitrary results.
- `Duration` should be fine.


Other Rust `std` modules:
- alloc - Memory allocation APIs.
- any - Utilities for dynamic typing or type reflection.
- array - Utilities for the array primitive type.
- ascii - Operations on ASCII strings and characters.
- backtrace - Support for capturing a stack backtrace of an OS thread
- borrow - A module for working with borrowed data.
- boxed - The `Box<T>` type for heap allocation.
- cell - Shareable mutable containers.
Expand All @@ -31,7 +46,6 @@ Other Rust `std` modules:
- collection - Collection types.
- convert - Traits for conversions between types.
- default - The Default trait for types with a default value.
- env - Inspection and manipulation of the process’s environment.
- error - Interfaces for working with Errors.
- ffi - Utilities related to FFI bindings.
- fmt - Utilities for formatting and printing Strings.
Expand All @@ -44,8 +58,6 @@ Other Rust `std` modules:
- num - Additional functionality for numerics.
- ops - Overloadable operators.
- option - Optional values.
- panic - Panic support in the standard library.
- path - Cross-platform path manipulation.
- pin - Types that pin data to its location in memory.
- prelude - The Rust Prelude
- primitive - This module reexports the primitive types to allow usage that is not possibly shadowed by other declared types.
Expand All @@ -54,7 +66,5 @@ Other Rust `std` modules:
- slice - Utilities for the slice primitive type.
- str - Utilities for the str primitive type.
- string - A UTF-8–encoded, growable string.
- sync - Useful synchronization primitives.
- task - Types and Traits for working with asynchronous tasks.
- time - Temporal quantification.
- vec - A contiguous growable array type with heap-allocated contents, written `Vec<T>`.
File renamed without changes.
205 changes: 205 additions & 0 deletions library/std/src/backtrace/unsupported.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
//! Support for capturing a stack backtrace of an OS thread
//!
//! This module contains the support necessary to capture a stack backtrace of a
//! running OS thread from the OS thread itself. The `Backtrace` type supports
//! capturing a stack trace via the `Backtrace::capture` and
//! `Backtrace::force_capture` functions.
//!
//! A backtrace is typically quite handy to attach to errors (e.g. types
//! implementing `std::error::Error`) to get a causal chain of where an error
//! was generated.
//!
//! ## Accuracy
//!
//! Backtraces are attempted to be as accurate as possible, but no guarantees
//! are provided about the exact accuracy of a backtrace. Instruction pointers,
//! symbol names, filenames, line numbers, etc, may all be incorrect when
//! reported. Accuracy is attempted on a best-effort basis, however, any bug
//! reports are always welcome to indicate areas of improvement!
//!
//! For most platforms a backtrace with a filename/line number requires that
//! programs be compiled with debug information. Without debug information
//! filenames/line numbers will not be reported.
//!
//! ## Platform support
//!
//! Not all platforms that libstd compiles for support capturing backtraces.
//! Some platforms simply do nothing when capturing a backtrace. To check
//! whether the platform supports capturing backtraces you can consult the
//! `BacktraceStatus` enum as a result of `Backtrace::status`.
//!
//! Like above with accuracy platform support is done on a best effort basis.
//! Sometimes libraries might not be available at runtime or something may go
//! wrong which would cause a backtrace to not be captured. Please feel free to
//! report issues with platforms where a backtrace cannot be captured though!
//!
//! ## Environment Variables
//!
//! The `Backtrace::capture` function might not actually capture a backtrace by
//! default. Its behavior is governed by two environment variables:
//!
//! * `RUST_LIB_BACKTRACE` - if this is set to `0` then `Backtrace::capture`
//! will never capture a backtrace. Any other value set will enable
//! `Backtrace::capture`.
//!
//! * `RUST_BACKTRACE` - if `RUST_LIB_BACKTRACE` is not set, then this variable
//! is consulted with the same rules of `RUST_LIB_BACKTRACE`.
//!
//! * If neither of the above env vars are set, then `Backtrace::capture` will
//! be disabled.
//!
//! Capturing a backtrace can be a quite expensive runtime operation, so the
//! environment variables allow either forcibly disabling this runtime
//! performance hit or allow selectively enabling it in some programs.
//!
//! Note that the `Backtrace::force_capture` function can be used to ignore
//! these environment variables. Also note that the state of environment
//! variables is cached once the first backtrace is created, so altering
//! `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` at runtime might not actually change
//! how backtraces are captured.
#![stable(feature = "backtrace", since = "1.65.0")]
// Fully no-disabled version of `std::backtrace`, to avoid the various downsides
// inherent in producing backtraces.
//
// FIXME(thom): this is a terrible way to stub this out, and risks accidentally
// drifting from the public backtrace API :(
use crate::fmt;

/// A captured OS thread stack backtrace.
///
/// This type represents a stack backtrace for an OS thread captured at a
/// previous point in time. In some instances the `Backtrace` type may
/// internally be empty due to configuration. For more information see
/// `Backtrace::capture`.
#[stable(feature = "backtrace", since = "1.65.0")]
#[must_use]
pub struct Backtrace {
inner: Inner,
}

/// The current status of a backtrace, indicating whether it was captured or
/// whether it is empty for some other reason.
#[stable(feature = "backtrace", since = "1.65.0")]
#[non_exhaustive]
#[derive(Debug, PartialEq, Eq)]
pub enum BacktraceStatus {
/// Capturing a backtrace is not supported, likely because it's not
/// implemented for the current platform.
#[stable(feature = "backtrace", since = "1.65.0")]
Unsupported,
/// Capturing a backtrace has been disabled through either the
/// `RUST_LIB_BACKTRACE` or `RUST_BACKTRACE` environment variables.
#[stable(feature = "backtrace", since = "1.65.0")]
Disabled,
/// A backtrace has been captured and the `Backtrace` should print
/// reasonable information when rendered.
#[stable(feature = "backtrace", since = "1.65.0")]
Captured,
}

enum Inner {
Unsupported,
Disabled,
}

/// A single frame of a backtrace.
#[unstable(feature = "backtrace_frames", issue = "79676")]
pub struct BacktraceFrame {
_private: (),
}

#[stable(feature = "backtrace", since = "1.65.0")]
impl fmt::Debug for Backtrace {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.inner {
Inner::Unsupported => fmt.write_str("<unsupported>"),
Inner::Disabled => fmt.write_str("<disabled>"),
}
}
}

#[unstable(feature = "backtrace_frames", issue = "79676")]
impl fmt::Debug for BacktraceFrame {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.debug_list().finish()
}
}

impl Backtrace {
/// Capture a stack backtrace of the current thread.
///
/// This function will capture a stack backtrace of the current OS thread of
/// execution, returning a `Backtrace` type which can be later used to print
/// the entire stack trace or render it to a string.
///
/// This function will be a noop if the `RUST_BACKTRACE` or
/// `RUST_LIB_BACKTRACE` backtrace variables are both not set. If either
/// environment variable is set and enabled then this function will actually
/// capture a backtrace. Capturing a backtrace can be both memory intensive
/// and slow, so these environment variables allow liberally using
/// `Backtrace::capture` and only incurring a slowdown when the environment
/// variables are set.
///
/// To forcibly capture a backtrace regardless of environment variables, use
/// the `Backtrace::force_capture` function.
#[stable(feature = "backtrace", since = "1.65.0")]
pub fn capture() -> Backtrace {
Backtrace { inner: Inner::Unsupported }
}

/// Forcibly captures a full backtrace, regardless of environment variable
/// configuration.
///
/// This function behaves the same as `capture` except that it ignores the
/// values of the `RUST_BACKTRACE` and `RUST_LIB_BACKTRACE` environment
/// variables, always capturing a backtrace.
///
/// Note that capturing a backtrace can be an expensive operation on some
/// platforms, so this should be used with caution in performance-sensitive
/// parts of code.
#[stable(feature = "backtrace", since = "1.65.0")]
#[inline(never)] // want to make sure there's a frame here to remove
pub fn force_capture() -> Backtrace {
Backtrace { inner: Inner::Unsupported }
}

/// Forcibly captures a disabled backtrace, regardless of environment
/// variable configuration.
#[stable(feature = "backtrace", since = "1.65.0")]
#[rustc_const_stable(feature = "backtrace", since = "1.65.0")]
pub const fn disabled() -> Backtrace {
Backtrace { inner: Inner::Disabled }
}

/// Returns the status of this backtrace, indicating whether this backtrace
/// request was unsupported, disabled, or a stack trace was actually
/// captured.
#[stable(feature = "backtrace", since = "1.65.0")]
#[must_use]
pub fn status(&self) -> BacktraceStatus {
match self.inner {
Inner::Unsupported => BacktraceStatus::Unsupported,
Inner::Disabled => BacktraceStatus::Disabled,
}
}
}

impl<'a> Backtrace {
/// Returns an iterator over the backtrace frames.
#[must_use]
#[unstable(feature = "backtrace_frames", issue = "79676")]
pub fn frames(&'a self) -> &'a [BacktraceFrame] {
&[]
}
}

#[stable(feature = "backtrace", since = "1.65.0")]
impl fmt::Display for Backtrace {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.inner {
Inner::Unsupported => fmt.write_str("unsupported backtrace"),
Inner::Disabled => fmt.write_str("disabled backtrace"),
}
}
}
1 change: 1 addition & 0 deletions library/std/src/io/stdio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ impl Read for Stdin {

// only used by platform-dependent io::copy specializations, i.e. unused on some platforms
#[cfg(any(target_os = "linux", target_os = "android"))]
#[cfg(not(target_family = "postgres"))]
impl StdinLock<'_> {
pub(crate) fn as_mut_buf(&mut self) -> &mut BufReader<impl Read> {
&mut self.inner
Expand Down
Loading

0 comments on commit 7b38505

Please sign in to comment.