-
Notifications
You must be signed in to change notification settings - Fork 17
Useful test scripts
##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;
}