Как отладить сбой Cygwin? - PullRequest
       30

Как отладить сбой Cygwin?

0 голосов
/ 21 февраля 2011

Я портирую из Centos в Cygwin и нахожу, что мое приложение завершает работу без сообщения об ошибке и завершает работу с нулевым значением в середине выполнения во время конструктора для Botan :: InitializationVector.

Если я пытаюсь подключиться с помощью gdb предварительнов main (), где он ожидает переменную вращения, я не получаю нормальную трассировку стека:

(gdb) where
#0  0x7c90120f in ntdll!DbgUiConnectToDbg ()
   from /cygdrive/c/WINDOWS/system32/ntdll.dll
#1  0x7c952119 in ntdll!KiIntSystemCall ()
   from /cygdrive/c/WINDOWS/system32/ntdll.dll
#2  0x00000005 in ?? ()
#3  0x00000000 in ?? ()

Так что без gdb трудно понять, что происходит не так.

Почему я не получаю сообщение об ошибке в Cygwin, но приложение завершает работу в середине выполнения?

Я полагаю, что оно находится внутри конструктора, поскольку засорение отображается только для строки перед, а не после конструктора:

clog << "  About to create iv for Botan.\n";
Botan::InitializationVector iv(_rng, size);
clog << "  About to copy iv for Botan.\n";

Botan с открытым исходным кодом: http://botan.randombit.net/ Вот некоторые фрагменты кода из src / sym_algo / symkey. {H, cpp}:

typedef OctetString InitializationVector;

class BOTAN_DLL OctetString
{
public:
  u32bit length() const { return bits.size(); }
  SecureVector<byte> bits_of() const { return bits; }

  const byte* begin() const { return bits.begin(); }
  const byte* end() const   { return bits.end(); }

  std::string as_string() const;

  OctetString& operator^=(const OctetString&);

  void set_odd_parity();

  void change(const std::string&);
  void change(const byte[], u32bit);
  void change(const MemoryRegion<byte>& in) { bits = in; }

  OctetString(class RandomNumberGenerator&, u32bit len);
  OctetString(const std::string& str = "") { change(str); }
  OctetString(const byte in[], u32bit len) { change(in, len); }
  OctetString(const MemoryRegion<byte>& in) { change(in); }
private:
  SecureVector<byte> bits;
};

OctetString::OctetString(RandomNumberGenerator& rng,
                     u32bit length)
{
   bits.create(length);
   rng.randomize(bits, length);
}

Я переместилсбой кода в main (), и он работает нормально.Я также сделал попытку поймать ... вокруг кода, и никаких исключений не выдается.Что-то идет не так между main () и точкой сбоя позже в приложении.Я могу разделить и победить, чтобы сузить точную точку, где это больше не работает.Один из разработчиков Botan дал мне этот урезанный код для использования вместо него, который также не работает:

Botan::AutoSeeded_RNG _rng;
unsigned int size = 1; // or 16, or 1452 all fail.
Botan::SecureVector<Botan::byte> iv_val(size);
cerr << "We get to here." << endl;
_rng.randomize(&iv_val[0], size);
cerr << "But not here." << endl;

Теперь, когда у меня работает отладчик, я вижу segv:

(gdb) s
Botan::AutoSeeded_RNG::randomize (this=0x1270380, out=0x5841420 "", len=1)
    at ../../src/Botan-1.8.11/build/include/botan/auto_rng.h:23
(gdb) s

Program received signal SIGSEGV, Segmentation fault.
0x005d79ee in Botan::AutoSeeded_RNG::randomize (this=0x1270380, 
    out=0x5841420 "", len=1)
    at ../../src/Botan-1.8.11/build/include/botan/auto_rng.h:23
(gdb) p rng
$7 = (class Botan::RandomNumberGenerator *) 0x5841324
(gdb) p *this
$8 = {<Botan::RandomNumberGenerator> = {
    _vptr$RandomNumberGenerator = 0x11efc14}, rng = 0x5841324}
(gdb) p *rng
$9 = {_vptr$RandomNumberGenerator = 0x656e6f4e}

Вот код auto_rng.h:

class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator
  {
  public:
    void randomize(byte out[], u32bit len)
    { rng->randomize(out, len); }           // SEGV on this line.
    bool is_seeded() const
    { return rng->is_seeded(); }
    void clear() throw() { rng->clear(); }
    std::string name() const
    { return "AutoSeeded(" + rng->name() + ")"; }

    void reseed(u32bit poll_bits = 256) { rng->reseed(poll_bits); }
    void add_entropy_source(EntropySource* es)
    { rng->add_entropy_source(es); }
    void add_entropy(const byte in[], u32bit len)
    { rng->add_entropy(in, len); }

    AutoSeeded_RNG(u32bit poll_bits = 256);
    ~AutoSeeded_RNG() { delete rng; }
  private:
    RandomNumberGenerator* rng;
  };

Ответы [ 3 ]

3 голосов
/ 21 февраля 2011

Приложения Cygwin являются многопоточными (например, один поток является потоком прослушивателя сигналов).Используйте info threads в GDB, чтобы найти поток, который действительно вышел из строя.

1 голос
/ 21 февраля 2011

Исходя из нового кода, вы нарушаете Правило трех , и это может вызвать вашу проблему.

Определяя класс с необработанными указателями и не предоставляя правильный конструктор копирования (или делая его недоступным), вы открываете себя до двойного освобождения.

Добавить конструктор копирования. Или откройте проблему на трекере ошибок проекта. Вы используете последнюю версию, верно?

1 голос
/ 21 февраля 2011

Вы можете предварительно подключить gdb и поставить точку останова непосредственно перед неудачным вызовом конструктора, а затем выполнить один шаг до конца.

...