Concurso secreto: A guerra do SO [fechada]

29

Todos sabemos como a discussão sobre qual é o melhor sistema operacional causou muitas guerras de chamas. Seu objetivo agora é fornecer "provas" decisivas de que seu sistema operacional favorito é melhor ... ah, não, muito melhor, fornecer "provas" decisivas de que outro sistema operacional é ruim.

A tarefa: escreva um programa que faça alguns cálculos e funcione corretamente em pelo menos um SO e incorretamente em pelo menos outro.

  • o programa deve fazer pelo menos alguns cálculos; portanto, é necessário ler algumas entradas simples (de preferência na entrada padrão, ou se for de arquivos, se você quiser, mas o uso indevido de little endian / big endian não seria apenas barato, mas também óbvio) , e forneça alguma saída, dependendo da entrada. Os cálculos devem ser significativos e justificados, por exemplo, resolver uma vida real ou um problema matemático.
  • você deve especificar os dois sistemas operacionais, indicando em qual deles funcionará corretamente e em qual não. Ambos os sistemas operacionais devem ser bem conhecidos e aproximadamente ao mesmo tempo (portanto, não há DOS 1.0 versus um sistema operacional moderno). É aconselhável fornecer uma breve descrição sobre a causa da diferença (especialmente se você suspeitar que muitas pessoas não perceberiam) em tags de spoiler.

como isso

  • a causa da diferença tem que ser sutil, então não #ifdef _WIN32ou similar, por favor! Lembre-se, seu objetivo é "provar" que esse sistema específico é ruim, para que as pessoas não possam (imediatamente) descobrir seu truque!

  • se houver uma parte muito estranha ou muito incomum no seu código, você deverá justificá-lo nos comentários por que ele está lá. Obviamente, essa "justificativa" pode / será uma grande mentira.

Pontuação:

Isto não é um golfe! O código deve ser bem organizado e simples. Lembre-se, seu objetivo é ocultar um bug para que as pessoas não suspeitem. Quanto mais simples o código, menos suspeito é.

O vencedor será decidido por votos. O maior número de votos após aproximadamente 10 dias após o primeiro envio válido vence. Geralmente, as respostas em que o código é fácil de ler e entender, mas o bug está bem oculto e, mesmo se descoberto, podem ser atribuídas a um erro e não à malícia, devem ser votadas. Da mesma forma, deve valer muito mais se o erro causar apenas um resultado incorreto, em vez de apenas causar a falha do programa ou não fazer nada.

Como sempre, detenho o direito de escolher uma resposta como vencedora se ela não estiver mais de 10% ou 1 ponto abaixo da que tiver mais votos, em qualquer critério subjetivo.

vsz
fonte
5
Curiosamente make (1)funciona corretamente em essencialmente todas as caixas unix e indevidamente em algumas caixas de janelas. Não por causa dos sistemas operacionais, mas por causa dos sistemas de arquivos. Qualquer sistema de arquivos que mantém as datas de modificação de arquivos com baixa precisão pode não funcionar makeadequadamente em uma máquina rápida.
dmckee
11
@dmckee: é por isso que estou feliz por não ter deixado tudo aberto, e você deve ler algumas informações e fazer alguns cálculos simples.
vsz 18/07/12
10
Eu só percebi agora, que essa busca pelo código do mal tem o ID de 6666
vsz 19/07/12
3
Aqui está a esperança de uma resposta que funcione no Windows e em <Insert Linux Distribution>, mas não no Mac.
Casey Kuball 26/07/12
11
Estou votando para encerrar esta questão como fora de tópico, porque os desafios secretos não estão mais no tópico neste site. meta.codegolf.stackexchange.com/a/8326/20469
cat

Respostas:

15

Shell Unix + utilitários padrão

Vamos escrever um script de shell que encontre o processo (de propriedade de qualquer usuário) que tenha usado mais tempo de CPU e mate todos os processos com o mesmo nome. Suponho que isso conte como leitura de dados (do sistema) e execução de um cálculo. (Esse comportamento pode ser útil para processos que realizam muitos processos, como fork-pumps e Google Chromium.)

A seguir, deve ser uma maneira portátil de obter o nome do processo com o maior tempo de CPU (tentei evitar Linuxismos óbvios, mas não o testei no Solaris):

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

Portanto, nosso script é simplesmente

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

Execute como root para obter melhores resultados, para que ele possa matar processos de outros usuários.

Linux e BSD

Isso funciona no Linux e deve funcionar nos BSDs, porque killall argmata os processos nomeados arg.

Solaris

No entanto, no Solaris, se um usuário estiver executando um programa nomeado 9em um loop infinito, o script derrubará o sistema . Isto é porque:

No Solaris, killall argsignifica matar todos os processos com o sinal arg. Então a linha de comando se torna killall 9. Como 9é o número do SIGKILL no Solaris , isso matará todos os processos e, assim, derrubará o sistema.

NB

Esse problema de injeção de shell não se aplica ao Linux, porque, embora o usuário mal-intencionado possa fornecer algum argumento especial -KILLcomo um nome de processo, killall -KILLimprime inofensivamente uma mensagem de uso.

