Skip to content

OOM killer kicks in while editing a macro (very short time span; 1-5 mins) #18734

Open
@briancarbone

Description

@briancarbone

rust-analyzer version: rust-analyzer 1.85.0-nightly (5f23ef7 2024-12-20)

rustc version: rustc 1.85.0-nightly (5f23ef7d3 2024-12-20)

editor or extension: Vim + LSP plugin

relevant settings:

    initializationOptions: {
      cargo: {
        features: 'all',
      },
      completion: {
        postfix: {
          enable: false,
        },
      },
      imports: {
        group: {
          enable: false,
        },
      },
    },

I was working on the macro at the bottom (this code won't compile as-is), but when I start working, memory usage explodes to use all 64 GB and vim/tmux crashes. It's probably worth noting this is the first macro I've ever tried writing so I'm learning, but I wouldn't expect rust-analyzer to crash due to user error.

(Unrelated: I am aware of the function pointer closure capturing a variable which it can't do—leaving everything in this state for the purpose of the bug report.)

code snippet to reproduce:

use futures::future::join_all;
use lol_html::{
    element, html_content::ContentType, ElementContentHandlers, HandlerTypes, LocalHandlerTypes,
    Selector,
};
use std::{
    borrow::Cow,
    collections::{HashMap, HashSet},
    future::Future,
    pin::Pin,
};

type ElementHandlerArray<'h> = Vec<(Cow<'static, Selector>, ElementContentHandlers<'h>)>;

type FormData = Vec<(String, String)>;
type ValidationResult<'h> = Result<(), ElementHandlerArray<'h>>;
type Validation<'h> =
    fn(&'static str, Option<&'h str>) -> Pin<Box<dyn Future<Output = ValidationResult<'h>>>>;
type Field<'h> = (&'static str, Validation<'h>);

struct Form<'h> {
    id: &'static str,
    fields: Vec<Field<'h>>,
}

impl<'h> Form<'h> {
    pub fn new(id: &'static str, fields: Vec<Field<'h>>) -> Self {
        Self { id, fields }
    }

    pub async fn validate(&self, formdata: &'h FormData) -> Result<(), ElementHandlerArray<'h>> {
        let field_names: HashSet<_> = self.fields.iter().map(|&(k, _)| k).collect();

        let (map, err) = formdata.into_iter().fold(
            (HashMap::with_capacity(formdata.len()), false),
            |(mut map, err), (k, v)| {
                let duplicate = map.insert(k.as_str(), v.as_str()).is_some();
                (map, err || duplicate || !field_names.contains(k.as_str()))
            },
        );

        if err {
            let tx = vec![element!(
                format!(r#"form[data-form-id="{}"] > .message"#, self.id),
                |el| {
                    el.set_inner_content("Internal error", ContentType::Text);
                    Ok(())
                }
            )];
            return Err(tx);
        }

        let validations: Vec<_> = self
            .fields
            .iter()
            .map(|&(name, validator)| validator(self.id, map.get(name).map(|&v| v)))
            .collect();

        let results = join_all(validations).await;

        let errors: Vec<_> = results
            .into_iter()
            .filter_map(|r| r.err())
            .flat_map(|e| e)
            .collect();

        if errors.is_empty() {
            Ok(())
        } else {
            Err(errors)
        }
    }
}

macro_rules! validation {
    ($field:expr, $check:expr, $message:expr) => {
        |form_id: &str, value: Option<&str>| {
            let check = $check;
            Box::pin(async move {
                if !(check(value).await) {
                    let x = vec![element!(
                        format!(
                            r#"form[data-form-id="{}"] input[name="{}"] .message"#,
                            form_id, $field
                        ),
                        |el| {
                            el.set_inner_content($message, ContentType::Text);
                            Ok(())
                        }
                    )];
                    Err(x)
                } else {
                    Ok(())
                }
            })
        }
    };
}

pub fn make_required(field_name: &'static str) -> Validation<'_> {
}

const REQUIRED: fn(&'static str) -> Validation<'static> = |field_name| {
    validation!(
        field_name,
        async |a: Option<&str>| { a.is_some_and(|v| !v.is_empty()) },
        "ok"
    )
};

journal output w/ OOM killer

Dec 21 17:00:02 nixbox systemd[1]: logrotate.service: Deactivated successfully.
Dec 21 17:00:02 nixbox systemd[1]: Finished Logrotate Service.
Dec 21 18:00:25 nixbox systemd[1]: Starting Logrotate Service...
Dec 21 18:00:25 nixbox systemd[1]: logrotate.service: Deactivated successfully.
Dec 21 18:00:25 nixbox systemd[1]: Finished Logrotate Service.
Dec 21 18:02:23 nixbox kernel: rustc invoked oom-killer: gfp_mask=0x140cca(GFP_HIGHUSER_MOVABLE|__GFP_COMP), order=0, oom_score_adj=0
Dec 21 18:02:23 nixbox kernel: CPU: 6 UID: 1000 PID: 102429 Comm: rustc Tainted: P        W  O       6.12.5 #1-NixOS
Dec 21 18:02:23 nixbox kernel: Tainted: [P]=PROPRIETARY_MODULE, [W]=WARN, [O]=OOT_MODULE
Dec 21 18:02:23 nixbox kernel: Hardware name: Gigabyte Technology Co., Ltd. X570 AORUS MASTER/X570 AORUS MASTER, BIOS F39d 09/02/2024
Dec 21 18:02:23 nixbox kernel: Call Trace:
Dec 21 18:02:23 nixbox kernel:  <TASK>
Dec 21 18:02:23 nixbox kernel:  dump_stack_lvl+0x64/0x90
Dec 21 18:02:23 nixbox kernel:  dump_header+0x44/0x1c0
Dec 21 18:02:23 nixbox kernel:  oom_kill_process+0x104/0x210
Dec 21 18:02:23 nixbox kernel:  out_of_memory+0x256/0x590
Dec 21 18:02:23 nixbox kernel:  __alloc_pages_noprof+0xfdf/0x1130
--
Dec 21 18:02:23 nixbox kernel: [  65171]  1000 65171      690      137        0      137         0    32768        0             0 .wl-copy-wrappe
Dec 21 18:02:23 nixbox kernel: [ 102419]  1000 102419    66526     6980     6764      216         0   176128        0             0 cargo
Dec 21 18:02:23 nixbox kernel: [ 102424]  1000 102424  7979899  7040933  7040384      549         0 62279680        0             0 rustc
Dec 21 18:02:23 nixbox kernel: [ 102425]  1000 102425  8005727  7063544  7063296      248         0 62509056        0             0 rustc
Dec 21 18:02:23 nixbox kernel: [ 102505]  1000 102505   618837     4904     4291      419       194   548864        0           100 Isolated Servic
Dec 21 18:02:23 nixbox kernel: oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=user.slice,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1000.slice/user@1000.service/tmux-spawn-1fc8d326-38c3-4460-8f2e-9550aa8c2c0b.scope,task=rustc,pid=102425,uid=1000
Dec 21 18:02:23 nixbox kernel: Out of memory: Killed process 102425 (rustc) total-vm:32022908kB, anon-rss:28253184kB, file-rss:992kB, shmem-rss:0kB, UID:1000 pgtables:61044kB oom_score_adj:0
Dec 21 18:02:23 nixbox systemd[2107]: tmux-spawn-1fc8d326-38c3-4460-8f2e-9550aa8c2c0b.scope: A process of this unit has been killed by the OOM killer.
Dec 21 18:02:23 nixbox systemd[1]: user@1000.service: A process of this unit has been killed by the OOM killer.
Dec 21 18:02:25 nixbox systemd[2107]: tmux-spawn-1fc8d326-38c3-4460-8f2e-9550aa8c2c0b.scope: Failed with result 'oom-kill'.
Dec 21 18:02:25 nixbox systemd[2107]: tmux-spawn-1fc8d326-38c3-4460-8f2e-9550aa8c2c0b.scope: Consumed 5min 5.541s CPU time, 54.9G memory peak.
Dec 21 18:02:35 nixbox systemd[2107]: Started tmux child pane 102622 launched by process 102621.
Dec 21 18:02:49 nixbox nix-daemon[1711]: accepted connection from pid 102699, user brian (trusted)
Dec 21 18:02:54 nixbox nix-daemon[1711]: accepted connection from pid 102740, user brian (trusted)
Dec 21 18:03:25 nixbox rtkit-daemon[2863]: Successfully made thread 103217 of process 103078 owned by '1000' RT at priority 10.
Dec 21 18:27:18 nixbox kernel: rustc invoked oom-killer: gfp_mask=0x140dca(GFP_HIGHUSER_MOVABLE|__GFP_COMP|__GFP_ZERO), order=0, oom_score_adj=0
Dec 21 18:27:18 nixbox kernel: CPU: 21 UID: 1000 PID: 110988 Comm: rustc Tainted: P        W  O       6.12.5 #1-NixOS
Dec 21 18:27:18 nixbox kernel: Tainted: [P]=PROPRIETARY_MODULE, [W]=WARN, [O]=OOT_MODULE
Dec 21 18:27:18 nixbox kernel: Hardware name: Gigabyte Technology Co., Ltd. X570 AORUS MASTER/X570 AORUS MASTER, BIOS F39d 09/02/2024
Dec 21 18:27:18 nixbox kernel: Call Trace:
Dec 21 18:27:18 nixbox kernel:  <TASK>
Dec 21 18:27:18 nixbox kernel:  dump_stack_lvl+0x64/0x90
Dec 21 18:27:18 nixbox kernel:  dump_header+0x44/0x1c0
Dec 21 18:27:18 nixbox kernel:  oom_kill_process+0x104/0x210
Dec 21 18:27:18 nixbox kernel:  out_of_memory+0x256/0x590
Dec 21 18:27:18 nixbox kernel:  __alloc_pages_noprof+0xfdf/0x1130
--
Dec 21 18:27:18 nixbox kernel: [ 110905]  1000 110905   616324     6121     3737     2190       194   462848        0           233 Web Content
Dec 21 18:27:18 nixbox kernel: [ 110979]  1000 110979    66540     7295     6775      520         0   176128        0             0 cargo
Dec 21 18:27:18 nixbox kernel: [ 110984]  1000 110984  7860607  6896524  6896238      286         0 61063168        0             0 rustc
Dec 21 18:27:18 nixbox kernel: [ 110985]  1000 110985  7888959  6936565  6936064      501         0 61366272        0             0 rustc
Dec 21 18:27:18 nixbox kernel: [ 111026]  1000 111026   616324     5773     3604     1975       194   462848        0           233 Web Content
Dec 21 18:27:18 nixbox kernel: oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=user.slice,mems_allowed=0,global_oom,task_memcg=/user.slice/user-1000.slice/user@1000.service/tmux-spawn-a41953ec-3e11-482c-bb2c-90af560aca2b.scope,task=rustc,pid=110985,uid=1000
Dec 21 18:27:18 nixbox kernel: Out of memory: Killed process 110985 (rustc) total-vm:31555836kB, anon-rss:27744256kB, file-rss:2004kB, shmem-rss:0kB, UID:1000 pgtables:59928kB oom_score_adj:0
Dec 21 18:27:18 nixbox systemd[2107]: tmux-spawn-a41953ec-3e11-482c-bb2c-90af560aca2b.scope: A process of this unit has been killed by the OOM killer.
Dec 21 18:27:18 nixbox systemd[1]: user@1000.service: A process of this unit has been killed by the OOM killer.
Dec 21 18:27:20 nixbox systemd[2107]: tmux-spawn-a41953ec-3e11-482c-bb2c-90af560aca2b.scope: Failed with result 'oom-kill'.
Dec 21 18:27:20 nixbox systemd[2107]: tmux-spawn-a41953ec-3e11-482c-bb2c-90af560aca2b.scope: Consumed 1min 6.001s CPU time, 53.8G memory peak.
Dec 21 18:35:15 nixbox sudo[113234]:    brian : TTY=pts/0 ; PWD=/home/brian/dev/unifyr ; USER=root ; COMMAND=/run/current-system/sw/bin/dmesg
Dec 21 18:35:15 nixbox sudo[113234]: pam_unix(sudo:session): session opened for user root(uid=0) by brian(uid=1000)
Dec 21 18:35:15 nixbox sudo[113234]: pam_unix(sudo:session): session closed for user root

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-supportCategory: support questions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions