Skip to content

Useful test scripts

CyberShadow edited this page Sep 15, 2011 · 21 revisions

##Detecting a specific segfault ###Bash (Linux/Posix only) Note: This script expects a core dump to be written to a core file. See ulimit for more information.

#!/bin/sh
BINARY="test" #the binary to test
SEGFUNC="_aaDelX" #the function where the segfault occurs (as in the gdb backtrace!)
dmd test.d -of$BINARY 2>/dev/null #Your compile command

echo $(sh -c "./$BINARY" 2>&1) | grep -q "Segmentation fault" #Make sure there was a segfault
if [ $? -eq 0 ]
then
    gdb --batch -ex 'backtrace' $BINARY core 2>&1 | grep -q "#0 .* in $SEGFUNC"
    if [ $? -eq 0 ]
    then
        return 0
    else
        return 1
    fi
else
    return 1
fi

###Bash (alternative without core files)

#!/bin/sh
BINARY="test" #the generated binary to test
SEGFUNC="D main ()" #the function where the segfault occurs (as in the gdb backtrace!)
dmd test.d -of$BINARY 2>/dev/null #Your compile command

OUTPUT=$(gdb --batch -ex 'run' -ex 'backtrace' ./$BINARY 2>&1)
echo "$OUTPUT" | grep -q "Program received signal SIGSEGV, Segmentation fault." #Make sure there was a segfault
if [ $? -eq 0 ]
then
    echo "$OUTPUT" | grep "#0"| grep -q " in $SEGFUNC"
    if [ $? -eq 0 ]
    then
        return 0
    else
        return 1
    fi
else
    return 1
fi

##Running commands with a timeout ###Coreutils timeout command Replace testdir with your test directory and sleep 60 with your test command:

dustmite testdir "timeout -k 30s 30s sleep 60"

You can also use a script as the test command:

dustmite testdir "timeout -k 30s 30s ./testscript.sh"

##Suppressing the standard "Program has stopped working" dialog on Windows The following D program will launch another program with the general protection fault error dialog disabled.

import std.process;

extern(Windows) void SetErrorMode(int);
enum : uint { SEM_FAILCRITICALERRORS = 1, SEM_NOGPFAULTERRORBOX = 2 }

int main(string[] args)
{
	SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
	return spawnvp(P_WAIT, args[1], args[1..$]);
}

##Suppressing DMD's "abnormal program termination" message box on Windows Run the following D program in the background. It's not a perfect solution (message boxes will steal focus for a fraction of a second), but it'll keep the reduction going.

import std.c.windows.windows;

extern(Windows)
{
	HWND FindWindowA(LPCSTR, LPCSTR);
	HWND FindWindowExA(HWND, HWND, LPCSTR, LPCSTR);
}

void main()
{
	while(true)
	{
		auto h = FindWindowA("#32770", null);
		while (h)
		{
			auto h2 = FindWindowExA(h, null, null, "\nabnormal program termination\n");
			if (h2)
			{
				h2 = FindWindowExA(h, null, "Button", "OK");
				if (h2)
					SendMessageA(h2, BM_CLICK, 0, 0);
			}
			h = FindWindowExA(null, h, "#32770", null);
		}

		Sleep(1);
	}
}

##Reducing OPTLINK's Message Box of Death The following D program will launch another command and return 0 if it encountered and closed an OPTLINK MBoD, and 1 otherwise.

import std.c.windows.windows;
import core.thread;
import std.process;

extern(Windows)
{
	HWND FindWindowA(LPCSTR, LPCSTR);
	HWND FindWindowExA(HWND, HWND, LPCSTR, LPCSTR);
}

enum title = "Unexpected OPTLINK Termination at EIP=0042785B";

int main(string[] args)
{
	bool optlinkCrashed = false;
	bool done = false;
	
	auto thread = new Thread({
		while (!done)
		{
			auto h = FindWindowA("#32770", title);
			while (h)
			{
				auto h2 = FindWindowExA(h, null, "Button", "OK");
				if (h2)
				{
					optlinkCrashed = true;
					SendMessageA(h2, BM_CLICK, 0, 0);
				}
				h = FindWindowExA(null, h, "#32770", title);
			}
			Sleep(1);
		}
	});

	thread.start();
	system(args[1]);
	done = true;
	return optlinkCrashed ? 0 : 1;
}
Clone this wiki locally