diff --git a/gdb-port/parser-type-instrumentation-gdb.py b/gdb-port/parser-type-instrumentation-gdb.py
index ee9b45b70315bb9243f91afde7aa8e3323ad8c5f..35ecd65f8f9b105a045a263f786943b44bc2b501 100644
--- a/gdb-port/parser-type-instrumentation-gdb.py
+++ b/gdb-port/parser-type-instrumentation-gdb.py
@@ -147,12 +147,17 @@ class ButNotEnv(HParserEnv):
 		self.parser = parser
 		super().__init__(parser, top_level_parse)
 
-		p1_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p1")
+		htwoparsers_t = gdb.lookup_type("HTwoParsers")
+		htwoparsers_p_t = htwoparsers_t.pointer()
+
+		parser_obj = gdb.parse_and_eval("*parser")
+		p_env = parser_obj['env'].cast(htwoparsers_p_t).dereference()
+		p1_p = p_env['p1']
 		p1_obj = top_level_parse.add_or_get_parser(p1_p)
 		if p1_obj.name is None:
 			p1_obj.name_parser( self.name_from_vtable(p1_obj) )
 		self.p1 = p1_obj
-		p2_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p2")
+		p2_p = p_env['p2']
 		p2_obj = top_level_parse.add_or_get_parser(p2_p)
 		if p2_obj.name is None:
 			p2_obj.name_parser( self.name_from_vtable(p2_obj) )
@@ -165,8 +170,11 @@ class ActionEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
 		super().__init__(parser, top_level_parse)
+		parser_t = gdb.lookup_type("HParser") # TODO: maybe move this into TopLevelParse
+		parser_p_t = parser_t.pointer()
 
-		member_parser_p = gdb.parse_and_eval("((HParseAction*) parser->env)->p")
+		#member_parser_p = gdb.parse_and_eval("((HParseAction*) parser->env)->p")
+		member_parser_p = gdb.Value(parser.address).cast(parser_p_t) #TODO: shuffling around pointers may not be necessary after all, if using Value objects
 		parser_obj = top_level_parse.add_or_get_parser(member_parser_p)
 		if parser_obj.name is None:
 			parser_obj.name_parser( self.name_from_vtable(parser_obj) )
@@ -216,7 +224,9 @@ class CharsetEnv(HParserEnv):
 	def __str__(self):
 		return str(self.charset_arg)
 
-# TODO: numeric parameter passed to parse_and_eval
+# TODO: this assumes the parser parameter passed to init and the parser value returned by GDB are the same
+# they should be, but parse_and_eval could be removed entirely if the code just used the parameter
+# This would also make initialization independent of being at specific breakpoints when executing
 class ChoiceEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		super().__init__(parser, top_level_parse)
@@ -450,10 +460,9 @@ class OptionalEnv(HParserEnv):
 	def __str__(self):
 		return str(self.member_parser)
 
-# TODO: numeric parameter passed to parse_and_eval
 class PermutationEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
-		super().__init__(parser, top_level_parse) # TODO: maybe move self.parser to base class. otherwise, is this needed?
+		super().__init__(parser, top_level_parse)
 		self.parser = parser
 		self.member_parsers = []
 
@@ -684,6 +693,7 @@ class ParserDecombinator:
 
 	def decompose_parser(self, parser, top_level_parse):
 		# Sadly, this is stringly typed for now
+		# TODO: use gdb.Value!
 		parser_addr = parser.address
 		vtable_p = gdb.parse_and_eval("((HParser*) " + str(parser_addr) + ")->vtable")
 		try: