diff --git a/__init__.py b/__init__.py
index ac892a10e771f664dfbef8167c9c9f03025cbb24..c9eda4626988c313115c94025f4047da0339e878 100644
--- a/__init__.py
+++ b/__init__.py
@@ -173,7 +173,8 @@ class GDB_Output(list):
             
 class GDB_Instance:
     PROMPT = "(gdb) "
-
+    TIMEOUT = 20 # * 0.1 s = 2s before checking for exceptions
+    
     CSV_mode = False
     CSV_header = False
     CSV_REPEAT = 10
@@ -185,6 +186,7 @@ class GDB_Instance:
         self.package = package
         self._fout = None
         self._fcmd = None
+        self.src = None
         
     def start(self, source, init_hook=None):
         self.src = source
@@ -218,6 +220,12 @@ class GDB_Instance:
         self.execute("file {}".format(source.binary))
         
     def check_results(self, command, expected, results):
+        try:
+            return expected.search(results) is not None
+        except AttributeError: # not a regex
+            pass
+
+        
         if expected.startswith(EXPECTED_FILE_PREFIX):
             expected_filename = expected[len(EXPECTED_FILE_PREFIX):]
             with open("{}/{}".format(self.src.src_dir, expected_filename)) as expected_file:
@@ -225,34 +233,59 @@ class GDB_Instance:
         
         return expected in results
         
+        
     def execute_many(self, commands, *args, **kwargs):
         if not isinstance(commands, list):
             commands = [commands]
 
         return [self.execute(a_command, *args, **kwargs) for a_command in commands]
-        
-    def execute(self, command, expected_results=None, expected_stderr=None, may_fail=False):
+
+
+    def test_fail(self, details=""):
+        print("FAILED {}{}".format(self.last_cmd, " ({})".format(details) if details else ""))
+        import pdb;pdb.set_trace()
+        pass
+    
+    def test_success(self, details=""):
+        if self.verbose:
+            print("PASSED")
+    
+    def test_expected_fail(self, details=""):
+        print("EXPECTED FAILURE {}{}".format(self.last_cmd, "({})".format(details) if details else ""))
+    
+    def execute(self, command, expected_results=None, expected_stderr=None, may_fail=False, check_stdout=None, check_stderr=None):
         if GDB_Instance.CSV_header: return GDB_Output(command, "", "", True)
         
         assert not isinstance(command, list)
-            
-        out, err = self._read_til_prompt(command)
+
+        self.last_cmd = command
+        self.last_err = None
+        self.last_out = None
         
+        self.last_out, self.last_err = self._read_til_prompt(command)
+
+        if check_stdout is None:
+            check_stdout = self.check_results
+        if check_stderr is None:
+            check_stderr = self.check_results
+            
         correct = all([
-            not expected_results or self.check_results(command, expected_results, out),
-            not expected_stderr or self.check_results(command, expected_results, err)])
+            not expected_results or check_stdout(command, expected_results, self.last_out),
+            not expected_stderr or check_stderr(command, expected_results, self.last_err)
+            ])
         
-
-        if correct:
-            if self.verbose: print("PASSED")
+        if not (expected_results or expected_stderr):
+            pass
+        elif correct:
+            self.test_success()
         elif may_fail:
-            print("EXPECTED FAILURE ({})".format(command))
+            self.test_expected_fail()
             correct = None
         else:
-            print("FAILED {}".format(command))
+            self.test_fail()
 
         if not correct and not may_fail and self.verbose:
-            for results, name in (out, "stdout"), (err, "stderr"):
+            for results, name in (self.last_out, "stdout"), (self.last_err, "stderr"):
                 if not results: continue
                 for line in difflib.context_diff(expected_results.split("\n"), results.split("\n"),
                                                  fromfile='Expected results', tofile='Actual results ({})'.format(name)):
@@ -262,7 +295,7 @@ class GDB_Instance:
                 print(expected_results)
         #print(levenshtein_distance(expected, results))
 
-        return GDB_Output(command, out, err, correct)
+        return GDB_Output(command, self.last_out, self.last_err, correct)
 
     def set_title(self, title):
         if GDB_Instance.CSV_header:
@@ -317,21 +350,35 @@ class GDB_Instance:
         def read_utf8_buffer(buff):
             bs = buff.read()
             return bs.decode("utf-8") if bs else ""
-        
+
+        timeout = GDB_Instance.TIMEOUT
         while not out_buffer.endswith(GDB_Instance.PROMPT):
             try:
                 self._gdb.poll()
                 if self._gdb.returncode is not None:
                     raise TerminatedError(self._gdb.returncode)
                 
-                out_buffer += read_utf8_buffer(self._gdb.stdout)
-                err_buffer += read_utf8_buffer(self._gdb.stderr)
+                out = read_utf8_buffer(self._gdb.stdout)
+                out_buffer += out
+                err = read_utf8_buffer(self._gdb.stderr)
+                err_buffer += err
+
+                if not err and not out and timeout > 0:
+                    timeout -= 1
             except IOError:
                 time.sleep(0.1)
             except KeyboardInterrupt:
                 import pdb;pdb.set_trace()
                 print(out_buffer)
 
+            if timeout <= 0 and  "(Pdb)" in out_buffer:
+                print(err_buffer)
+                print(out_buffer, end="")
+                print("FORCE QUITTING PDB")
+                
+                self._gdb.stdin.write("import os;os._exit(0)\n".encode('ascii'))
+                raise TerminatedError(None)
+        
         out_buffer = out_buffer[:-(len(GDB_Instance.PROMPT))].strip()
         self._gdb.stderr.flush()
         while True:
@@ -398,7 +445,16 @@ class GDB_Instance:
         finally:
             self._fout.close()
             self._fcmd.close()
-        
+
+    def get_location(self, text, src_fname=None):
+        if src_fname is None:
+            src_fname = "/".join((self.src.src_dir, self.src.srcname))
+            
+        with open(src_fname) as src_f:
+            for i, line in enumerate(src_f.readlines()):
+                if text in line:
+                    return i
+
 ##############################################3
 
 def levenshtein_distance(first, second):