Строка просмотра, переданная конструктору выброшенного исключения

Я пытаюсь отлаживать программу на C++, скомпилированную с помощью Emscripten, которая генерирует исключения, в частности runtime_error. s, которые передают строку как what_arg. Однако, когда они выбрасывают, я просто получаю число (значение указателя?) в консоли Javascript. Строка, переданная конструктору, была бы гораздо полезнее.

Например, программа

#include <stdexcept>

int main()
{
  throw std::runtime_error("I want to see this in the console");
  return 0;
}

скомпилировано с использованием Emscripten 1.35.0 64bit (в Mac OS X) командой

em++ exception.cc -o exception.html

при просмотре в браузере выводит в консоль

Uncaught 5247024

Как я могу увидеть во время выполнения, каким был аргумент what_arg?

В идеале это было бы без блока try-catch в коде C++, поэтому я мог бы использовать DISABLE_EXCEPTION_CATCHING флаг. Существуют способы преобразования адреса памяти строки в стиле C в строку Javascript с помощью Pointer_stringify. Может быть, есть что-то подобное для номера, переданного как исключение?


person Michal Charemza    schedule 15.11.2015    source источник
comment
Я не вижу смысла преобразовывать C++ в JS для выполнения в браузере, но это неважно. В любом случае вы поймаете исключение в C++ так: try {...} catch (std::exception ex) { std::cout << ex.what( ); }.   -  person user4520    schedule 15.11.2015
comment
@szczurcio Можете ли вы пояснить, почему не было бы смысла смотреть, в чем состоял аргумент?   -  person Michal Charemza    schedule 15.11.2015
comment
Извините, пожалуйста, уточните, какой аргумент? Если вы спрашиваете о сообщении const char[], которое вы передаете конструктору std::runtime_error, это то, что вам даст what( ).   -  person user4520    schedule 15.11.2015
comment
Ах, извините... Я неправильно прочитал ваше сообщение (или, может быть, вы его отредактировали?). Я думал, что это говорит о том, что я не вижу в этом смысла, и я понял, что это означает желание увидеть сообщение const char[], а не преобразование C++ в JS для выполнения в браузере. Мои причины преобразования C++ в JS для выполнения в браузере заключаются в том, что существует существующая кодовая база C++, которая должна работать в браузере. Да, понял про what.   -  person Michal Charemza    schedule 15.11.2015
comment
Первоначально он сказал, что я не вижу в этом смысла, потому что я имел в виду ваш удаленный комментарий, который, в свою очередь, был написан как ответ на мой удаленный первоначальный комментарий;). В любом случае, на самом деле нет способа перехватить исключение, полученное из std::exception, и вывести его what( ) без блока try-catch. Вы можете прочитать о std::set_terminate и std::set_unexpected, но они не позволят вам напечатать сообщение просто потому, что не каждый тип исключения должен иметь его (в C++ любой класс может быть выброшен как исключение, в отличие, например, от Java).   -  person user4520    schedule 15.11.2015


Ответы (2)


Существует способ использования window.onerror, который кажется вызываться при возникновении необработанного исключения. Используя это, я могу

  • Получить 5-й параметр обработчика onerror
  • Ничего не делать, если это не число
  • Передайте номер обратно в мир C++ функции, используя, например, ccall
  • Затем функция выполняет reinterpret_cast для числа, чтобы получить указатель на runtime_error.
  • Вызовите what на runtime_error и передайте полученную строку cerr

Пример программы C++, которая делает это:

#include <stdexcept>
#include <iostream>

#include <emscripten.h>

extern "C" void EMSCRIPTEN_KEEPALIVE what_to_stderr(intptr_t pointer)
{
  auto error = reinterpret_cast<std::runtime_error *>(pointer);
  std::cerr << error->what() << "\n";
}

int main()
{
  throw std::runtime_error("I want to see this in the console");
  return 0;
}

который можно скомпилировать с помощью команды

em++ -std=c++11 exception.cc -o exception.js

и запустить внутри простой HTML-страницы

<!doctype html>
<html>
  <head>
    <title>Exception test</title>
    <script>
      var Module = {};
      window.onerror = function(message, url, line, column, e) {
        if (typeof e != 'number') return;
        var pointer = e;
        Module.ccall('what_to_stderr', 'number', ['number'], [pointer]);
      }
    </script>
    <script src="exception.js"></script>
  </head>
  <body>
  </body>
</html>

Кажется, он работает в Chrome 46 и Firefox 41.

person Michal Charemza    schedule 16.11.2015

Вам нужно catch это и напечатать строку what() вручную.

РЕДАКТИРОВАТЬ: это должно быть выполнено на С++ с блоком try/catch, например:

int main(int argc, char** argv)
{
    try
    {
        throw std::runtime_error("I want to see this in the console");
    }
    catch (const std::runtime_error& error)
    {
        std::cout << error.what() << std::endl;
    }

    return 0;
}
person Paul Evans    schedule 15.11.2015
comment
Можете ли вы привести пример кода этого? Будет ли это ловить его в С++ или в Javascript? - person Michal Charemza; 15.11.2015
comment
Это будет ловить его на С++. Затем вам нужно будет как-то отправить информацию в JS. - person Roman Plášil; 21.03.2016