つくねの手帳

C++およびAndroidアプリ開発メインで何か書きたい

QtCreatorでデバッグ中にブレークポイントにとまるとアプリがクラッシュする

この現象はQtCreator2.5.2という古いバージョンで発生したものなので、現在のQtCreatorでは発生しないかもしれません。

内容はタイトルの通りで、QtCreatorでQtプロジェクトのデバッグ実行中に、特定の場所、タイミングでブレークポイントんとに止まるとアプリがクラッシュするというものです。

結論から言うと、QtCreatorの監視ウィンドウが原因でした。


QtCreatorにはデバッグ中に変数の中身を表示させる監視ウィンドウというものがあります。
中身を見たい変数を右クリックし、「監視ウィンドウに追加」のメニューを選択することで、QtCreatorが変数の中身を表示してくれます。
VisualStudioでいうローカル変数タブのイメージですね。

デバッグ時には便利なのですが、以下のようなコードを監視することで、タイトルの現象が起きてしまいます。

hoge.h

class hoge

public:

  hoge();
  ~hoge();
  
  bool getFirstItem(int* buf); 

private
  QVector<int> m_vector; // メンバ変数にQVectorを定義
hoge.cpp

hoge::hoge()
{
  this->m_vector.clear(); 

  int a = 0;
  this->getFirstItem(&a); // ここにブレークポイントを置くと落ちる。ブレークせずに走らせる場合は問題なし。
}

bool hoge::getFirstItem(int* buf)
{
  bool bRet = false;
  
  if(false == this->m_vector->isEmpty())
  {
    buf = this->m_vector[0]; // ここのthis->m_vector[0]を監視ウィンドウに追加
    bRet = true;
  }

  return bRet;
}


QVectorは可変配列ですが、通常の配列のようにでアクセスが可能です。

当然、Vectorの中身がない場合はエラーになるのですが、上記のようにコード上はチェックをしていても、
監視ウィンドウにm_vector[0]のような変数を追加しておくと、このVectorはメンバ変数なので、クラス内どこでも参照可能です。

そのため、クラス内のブレークポイントに止まった際に、問答無用でアクセスエラーを起こします。

この時に、QtCreatorがエラーログをはいてくれるのですが、"ASSERT failure in QVector::operator:"index out of range",file....."
と配列オーバーアクセスなのはわかるのですが、どこで起きているのかわからないので、コード上を探しても配列オーバーアクセスを起こすコードは見つからない。
ということが起こります。

そもそもVectorにたいして[]でアクセスするな。という話かもしれませんが、ブレークしたときにVectorのアクセスエラーで落ちる。
なんて現象に遭遇した場合は、一度監視ウィンドウをチェックするほうがいいかもしれません。