我正在写一个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) 我目前正在使用 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 …
好的,所以,我是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编译器.我不会在细节上得到太多.基本上,我想知道是否可以使用可以识别结束括号的正则表达式.例如,这将是一个合法的输入
void foo(){
asd
}
Run Code Online (Sandbox Code Playgroud)
这不会
void foo(){
asd
if (){
asd
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,2个开启者({)只有1个close(}),这使得输入无效.有没有办法使用正则表达式并确定出现次数匹配?