2

特定の問題を見つけることができるようにスタックトレースを追加した、非常に計算集約型のモジュールがあります。このスタックトレースが有効になっている場合、アプリケーションの実行速度は低下しますが、実行速度が10倍遅くなることはありません。そのため、DBGHELP.DLLのStackWalkルーチンを使用していませんが、フレームポインターを使用して自分でスタックをウォークしています(したがって、フレームポインター省略コンパイラオプションは使用していません)。

ほとんどの場合、呼び出しスタックの取得は正しく機能し、非常に高速ですが、フレームポインターの1つがスタック外のアドレスを指しているために、ロジックが失敗する場合があります(それほど多くはありませんが、ほんの少しです)。

これはおそらくどこかのエラーであることがわかっていますが、コードをより安全にするには、フレームポインタが現在のスレッドのスタック内のメモリ位置を指しているかどうかを確認する方法が必要です。アプリケーションは64ビットで、Windowsで実行されます。

Windowsでスレッドスタック情報を取得する方法のコードおそらく問題は解決しますが、これは他の関数を呼び出すため、コードの実行が大幅に遅くなる可能性があります(正直なところ、テストはしていません)。

トリックを実行する必要のあるインラインアセンブリコード(http://nasutechtips.blogspot.com/2011/01/thread-information-block-tib-and-fs.html)も見つかりましたが、インラインアセンブリはによってサポートされていません。 Microsoftの64ビットC++コンパイラ。

また、組み込みの__readfsqwordは64ビットでは機能しないようです。

TIBを64ビットでできるだけ速く取得する方法に関する他の提案はありますか?

4

2 に答える 2

3

それを見つけた、次のコードはトリックを行います:

#include <windows.h>
#include <winnt.h>

struct _TEB
   {
   NT_TIB NtTib;
   // Ignore rest of struct
   };

void *startOfStack;
startOfStack = NtCurrentTeb()->NtTib.StackBase;
std::cout << "startOfStack = " << startOfStack << std::endl;

winnt.hのNtCurrentTeb()の定義を調べたところ、これは非常に低レベルの関数のように見えるので、必要なものを取得するのに十分な速度である可能性があります。

于 2012-05-29T16:07:02.007 に答える
3

64ビット__readgsqwordではなくする必要があります。__readfsqword

于 2013-06-11T09:25:40.907 に答える