Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use original opcode in DynamicMethodBuilder #448

Merged
merged 12 commits into from
Jul 18, 2019

Conversation

lucaspimentel
Copy link
Member

@lucaspimentel lucaspimentel commented Jul 16, 2019

Follow-up to #367.
Fixes the StackOverflowException in StackExchange.Redis integration (see #447).

Changes proposed in this pull request:

  • use the original method call opcode when dynamically emitting IL to call a method in all the integrations that still use DynamicMethodBuilder
  • in StackExchange.Redis integration, call RedisBase.ExecuteAsync() instead of the ExecuteAsync() method from the derived type
  • rename HttpMessageHandler.StackOverflow project to HttpMessageHandler.StackOverflowException

@lucaspimentel lucaspimentel added type:bug area:automatic-instrumentation Automatic instrumentation managed C# code (Datadog.Trace.ClrProfiler.Managed) status:work-in-progress Actively worked on. If this is a PR, no review needed yet. WIP. priority:high labels Jul 16, 2019
@lucaspimentel lucaspimentel added this to the 1.5.1 milestone Jul 16, 2019
@lucaspimentel lucaspimentel requested a review from a team as a code owner July 16, 2019 16:15
@lucaspimentel lucaspimentel self-assigned this Jul 16, 2019
@lucaspimentel lucaspimentel changed the title pass original opcode DynamicMethodBuilder.CreateMethodCallDelegate() use original opcode in DynamicMethodBuilder Jul 16, 2019
@lucaspimentel lucaspimentel force-pushed the lpimentel/use-original-opcode-everywhere branch 2 times, most recently from 920e17c to bec0b10 Compare July 16, 2019 19:29
@lucaspimentel lucaspimentel modified the milestones: 1.5.1, 1.6 Jul 17, 2019
@lucaspimentel lucaspimentel force-pushed the lpimentel/use-original-opcode-everywhere branch 2 times, most recently from c402644 to 29c84a5 Compare July 17, 2019 18:49
@lucaspimentel lucaspimentel force-pushed the lpimentel/use-original-opcode-everywhere branch from 29c84a5 to 40e8d59 Compare July 17, 2019 19:00
@lucaspimentel lucaspimentel force-pushed the lpimentel/use-original-opcode-everywhere branch from 74fdb67 to 929de65 Compare July 17, 2019 19:31
methodParameterTypes: new[] { messageType, processorType, serverType },
methodGenericArguments: new[] { genericType });
.GetOrCreateMethodCallDelegate(
_redisBaseType,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE: we intercepted a call to RedisBase.ExecuteAsync(), so we need to call that method, not the one in type redisBase.GetType(), which could be an override. This is required in addition to using the original opcode to avoid stack overflow exceptions (#447).

@lucaspimentel lucaspimentel removed the status:work-in-progress Actively worked on. If this is a PR, no review needed yet. WIP. label Jul 17, 2019
m.GetGenericArguments().Length == methodGenericArguments.Length)
.ToArray();
m => m.IsGenericMethodDefinition &&
m.GetGenericArguments().Length == methodGenericArguments.Length);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find, no need to generate a new array!

{
// get these only once and cache them,
// no need for locking, race conditions are not a problem
_redisAssembly = thisType.Assembly;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I feel like I should edit my GraphQL integration to do this since the GraphQL parameters are defined in the same assembly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with doing it either way (like this or using the assembly name). In this case the assembly name can be either StackExchange.Redis or StackExchange.Redis.StrongName, so doing it this way allows us to handle either one.

Copy link
Contributor

@zacharycmontoya zacharycmontoya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! 👍

@lucaspimentel lucaspimentel force-pushed the lpimentel/use-original-opcode-everywhere branch from e9c441a to d936f73 Compare July 18, 2019 14:18
@lucaspimentel lucaspimentel force-pushed the lpimentel/use-original-opcode-everywhere branch from d936f73 to 343381c Compare July 18, 2019 15:06
@lucaspimentel lucaspimentel merged commit 6ba490d into develop Jul 18, 2019
@lucaspimentel lucaspimentel deleted the lpimentel/use-original-opcode-everywhere branch July 18, 2019 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:automatic-instrumentation Automatic instrumentation managed C# code (Datadog.Trace.ClrProfiler.Managed) priority:high type:bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants