Fix #7239: Prefix exeutions with stdbuf -o0 (#7378)

Please note this adds the anti-stdout-buffering machinery to all
executions - *including of the compilers themselves*. I think this is a
good thing.

I (hope I) excluded execution on windows. Are there other needed
exceptions?
This commit is contained in:
Ofek
2025-02-17 00:55:53 +02:00
committed by GitHub
parent bbdad0fe8e
commit a457221f7a
3 changed files with 27 additions and 1 deletions

View File

@@ -1,3 +1,4 @@
sandboxType=cewrapper
executionType=cewrapper
cewrapper=C:/cewrapper/cewrapper.exe
unbufferStdoutExe=

View File

@@ -14,3 +14,8 @@ firejail.profile.wine=etc/firejail/wine.profile
cewrapper=
cewrapper.config.sandbox=etc/cewrapper/user-execution.json
cewrapper.config.execute=etc/cewrapper/compilers-and-tools.json
# Prefix execution with `stdbuf -o0` to have stdout output also for crashing executions.
# Discussed further in https://github.com/compiler-explorer/compiler-explorer/issues/7239
unbufferStdoutExe=stdbuf
unbufferStdoutArgs=-o0

View File

@@ -26,6 +26,9 @@ import buffer from 'buffer';
import child_process from 'node:child_process';
import os from 'node:os';
import path from 'node:path';
// @ts-ignore
import which from 'which';
import {Stream} from 'node:stream';
import fs from 'fs-extra';
@@ -35,6 +38,7 @@ import _ from 'underscore';
import type {ExecutionOptions} from '../types/compilation/compilation.interfaces.js';
import type {FilenameTransformFunc, UnprocessedExecResult} from '../types/execution/execution.interfaces.js';
import {splitArguments} from '../shared/common-utils.js';
import {assert, unwrap, unwrapString} from './assert.js';
import {logger} from './logger.js';
import {Graceful} from './node-graceful.js';
@@ -49,6 +53,8 @@ type NsJailOptions = {
const execProps = propsFor('execution');
let stdbufPath = null;
function checkExecOptions(options: ExecutionOptions) {
if (options.env) {
for (const key of Object.keys(options.env)) {
@@ -68,7 +74,7 @@ function setupOnError(stream: Stream, name: string) {
});
}
export function executeDirect(
export async function executeDirect(
command: string,
args: string[],
options: ExecutionOptions,
@@ -91,6 +97,20 @@ export function executeDirect(
if (command.startsWith('./')) command = path.join(process.cwd(), command);
}
if (stdbufPath == null) {
const unbufferStdoutExe = execProps<string>('unbufferStdoutExe', undefined); // by default 'stdout'
if (unbufferStdoutExe) {
stdbufPath = await which(unbufferStdoutExe);
if (!stdbufPath) logger.error(`Could not find ${unbufferStdoutExe} in PATH`);
}
}
if (stdbufPath) {
const stdbufArgs = splitArguments(execProps<string>('unbufferStdoutArgs', undefined)); // by default ['-o0']
args.unshift(...stdbufArgs, command);
command = stdbufPath;
}
let okToCache = true;
let timedOut = false;
// In WSL; run Windows-volume executables in a temp directory.