Skip to content

Conversation

@myeongseoklee
Copy link

What does this PR do?

Fixes a bug in mysql2 instrumentation where onResult callback is re-wrapped on every execute() call, causing stack overflow with large prepared statement params.

The Problem:

In bindExecute and wrapExecute, the onResult callback gets wrapped on every packet. MySQL's prepared statement protocol sends one packet per parameter definition. For queries with 3,366+ params, execute() is called 3,369 times, nesting the callback 3,369 layers deep → Stack Overflow.

The Fix:

Add a _ddWrapped flag to prevent re-wrapping callbacks that have already been wrapped.

- if (onResult) {
+ if (onResult && !onResult._ddWrapped) {
    this.onResult = function () {
      return commandFinishCh.runStores(ctx, onResult, this, ...arguments)
    }
+   this.onResult._ddWrapped = true
  }

Motivation

Reproduction Repository: https://github.com/myeongseoklee/mysql2-callstack-reproduction

git clone https://github.com/myeongseoklee/mysql2-callstack-reproduction.git
cd mysql2-callstack-reproduction
npm install && npm run docker:up
npm run reproduce      # Before fix: crashes
npm run debug:wrap     # Shows 3,369 execute() calls for 3,366 params

Additional Notes

Evidence:

Params execute() calls Before Fix After Fix
3,060 3,063 ✅ OK ✅ OK
3,366 3,369 ❌ Crash ✅ OK

… packet

MySQL's prepared statement protocol sends one packet per parameter
definition. For queries with 3,366+ params, execute() is called 3,369
times, and each call was re-wrapping the onResult callback, creating
a deeply nested callback chain that causes stack overflow.

This fix adds a _ddWrapped flag to prevent re-wrapping callbacks that
have already been wrapped.

Fixes DataDog#7074
@myeongseoklee myeongseoklee requested review from a team as code owners December 10, 2025 17:23
@myeongseoklee myeongseoklee marked this pull request as draft December 11, 2025 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: mysql2 instrumentation causes stack overflow with large prepared statement params

1 participant