Giter VIP home page Giter VIP logo

Comments (3)

plnelson avatar plnelson commented on July 19, 2024

Hello Simon,
This is a known problem with mixing IL interpretation and real func eval. The quick workaround for this as you discovered is to have a real array value in the process being debugged. This could be a real local that has been initialized in the process. The key thing is the array value must exist in the process. The variable being a temporary or real variable doesn't matter. Two other solutions are to call a function that creates an array and then assigning this value to your temporary local. You may find a framework Array.Create variant that works, but I wouldn't suggest doing that because because the interpreter usually special cases these so such a solution would be fragile. The other solution is to create a pseudo-local and use that value as the parameter to StoreInByteArray.

TL;DR - Here's the details of what's happening if your interested:
If the IL for the query method has a call instruction, the debugger will do a "real func eval" rather than use the interpreter. This means we set the context of the current thread to the beginning of the function being evaluated, set a guard breakpoint at the return address, then allow the process to run until the guard breakpoint is hit. That's a simplification, but it's the general idea. If the function being evaluated takes parameters, we need to marshal the values from the interpreter to the process being debugged. If the value already exists in the process, this is a simple task. If the value doesn't exist, we need to create it within the process. Due to the architecture of the interpreter, we can't update the value itself to this marshalled value. This is fine for immutable values. However, if the value is mutable, changes made by the process won't be visible to the interpreter.

Looking at your example (with added comments):

.method public hidebysig static string '<>m0'()
{
<snip>
newarr uint8 // Value is initialized inside the interpreter
.locals init (uint8[] _TEMP_LOCAL_2)
stloc.2 // The value that exists only in the interpreter is assigned to a temporary local

<snip>
           // Before the func eval, parameter 2 (an array value) is marshalled into a
           // real array value in the process being debugged
call void 'StoreInByteArray'(int32, uint8[], int32, int32)
           // StoreInByteArray has modified a value in the marshalled array value.
ldloc.2
<snip>
           // Local 2 is still the value that exists only in the interpreter and hasn't
           // been modified by any interpreted code
           // Parameter 1 is marshalled again to a real array value in the process
           // being debugged.
call string 'FormatAsString'(uint8[], int32, int32) // This just has a sequence of null bytes
ret
}

This is something I want to fix at some point, but in the meantime, you can work around this be ensuring the value is initialized within the process being debugged then assigning it to a variable the interpreter knows about. Also pseudo-locals force creation of array values in the process being debugged to work around this same problem.

Hopefully that helps. Let me know if you have any other questions

from concordextensibilitysamples.

sae42 avatar sae42 commented on July 19, 2024

Thanks for the explanation Patrick, that makes sense. I'll have a think about a workaround; I'd forgotten about the pseudo-locals which looks like it may be the best bet.

from concordextensibilitysamples.

plnelson avatar plnelson commented on July 19, 2024

A problem with pseudo-variables that occurred to me later is that they are visible to the user. There's also no way to delete them once they are created. That leaves calling a function in the process to create the array. If your runtime has a function to create arrays, I would try using that.

from concordextensibilitysamples.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.