hi
diff --git a/src/passes/Outlining.cpp b/src/passes/Outlining.cpp
index 91154b1..2a00b12 100644
--- a/src/passes/Outlining.cpp
+++ b/src/passes/Outlining.cpp
@@ -21,8 +21,6 @@
 #include "support/suffix_tree.h"
 #include "wasm.h"
 
-#define OUTLINING_DEBUG 0
-
 #if OUTLINING_DEBUG
 #define DBG(statement) statement
 #else
@@ -93,23 +91,24 @@
 
     DBG(std::string desc);
     if (auto curr = reason.getBlockStart()) {
-      ASSERT_OK(existingBuilder.visitBlockStart(curr->block));
       DBG(desc = "Block Start at ");
+      ASSERT_OK(existingBuilder.visitBlockStart(curr->block));
     } else if (auto curr = reason.getIfStart()) {
       // IR builder needs the condition of the If pushed onto the builder before
       // visitIfStart(), which will expect to be able to pop the condition.
       // This is always okay to do because the correct condition was installed
       // onto the If when the outer scope was visited.
       existingBuilder.push(curr->iff->condition);
-      ASSERT_OK(existingBuilder.visitIfStart(curr->iff));
       DBG(desc = "If Start at ");
+      ASSERT_OK(existingBuilder.visitIfStart(curr->iff));
     } else if (reason.getElseStart()) {
-      ASSERT_OK(existingBuilder.visitElse());
       DBG(desc = "Else Start at ");
+      ASSERT_OK(existingBuilder.visitElse());
     } else if (auto curr = reason.getLoopStart()) {
-      ASSERT_OK(existingBuilder.visitLoopStart(curr->loop));
       DBG(desc = "Loop Start at ");
+      ASSERT_OK(existingBuilder.visitLoopStart(curr->loop));
     } else if (reason.getEnd()) {
+      DBG(desc = "End at ");
       ASSERT_OK(existingBuilder.visitEnd());
       // Reset the function in case we just ended the function scope.
       existingBuilder.setFunction(func);
@@ -122,7 +121,6 @@
       // its expressions off the stack, so we must call build() after visitEnd()
       // to clear the internal stack IRBuilder manages.
       ASSERT_OK(existingBuilder.build());
-      DBG(desc = "End at ");
     } else {
       DBG(desc = "addUniqueSymbol for unimplemented control flow ");
       WASM_UNREACHABLE("unimplemented control flow");
@@ -207,18 +205,24 @@
   void transitionToInSeq() {
     Function* outlinedFunc =
       getModule()->getFunction(sequences[seqCounter].func);
+    DBG(std::cerr << "\ncreated outlined fn: " << outlinedFunc->name << "\n");
     ASSERT_OK(outlinedBuilder.visitFunctionStart(outlinedFunc));
 
     // Add a local.get instruction for every parameter of the outlined function.
     Signature sig = outlinedFunc->type.getSignature();
+    DBG(std::cerr << outlinedFunc->name << " takes " << sig.params.size()
+                  << " parameters\n");
     for (Index i = 0; i < sig.params.size(); i++) {
+      DBG(std::cerr << "adding local.get $" << i << " to " << &outlinedBuilder
+                    << "\n");
       ASSERT_OK(outlinedBuilder.makeLocalGet(i));
     }
 
     // Make a call from the existing function to the outlined function. This
     // call will replace the instructions moved to the outlined function.
+    DBG(std::cerr << "\nadding call to outlined fn: " << outlinedFunc->name
+                  << "\n");
     ASSERT_OK(existingBuilder.makeCall(outlinedFunc->name, false));
-    DBG(std::cerr << "\ncreated outlined fn: " << outlinedFunc->name << "\n");
   }
 
   void transitionToInSkipSeq() {
@@ -302,7 +306,13 @@
     // are relative to the enclosing function while substrings have indices
     // relative to the entire program.
     auto sequences = makeSequences(module, substrings, stringify);
-    outline(module, sequences);
+    outline(module,
+            sequences
+#if OUTLINING_DEBUG
+            ,
+            stringify
+#endif
+    );
     // Position the outlined functions first in the functions vector to make
     // the outlining lit tests far more readable.
     moveOutlinedFunctions(module, substrings.size());
@@ -351,15 +361,28 @@
         // sequence relative to its function is better for outlining because we
         // walk functions.
         auto [relativeIdx, existingFunc] = stringify.makeRelative(seqIdx);
-        auto seq =
-          OutliningSequence(relativeIdx, relativeIdx + substring.Length, func);
+        auto seq = OutliningSequence(relativeIdx,
+                                     relativeIdx + substring.Length,
+                                     func
+#if OUTLINING_DEBUG
+                                     ,
+                                     seqIdx,
+                                     substring.Length
+#endif
+        );
         seqByFunc[existingFunc].push_back(seq);
       }
     }
     return seqByFunc;
   }
 
