Закулисный конкурс: Война ОС [закрыто]


29

Все мы знаем, как дискуссия о том, какая операционная система является лучшей, вызвала много пламенных войн. Теперь ваша цель - предоставить решающее «доказательство» того, что ваша любимая операционная система лучше ... ах, нет, намного лучше, предоставить решающее «доказательство» того, что другая операционная система плохая.

Задача: написать программу, которая выполняет некоторые вычисления, и она работает корректно как минимум на одной ОС и неправильно на хотя бы еще одной.

  • программа должна выполнить, по крайней мере, некоторые вычисления, поэтому она должна прочитать какой-то простой ввод (предпочтительно на стандартный ввод или, если хотите, из файлов, но неправильное использование байтов с прямым и обратным порядком байтов не только будет дешевым, но и очевидным) , и предоставить некоторый вывод в зависимости от ввода. Расчеты должны быть осмысленными и обоснованными, например, решение реальной жизни или математическая задача.
  • Вы должны указать обе операционные системы, указав, какая из них будет работать правильно, а какая - нет. Обе операционные системы должны быть хорошо известны и примерно в одно и то же время (поэтому не DOS 1.0, а современная ОС). Рекомендуется предоставить краткое описание причины разницы (особенно если вы подозреваете, что многие этого не осознают) в тегах спойлера.

так

  • причина разницы должна быть тонкой, поэтому нет #ifdef _WIN32или похожее, пожалуйста! Помните, ваша цель состоит в том, чтобы «доказать», что эта конкретная система плохая, поэтому люди не должны быть в состоянии (немедленно) определить ваш трюк!

  • если в вашем коде есть очень странная или очень необычная часть, вы должны обосновать это в комментариях, почему она есть. Конечно, это «оправдание» может / будет большой ложью.

Подсчет очков:

Это не гольф! Код должен быть хорошо организован и прост. Помните, ваша цель состоит в том, чтобы скрыть ошибку, чтобы люди не подозревали об этом. Чем проще код, тем менее подозрительным он является.

Победитель будет определен голосованием. Большинство голосов спустя приблизительно 10 дней после первого действительного представления выигрывает. Как правило, следует голосовать за ответы, в которых код легко читается и понимается, но ошибка хорошо скрыта, и даже если она обнаружена, ее можно отнести к ошибке, а не к злобе. Точно так же, это должно стоить гораздо больше, если ошибка просто приводит к неверному результату, а не просто вызывает сбой программы или ее отсутствие.

Как обычно, я оставляю за собой право выбрать ответ в качестве победителя, если он не превышает 10% или 1 балл ниже того, который набрал наибольшее количество голосов, по любым субъективным критериям.


5
Интересно, что make (1)работает правильно практически на каждом Unix-боксе и неправильно на некоторых Windows-боксах. Не из-за ОС, а из-за файловых систем. Любая файловая система, которая сохраняет даты изменения файлов с низкой точностью, может работать makeнеправильно на быстрой машине.
dmckee

1
@dmckee: вот почему я рад, что я не оставил все открытым, и вы должны прочитать некоторые входные данные и сделать несколько простых вычислений.
вс

10
Я понял только сейчас, что этот поиск злого кода имеет идентификатор 6666
вс

3
Надеемся на ответ, который работает в Windows и <Insert Linux Distribution>, но не в Mac.
Кейси Кубалл

1
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что скрытые проблемы больше не обсуждаются на этом сайте. meta.codegolf.stackexchange.com/a/8326/20469
кошка,

Ответы:


15

Unix shell + стандартные утилиты

Давайте напишем сценарий оболочки, который находит процесс (принадлежащий любому пользователю), который использовал наибольшее количество процессорного времени, и убивает все процессы с одинаковыми именами. Я предполагаю, что это считается как чтение данных (из системы) и выполнение расчета. (Такое поведение может быть полезно для процессов, которые разветвляются на многие процессы, такие как разветвления и Google Chromium.)

Следующее должно быть портативным способом получения имени процесса с наибольшим временем ЦП (я пытался избежать явных Linuxism, но не проверял его на Solaris):

ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2