Caracol mecânico
fonte
3
killallnão é um exemplo. Que apenas dois programas diferentes com o mesmo nome. Cada versão está funcionando corretamente.
dmckee
7
Sim, mas o script do shell não está funcionando corretamente.
Caracol mecânico
12
Você notou como as bombas de cromo e garfo são comparáveis? ;)
kaoD
7
@kaoD: A principal diferença é que as bombas de garfo usam menos memória.
Caracol mecânico
11
Apenas observando que não existe "Google Chromium": o navegador Google Chrome é baseado no navegador de código aberto Chromium , mas apenas o primeiro contém código específico do Google e o nome do Google anexado.
Anko
18

Python

Este programa abre a imagem especificada na linha de comando e a exibe.

import Image
import sys

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

Funciona no Linux, não funciona no Windows.

Isso ocorre devido à maneira como o Windows abre arquivos. O modo binário deve ser especificado para que isso funcione corretamente em todos os sistemas operacionais.

Matt
fonte
4
O programa deve fazer alguns cálculos e exibir os resultados. Em um sistema operacional específico, ele também deve exibir alguns resultados, mas incorretos. Sim, com algumas brincadeiras inteligentes, você pode argumentar que é exatamente isso que seu programa está fazendo, mas acho que é uma interpretação deliberada incorreta das regras. No entanto, em última análise, os eleitores decidem.
vsz 19/07/12
5

Little Endian (Intel x86) vs. Big Endian (IBM Power7)

Qualquer formato de arquivo em que haja quantidades binárias de vários bytes em ordem não-host corre o risco de ser mal interpretado. Aqui está uma função que pega o áudio bruto, extraído de um arquivo WAV (que é um formato de arquivo little endian da Microsoft), reduz pela metade a amplitude e emite o áudio atenuado.

#include <stdio.h>

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

Em pequenas máquinas endian, isso funciona muito bem, mas em grandes máquinas endian é um desastre. Por exemplo

01001101 11001110 -> CE4D (little endian format)

Mude para a direita no little endian:

00100110 01100111 -> 8726 (correct)

Mude para a direita na big endian:

00100110 11100111 -> E726 (not correct)

Note que alguns dos nybbles estão corretos! De fato, é uma chance de 50:50 que a saída esteja correta, dependendo se o bit menos significativo da amostra de som é 0 ou 1!

Portanto, quando você ouve esse áudio, é como meia amplitude, mas com algum ruído agudo estridente sobreposto. Muito surpreendente se você não estiver preparado para isso!


fonte
5

GTB

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

No computador, ele funciona, mas na minha calculadora TI-84, não. Por quê?

Na calculadora, a RAM excede e é potencialmente limpa, enquanto no emulador para Windows, a RAM não pode ser excedida pelo emulador devido à alocação limitada.

Timtech
fonte
O que isso faz?
Ilmari Karonen
Há um spoiler (caixa amarela) na pergunta que você pode passar o mouse para ver o texto oculto.
Timtech
4
Sim, mas o que faz o que a RAM não transborda? Realmente "faz alguns cálculos", como a pergunta pede e, em caso afirmativo, o que?
Ilmari Karonen
@IlmariKaronen Apenas concatena as strings. (Você pode especificar, é claro)
Timtech
4

C

Esta solução para o problema 100 (sobre a sequência Collatz) é aceita pelo UVa Online Judge.

No entanto, esse código funciona apenas corretamente na plataforma * nix , pois o longtipo é implementado como número inteiro assinado de 64 bits. No Windows , o código chama um comportamento indefinido, pois o longtipo é implementado como número inteiro assinado de 32 bits, enquanto um dos valores intermediários na cyc()função precisa de pelo menos 32 bits para representar.

#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;
}

Outra maneira de tornar isso ainda mais incompatível é colocar a matriz ldentro main()e fazer as alterações correspondentes para cyc()funcionar. Como o executável está definido para solicitar uma pilha de 2 MB por padrão no Windows, o programa falha imediatamente.

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳
fonte
2

Python

Me deparei com isso no StackOverflow ao procurar tempos limite de entrada.

 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 

Isso não funciona no Windows.

beary605
fonte
Por que isso não está funcionando no Windows? Estou certo de que é porque o Windows não suporta POSIX SIGs? Depois, é apenas uma questão de as bibliotecas padrão do Python exporem funcionalidade aos dois sistemas operacionais. Eu não acho que segue o espírito do desafio (por exemplo, o fork do Python também não funcionará por razões óbvias), mas essa é a falha do Python (mais o fato de ser interpretado), não o Windows. Ex .: incluir conio.hteria o mesmo efeito, mas C nem compilará.
21412 kaoD
@kaoD: Honestamente, também não sei por que não funciona no Windows. Talvez o Linux tenha alguns recursos que o Windows não possui, então isso pode ser implementado no Linux e não no Windows.
beary605
Então é o que eu imaginei: você está usando a funcionalidade POSIX exposta pelo Python. IMHO isso não se encaixa como resposta por causa do motivo exposto anteriormente, mas, ei, sou apenas mais uma formiga na colônia;) O que você vê é a "falha" do Python, não o Windows. Veja isto: docs.python.org/library/signal.html#signal.signal
kaoD
A API do Windows não fornece leitura cancelável em um canal de dentro do encadeamento.
Joshua
0

Linux + bash + núcleo GNU

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

Isso apagará a pasta raiz e tudo o que não existe no Windows, mesmo se você instalar o bash para Windows :)

LAUAR
fonte
Isso funciona em Windows agora que o Windows tem um subsistema Linux construído em (I pensar, não vai tentar).
Pavel
@ Pavel Muito simples de abrir cmd.exee digitar rmpara ver se não funciona.
MD XF