-  void outline(Module* module, Sequences seqByFunc) {
+  void outline(Module* module,
+               Sequences seqByFunc
+#if OUTLINING_DEBUG
+               ,
+               const HashStringifyWalker& stringify
+#endif
+  ) {
     // TODO: Make this a function-parallel sub-pass.
     std::vector<Name> keys(seqByFunc.size());
     std::transform(seqByFunc.begin(),
@@ -379,6 +402,11 @@
                 });
       ReconstructStringifyWalker reconstruct(module, module->getFunction(func));
       reconstruct.sequences = std::move(seqByFunc[func]);
+      DBG(printReconstruct(module,
+                           stringify.hashString,
+                           stringify.exprs,
+                           func,
+                           reconstruct.sequences));
       reconstruct.doWalkFunction(module->getFunction(func));
     }
   }
@@ -414,6 +442,31 @@
       }
     }
   }
+
+  void printReconstruct(Module* module,
+                        const std::vector<uint32_t>& hashString,
+                        const std::vector<Expression*>& exprs,
+                        Name existingFunc,
+                        const std::vector<OutliningSequence>& seqs) {
+    std::cerr << "\n\nReconstructing existing fn: " << existingFunc << "\n";
+    std::cerr << "moving sequences: " << "\n";
+    for (auto& seq : seqs) {
+      for (Index idx = seq.originalIdx; idx < seq.originalIdx + seq.length;
+           idx++) {
+        Expression* expr = exprs[idx];
+        if (expr == nullptr) {
+          std::cerr << "unique symbol\n";
+        } else {
+          std::cerr << idx << " - " << hashString[idx] << " - " << seq.startIdx
+                    << " : " << ShallowExpression{expr} << "\n";
+        }
+      }
+      std::cerr << "to outlined function: " << seq.func << "\n";
+      auto outlinedFunction = module->getFunction(seq.func);
+      std::cerr << "with signature: " << outlinedFunction->type.toString()
+                << "\n";
+    }
+  }
 #endif
 };
 
diff --git a/src/passes/stringify-walker-impl.h b/src/passes/stringify-walker-impl.h
index 040770f..cca2a34 100644
--- a/src/passes/stringify-walker-impl.h
+++ b/src/passes/stringify-walker-impl.h
@@ -16,14 +16,6 @@
 
 #include "stringify-walker.h"
 
-#define STRINGIFY_DEBUG 0
-
-#if STRINGIFY_DEBUG
-#define DBG(statement) statement
-#else
-#define DBG(statement)
-#endif
-
 #ifndef wasm_passes_stringify_walker_impl_h
 #define wasm_passes_stringify_walker_impl_h
 
@@ -52,8 +44,6 @@
   Expression* curr = *currp;
   if (Properties::isControlFlowStructure(curr)) {
     self->controlFlowQueue.push(curr);
-    DBG(std::cerr << "controlFlowQueue.push: " << ShallowExpression{curr}
-                  << ", " << curr << "\n");
     self->pushTask(doVisitExpression, currp);
     // The if-condition is a value child consumed by the if control flow, which
     // makes the if-condition a true sibling rather than part of its contents in
@@ -72,8 +62,6 @@
   auto& queue = controlFlowQueue;
   Expression* curr = queue.front();
   queue.pop();
-  DBG(std::cerr << "controlFlowQueue.pop: " << ShallowExpression{curr} << ", "
-                << curr << "\n");
 
   // TODO: Issue #5796, Make a ControlChildIterator
   switch (curr->_id) {
diff --git a/src/passes/stringify-walker.h b/src/passes/stringify-walker.h
index c8a3285..92ed007 100644
--- a/src/passes/stringify-walker.h
+++ b/src/passes/stringify-walker.h
@@ -27,6 +27,8 @@
 #include "wasm-traversal.h"
 #include <queue>
 
+#define OUTLINING_DEBUG 1
+
 namespace wasm {
 
 /*
@@ -254,9 +256,27 @@
   unsigned startIdx;
   unsigned endIdx;
   Name func;
+#if OUTLINING_DEBUG
+  unsigned originalIdx;
+  unsigned length;
+#endif
 
-  OutliningSequence(unsigned startIdx, unsigned endIdx, Name func)
-    : startIdx(startIdx), endIdx(endIdx), func(func) {}
+  OutliningSequence(unsigned startIdx,
+                    unsigned endIdx,
+                    Name func
+#if OUTLINING_DEBUG
+                    ,
+                    unsigned originalIdx,
+                    unsigned length
+#endif
+                    )
+    : startIdx(startIdx), endIdx(endIdx), func(func)
+#if OUTLINING_DEBUG
+      ,
+      originalIdx(originalIdx), length(length)
+#endif
+  {
+  }
 };
 
 using Substrings = std::vector<SuffixTree::RepeatedSubstring>;
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index 9371046..81b79d8 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -547,7 +547,9 @@
       if (scope.unreachable) {
         return builder.builder.makeUnreachable();
       }
-      return Err{"popping from empty stack"};
+      std::stringstream ss;
+      ss << this;
+      return Err{"popping from empty stack" + ss.str()};
     }
 
     CHECK_ERR(builder.packageHoistedValue(*hoisted, size));
@@ -829,7 +831,9 @@
     auto hoisted = hoistLastValue();
     CHECK_ERR(hoisted);
     if (!hoisted) {
-      return Err{"popping from empty stack"};
+      std::stringstream ss;
+      ss << this;
+      return Err{"popping from empty stack" + ss.str()};
     }
 
     if (type.isTuple()) {