Конкурс в рамках: війна в ОС [закрита]


29

Всі ми знаємо, як дискусія про те, яка найкраща операційна система викликала багато вогняних воєн. Ваша мета зараз - надати рішучий "доказ" того, що ваша улюблена операційна система краща ... ах, ні, набагато краще, надати рішучий "доказ", що інша операційна система погана.

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

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

подобається це

  • причина різниці має бути тонка, тому ні, #ifdef _WIN32ні подібне, будь ласка! Пам'ятайте, ваша мета - "довести", що ця конкретна система погана, тому люди не повинні мати можливість (негайно) помітити ваш трюк!

  • якщо у вашому коді є дуже дивна або дуже незвична частина, ви повинні виправдати це в коментарях, чому він є. Звичайно, це "виправдання" може / буде великою брехнею.

Оцінка:

Це не гольф! Код повинен бути добре організованим та простий. Пам'ятайте, ваша мета - сховати помилку в ній, щоб люди не підозрювали про це. Чим простіший код, тим він менш підозрілий.

Переможець визначатиметься голосами. Найбільше голосів приблизно через 10 днів після першого дійсного подання виграє. Як правило, відповіді, де код легко читати та розуміти, але помилка добре прихована, і навіть якщо вона виявлена, її можна віднести до помилки, а не до злості. Аналогічно, варто коштувати набагато більше, якщо помилка просто викликає неправильний результат, а не просто спричиняє збій програми або нічого не робить.

Як завжди, я позбавляю права обирати відповідь як переможець, якщо вона не на 10% або на 1 бал нижче за ту, яка має найбільше голосів, за будь-якими суб'єктивними критеріями.


5
Цікаво, що make (1)працює належним чином на кожній коробці Unix та неправильно на деяких вікнах. Не через ОС, а через файлові системи. Будь-яка файлова система, яка зберігає дати модифікації файлів з низькою точністю, може не працювати makeналежним чином на швидкій машині.
dmckee

1
@dmckee: ось чому я радий, що я не залишив все відкритим, і вам доведеться прочитати в якомусь матеріалі і зробити кілька простих розрахунків.
vsz

10
Я тільки зараз зрозумів, що цей квест на злий код має Id 6666
vsz

3
Ось сподіватися на відповідь, яка працює в Windows та <Вставити дистрибутив Linux>, але не на Mac.
Кейсі Кубалл

1
Я голосую за те, щоб закрити це питання як позатематичне, тому що недостатньо важкі виклики вже не є актуальними на цьому веб-сайті. meta.codegolf.stackexchange.com/a/8326/20469
кіт

Відповіді:


15

Оболонка Unix + стандартні утиліти

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

Наступним повинен бути портативний спосіб отримати ім'я процесу з найбільшим часом процесора (я намагався уникати очевидних Linuxisms, але не перевіряв його на 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`

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

Linux та BSD

Це працює на Linux і має працювати над BSD, оскільки killall argвбиває процеси, названі arg.

Соляріс

Однак у Solaris, якщо користувач запускає програму, названу 9у нескінченному циклі, сценарій знищить систему . Це відбувається тому:

На Solaris - killall argозначає вбити всі процеси за допомогою сигналу arg. Так стає командний рядок killall 9. Як 9і число для SIGKILL на Solaris , це знищить усі процеси і тим самим знищить систему.

NB

Ця проблема введення оболонки не застосовується в Linux, тому що навіть незважаючи на те, що зловмисник може надати якийсь спеціальний аргумент, наприклад, -KILLяк ім'я процесу, killall -KILLвін нешкідливо надрукує повідомлення про використання.


3
killallце НЕ є прикладом. Це лише дві різні програми з однаковою назвою. Кожна версія працює належним чином.
dmckee

7
Так, але сценарій оболонки не працює належним чином.
Механічний равлик

12
Чи помічали ви, як хромові та вилкові бомби можна порівняти? ;)
якD

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
Програма повинна зробити деякі розрахунки та відобразити результати. У певній операційній системі він також повинен відображати деякі результати, але неправильні. Так, за допомогою розумної гри слів ви можете стверджувати, що саме це робить ваша програма, але я думаю, що це навмисне неправильне тлумачення правил. Однак, врешті-решт, виборці вирішують.
vsz

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 (про послідовність Collatz) приймає Інтернет-суддя UVa.

Однак цей код правильно працює лише на платформі * 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 навіть не компілюється.
якDD

@kaoD: Чесно кажучи, я не впевнений, чому він також не працює в Windows. Можливо, у Linux є деякі функції, яких Windows не має, тому це можливо реалізувати в Linux, а не в Windows.
beary605

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

API Windows не забезпечує скасовуваного зчитування на трубі з потоку.
Джошуа

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.