Так что наш сценарий просто

killall `ps -A -o time= -o comm= | sort | tail -n 1 | cut -d ' ' -f 2`

Запустите от имени пользователя root для достижения наилучших результатов, чтобы он мог убивать процессы других пользователей.

Linux и BSD

Это работает на Linux и должно работать на BSD, потому что killall argубивает названные процессы arg.

Solaris

Однако в Solaris, если пользователь запускает программу 9с бесконечным циклом, сценарий отключит систему . Это потому что:

В Solaris killall argозначает уничтожение всех процессов с помощью сигнала arg. Так что командная строка становится killall 9. Как 9и число для SIGKILL в Solaris , это убьет все процессы и, таким образом, выведет из строя систему.

NB

Эта проблема с внедрением оболочки не применяется в Linux, потому что, даже если злонамеренный пользователь может предоставить какой-то особый аргумент, такой -KILLкак имя процесса, killall -KILLон безвредно напечатает сообщение об использовании.


3
killallэто не пример. Это просто две разные программы с одинаковыми именами. Каждая версия работает правильно.
dmckee

7
Да, но сценарий оболочки не работает должным образом.
Механическая улитка

12
Вы заметили, как хромовые и вилочные бомбы сравнимы? ;)
kaoD

7
@kaoD: ключевое отличие в том, что вилочные бомбы используют меньше памяти.
Механическая улитка

1
Просто отметить , что не существует такого понятия , как «Google Хром»: В Google Chrome браузер будет основан на с открытым исходным кодом Chromium браузер, но только первый содержит Google специфичный код и присоединил имя компании Google.
Анко

18

питон

Эта программа открывает изображение, указанное в командной строке, и отображает его.

import Image
import sys

with open(sys.argv[1]) as f:
    im = Image.open(f)
    im.show()

Работает на Linux, не работает на Windows.

Это связано с тем, как Windows открывает файлы. Для правильной работы всех операционных систем необходимо указать двоичный режим.


4
Программа должна сделать некоторые расчеты и отобразить результаты. В конкретной операционной системе также должны отображаться некоторые результаты, но неверные. Да, с некоторой умной игрой слов вы могли бы утверждать, что это именно то, что делает ваша программа, но я думаю, что это намеренное неправильное толкование правил. Однако, в конечном итоге, решают избиратели.
вс

5

Little Endian (Intel x86) против Big Endian (IBM Power7)

Любой формат файла, в котором присутствуют многобайтовые двоичные величины в не хостовом порядке, рискует быть неверно истолкованным. Вот функция, которая принимает необработанный звук, скажем, извлеченный из файла WAV (который является форматом файла с прямым порядком байтов Microsoft), делит пополам амплитуду и выводит ослабленный звук.

#include <stdio.h>

int main()
{
    short audio;
    while (fread(&audio, sizeof(short), 1, stdin))
    {
        audio >>= 1;
        fwrite(&audio, sizeof(short), 1, stdout);
    }
    return 0;
}

На машинах с прямым порядком байтов это прекрасно работает, но на машинах с большим порядком байтов это катастрофа. Например

01001101 11001110 -> CE4D (little endian format)

Сдвиг вправо по порядку байтов:

00100110 01100111 -> 8726 (correct)

Сдвиг вправо на старшем порядке:

00100110 11100111 -> E726 (not correct)

Обратите внимание, что некоторые из них правильны! Фактически, вероятность того, что выходной сигнал будет правильным, составляет 50:50, в зависимости от того, равен ли младший бит сэмпла звуку 0 или 1!

Поэтому, когда вы слушаете этот звук, он похож на половину амплитуды, но с наложенным каким-то резким громким высокочастотным шумом. Довольно поразительно, если вы не готовы к этому!


5

GTB

:"-→_[_+_→_]

На компьютере это работает, а на моем калькуляторе TI-84 - нет. Зачем?

В калькуляторе ОЗУ переполняется и потенциально очищается, а в эмуляторе для Windows эмулятор не может переполнить ОЗУ из-за ограниченного выделения.


Что оно делает?
Илмари Каронен

