小编Ego*_*ozy的帖子

CLR概要分析:在catch块内抛出后的DoStackSnapshot会产生错误的指令指针

我正在写一个CLR分析器,我遇到了一些非常奇怪的东西.当抛出两个不同的异常时,一个来自try子句,一个来自catch子句,CLR通知我相同的指令指针.更具体地说:我已注册接收ExceptionThrown回调

virtual HRESULT STDMETHODCALLTYPE ExceptionThrown(ObjectID thrownObjectId);

在回调中,我在当前线程上启动DoStackSnapshot(https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/profiling/icorprofilerinfo2-dostacksnapshot-method).CLR为每一帧调用我的方法:

HRESULT stackSnapshotCallback(FunctionID funcId, UINT_PTR ip, COR_PRF_FRAME_INFO, ULONG32, BYTE context[], void *clientData)

但是,如果我从try子句和相应的catch子句抛出异常(代码示例如下),我会收到两者的SAME ip.我还要提到,这不是重新抛出的情况,当这是预期的时候,但是一个全新的异常甚至可能发生在catch的调用堆栈中.

在研究了更多内容并深入挖掘CoreCLR代码之后,我找不到发生这种情况的原因,这就是为什么我在这里问这个问题.我还要提到,在普通的C#调试器中,这很容易重现,我觉得这很令人震惊.我使用过.Net Framework 4.5,但这也发生在4.6和4.7上.

我相信,如果我理解为什么以下C#代码以这种方式运行,我可能会理解为什么CLR也会这样做.

这段代码:

try
{
    try
    {
        throw new Exception("A");
    }
    catch (Exception)
    {
        StackTrace st = new StackTrace(true);
        StackFrame sf = st.GetFrame(0);
        Console.WriteLine("Inside catch, instruction: " + sf.GetILOffset() + ". line: " + sf.GetFileLineNumber());
        throw new Exception("B");
    }
}
catch (Exception)
{
    StackTrace st = new StackTrace(true);
    StackFrame sf = st.GetFrame(0);
    Console.WriteLine("Outer catch, instruction: " …
Run Code Online (Sandbox Code Playgroud)

.net c# clr clr-profiling-api

7
推荐指数
1
解决办法
245
查看次数

理解结构的“this”参数(特别是迭代器/异步)

我目前正在使用 Profiler API 检查 CLR 中的深层对象。我在分析迭代器/异步方法的“this”参数(由编译器生成,形式为<name>d__123::MoveNext)时遇到了一个具体问题。

在研究这个时,我发现确实有一种特殊的行为。首先,C# 编译器将这些生成的方法编译为结构体(仅在 Release 模式下)。ECMA-334(C# 语言规范,第 5 版:https : //www.ecma-international.org/publications/files/ECMA-ST/ECMA-334.pdf)指出(12.7.8 此访问):

“...如果方法或访问器是迭代器或异步函数,则 this 变量表示调用该方法或访问器的结构的副本,....”

这意味着与其他“this”参数不同,在这种情况下,“this”是按值发送的,而不是按引用发送。我确实看到副本没有在外面修改。我试图了解结构实际上是如何发送的。

我冒昧地剥离了复杂的案例,并用一个小结构复制了它。看下面的代码:

struct Struct
    {
        public static void mainFoo()
        {
            Struct st = new Struct();
            st.a = "String";
            st.p = new Program();
            System.Console.WriteLine("foo: " + st.foo1());
            System.Console.WriteLine("static foo: " + Struct.foo(st));
        }

        int i;
        String a;
        Program p;

        [MethodImplAttribute(MethodImplOptions.NoInlining)]
        public static int foo(Struct st)
        {
            return st.i;
        }

        [MethodImplAttribute(MethodImplOptions.NoInlining)]
        public int foo1()
        {
            return i;
        }
    }
Run Code Online (Sandbox Code Playgroud)

NoInlining …

c# clr cil clr-profiling-api

5
推荐指数
1
解决办法
160
查看次数

Android计时器不准确

好的,所以,我是java和Android编程的真正初学者.我正在尝试为友谊赛制作一个篮球应用程序.现在我正在制作一个从24到0的拍摄时钟,播放声音,并通过一个按钮重置.

public class MainActivity extends Activity {
    private ShotClock shotClock;
    private TextView shotClockTimer;
    private Timer timer = new Timer();
    private Button shotClockReset;
    private final static int interval = 100;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        shotClockTimer = (TextView) findViewById(R.id.shotClock);
        shotClockReset = (Button)findViewById(R.id.shotClockReset);
        shotClock = new ShotClock();
        shotClockReset.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                shotClock.shotClockReset();
            }

        });
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                TimerMethod();
            }

        }, 0, interval);

    }

    private void TimerMethod() { …
Run Code Online (Sandbox Code Playgroud)

java android timer

4
推荐指数
1
解决办法
2971
查看次数

编程"编译器" - 任何知道{(开启者)是否}的方式(关闭)?

好吧,我有一个练习来构建一种java编译器.我不会在细节上得到太多.基本上,我想知道是否可以使用可以识别结束括号的正则表达式.例如,这将是一个合法的输入

void foo(){
   asd
}
Run Code Online (Sandbox Code Playgroud)

这不会

void foo(){
   asd
   if (){
      asd
   }
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,2个开启者({)只有1个close(}),这使得输入无效.有没有办法使用正则表达式并确定出现次数匹配?

java regex compiler-theory language-theory

1
推荐指数
1
解决办法
179
查看次数