0

私は最近多くのC#/。Netコードに取り組んでいて、何か(潜在的に)奇妙なことに気づきました。

私が所属しているチームは、Windows7ProfessionalとVisualStudio2008を使用して開発しており(その価値があるため)、生成されたコードの一部が異なるバージョンのWindows(私の例では、.Net3.5がインストールされたWindowsXP Professional)で実行されている場合)少し奇妙な動作が発生します。

私が気付いたのは、スイッチブロック内のネストされたifの非常に特定のセット(それぞれが同じメソッドを呼び出しますが、パラメーターが異なる)は、特定の1台のマシンでの実行時と開発時の動作が異なるようです。マシン。私が意味する例はこれです:

switch (someVariable)
{
    case true:
        //do some stuff
        //this case seems fine when stepped through
        break;
    case false:
        //do some stuff
        //this is the case that causes problems
        if (Foo())
        {
            if(Bar())
            {
                someOtherMethod();
                //I'll call these the nested ifs
                if (object.SomeValue == targetValueOne)
                    FooBar(string, someParam, int anotherParam);
                if (object.SomeValue == targetValueTwo)
                    FooBar(string differentStrParam, int differentIntParam);
                else
                    FooBar(string thirdStrParam, int thirdIntParam);
            }
        }
        else
        {
           //do some different things
        }
        break;
}

この例は非常に複雑ですが、目の前にあるコードにも(ほぼ)当てはまります(object.SomeValueの値をチェックする場合は余分なものがあります)。

Windows 7(開発)マシンでは、コードは完全に実行されます-object.SomeValueの順列ごとにコードをステップ実行し、各コードパスは計画どおりに実行されます。ただし、このコードをWindows XP(テスターに​​属する)マシンで実行すると、ネストされたifは呼び出されないように見えます。特に、Bar()がtrueを返した場合はそうです。

FooBar()には2つのバージョンがあり、1つは戻るバージョンと、もう1つは返さないバージョンです。ここでは、そうでないバージョンを明示的に呼び出しています。

Foo()とBar()は2つの異なるセットアップメソッドであり、セットアップ手順を完了するとtrueを返し、そうでない場合はfalseを返します。

上で述べたように、このコードがテスターのマシンで実行されると、ネストされたifは完全にスキップされます。それらは開発マシンで正しく評価されますが。JITは実行時にネイティブコードにコンパイルされ、ネイティブコードはそれが実行されているマシンに固有であることを私は知っています。

それで、テスターのマシン上のJITである可能性があるかどうか、これらのネストされたifがスキップされる原因であるかどうか、または何かを見逃したかどうかを誰かが知っているかどうかを尋ねていると思います。または、JITコンパイラがこのブロックを最適化して、想定どおりに実際に実行されないコードを生成しようとしている可能性がありますか?

おそらくより明確な例:

switch (Hawrdware.SomeProperty)
{
  case true:
      //do some stuff
      //this case seems fine when stepped through
      break;
  case false:
    //do some stuff
    //this is the case that causes problems
    if (SetupHardware()) //calls our library functions
    {                    //these have been tested thoroughly
      if(WaitForCorrectResponse()) //waits for the correct post-setup
      {                            //message from the hardware
        SendOTAMessageFromHardware(string message);
        //I'll call these the nested ifs
        if (Hawrdware.PropertyOne == targetValueOne)
            SendOTAMessageFromHardware(string message, int timeOutForResponse);
        if (Hawrdware.PropertyTwo == targetValueTwo)
            SendOTAMessageFromHardware(string message, int timeOutForResponse);
        else
            SendOTAMessageFromHardware(string message, int timeOutResposnse);
      }
    }
    else
    {
       //do some different things
    }
    break;
}

public void SendOTAMessage(string message)
{
  if (message != null)
  {
    device.Write(message);
    //Hardware's on-board OS takes care of the rest
  }
}

public void SendOTAMessage(string message, int TimeOut)
{
  if (message != null)
  {
    StopWatch clock = new StopWatch();
    device.Write(message);
    //Hardware's on-board OS takes care of the rest

    while (time.Elapsed.TotalSeconds < TimeOut)
    {
      //wait and see if we get a response
      //if we do, store it in a string (legacy
      //reasons state we have to do this
    }
  }
}

public string SendOTAMessage(string message, int TimeOut)
{
  if (message != null)
  {
    StopWatch clock = new StopWatch();
    device.Write(message);
    //Hardware's on-board OS takes care of the rest

    while (time.Elapsed.TotalSeconds < TimeOut)
    {
      //wait and see if we get a response
      //if we do, return this message as a string
    }
  }
}
4

2 に答える 2

0

「Myifステートメントがデバッガーでヒットしない」よりも決定的なものがない限り、他のすべての可能な要因を除外する必要があります。

2台の同一のマシンを構築します。

  • 1つは「疑わしい」OSバージョンを使用し、もう1つはDevのバージョンを使用します。最初のテストでは、両方が同じ「ビット数」である必要があります。つまり、一方が32ビットの場合、もう一方も32ビットである必要があります。
  • 新しいマシンに正しい.NETFrameworkバージョン、サードパーティライブラリ、必要なソフトウェアなどがあることを確認します。
  • それらがWindowsUpdateからパッチされていることを確認してください。
  • 外部ハードウェアドライバーがインストールされており、両方とも同じバージョンのドライバーであることを確認してください。ハードウェアベンダーがOSに基づいて異なるライブラリ/ソフトウェアを提供している場合は、その理由を知る必要があります。
  • 外部ハードウェアが正しく接続され、両方に同じバージョンのソフトウェアがインストールされていることを確認してください。
  • 外部ハードウェアが同じように接続されていることを確認してください。(マシンの同じポート)
  • 外部ハードウェアが両方で同じ応答を返していることを確認します(外部ハードウェアがOSのバージョンに基づいて異なる動作をする可能性があります)
  • 同じスレッドで同じイベントが同じ順序でトリガーされていることを確認します。
  • メソッドを入力するときは、同じ変数が同じ状態に設定されていることを確認してください。

このテスト全体を通して、一方に対して実行するすべてのアクションについて、もう一方に対して同じように実行することを確認してください。

于 2012-04-04T08:51:48.880 に答える
0

コンパイルの誤りが本当に疑われる場合は、次のようにします。

  1. スイッチの直前のHawrdware.SomePropertyの値をトレースします
  2. falseswitchケース内にトレースを追加します
  3. SetupHardwareおよびWaitForCorrectResponse内にトレース値を追加します。

Hardware.SomeProperty == false + caseステートメント内にトレースが表示されているが、メソッド内にトレースが表示されていない場合は、正しい可能性があります。どちらかをステップスルーする必要はありません。方程式からデバッガーを削除すると、作業が簡単になるだけです。

于 2012-04-04T09:12:38.057 に答える