В вопросе есть спойлер (желтая рамка), на который можно навести курсор мыши, чтобы увидеть скрытый текст.
Timtech

4
Да, но что он делает, если ОЗУ не переполняется? Действительно ли он "делает некоторые вычисления", как задает вопрос, и если да, то что?
Ильмари Каронен

@IlmariKaronen Это просто объединяет строки. (Можно указать, конечно)
Timtech

4

С

Это решение проблемы 100 (о последовательности Коллатца) принимается UVa Online Judge.

Однако этот код корректно работает только на платформе * nix, поскольку longтип реализован как 64-разрядное целое число со знаком. В Windows код вызывает неопределенное поведение, так как longтип реализован как 32-разрядное целое число со знаком, в то время как для представления одного из промежуточных значений в cyc()функции требуется как минимум 32-разрядное значение.

#include <stdio.h>

#define swap(a, b, t) t __tmp__ = a; a = b; b = __tmp__;
#define M 1000000

short l[M] = {0, 1};

int cyc(long n) { // HERE
    if (n < M && l[n]) return l[n];
    n = n & 0x1 ? 3 * n + 1 : n >> 1;
    return n < M ? (l[n] = cyc(n)) + 1 : cyc(n) + 1;
}

int max(int a, int b) { return a > b ? a : b; }

int main() {
    #ifndef ONLINE_JUDGE
    // freopen("input.txt", "r", stdin);
    #endif
    int i, j, m;
    while (scanf("%d %d", &i, &j) == 2) {
          printf("%d %d ", i, j);
          if (i > j) { swap(i, j, int); }
          for (m = 0; i <= j; i++)
              m = max(m, cyc(i));
          printf("%d\n", m);
    }

    return 0;
}

Еще один способ сделать это еще более несовместимым - поместить массив lвнутрь main()и внести соответствующие изменения в cyc()функцию. Поскольку исполняемый файл по умолчанию настроен на запрос стека 2 МБ в Windows, программа сразу падает.


2

питон

Я сталкивался с этим в StackOverflow при поиске таймаутов ввода.

 import signal 
 TIMEOUT = 5

 def interrupted(signum, frame): 
     print 'interrupted!' 
 signal.signal(signal.SIGALRM, interrupted) 

 def input(): 
     try: 
         print 'You have 5 seconds to type in your stuff...' 
         foo = raw_input() 
         return foo 
     except: 
         return

 signal.alarm(TIMEOUT) 
 s = input()
 signal.alarm(0) 
 print 'You typed', s 

Это не работает для Windows.


Почему это не работает в Windows? Правильно ли я догадываюсь, что это потому, что Windows не поддерживает POSIX SIG? Тогда это просто вопрос стандартных библиотек Python, предоставляющих функциональность обеим операционным системам. Я не думаю, что это соответствует духу задачи (например, форк Python не будет работать по понятным причинам), но это недостаток Python (плюс тот факт, что он интерпретируется), а не Windows ». Например: включение conio.hбудет иметь тот же эффект, но C даже не скомпилируется.
Каод

@kaoD: Честно говоря, я не уверен, почему это не работает и в Windows. Возможно, в Linux есть некоторые функции, которых нет в Windows, так что это может быть реализовано в Linux, а не в Windows.
beary605

Тогда это то, что я догадался: вы используете функциональность POSIX, предоставляемую Python. ИМХО, это не подходит как ответ из-за ранее заявленной причины, но эй, я просто еще один муравей в колонии;) То, что вы видите, это "ошибка" Python, а не Windows. Смотрите это: docs.python.org/library/signal.html#signal.signal
kaoD

Windows API не обеспечивает отменяемое чтение по каналу из потока.
Джошуа

0

Linux + bash + GNU coreutils

rm --no-preserve-root -R -dir /

Это удалит корневую папку и все, что в ней не существует в Windows, даже если вы установите bash для Windows :)


Это работает в Windows теперь, когда в Windows встроена подсистема Linux. (Я думаю, не буду пытаться это
Павел

@Pavel Довольно просто открыть cmd.exeи набрать, rmчтобы увидеть, что это не работает.
MD XF
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.