Project

General

Profile

Main process exited, how to log ?

Added by Pedro Vicente 10 months ago

Running a WT app app on systemd exits with this error message

The error happens randomly without any user interface action about 10 minutes after the service is started (successfully)

Jul 10 02:56:56 nostro.net nostro_web[77374]: [2023-Jul-10 02:56:56.666] 77374 [/ 8dZuW2KI0qj9uU1d] [info] "WebController: timeout: expiri>
Jul 10 02:56:56 nostro.net systemd[1]: wt.root.ssl.service: Main process exited, code=killed, status=11/SEGV
Jul 10 02:56:56 nostro.net systemd[1]: wt.root.ssl.service: Failed with result 'signal'.

Any suggestion of where to put some debugging messages ?

the refs

https://www.webtoolkit.eu/wt/doc/reference/html/overview.html#config_general

say that logs can be set with 'log-file' on the XML config file

and

--accesslog arg                       access log file (defaults to stdout),

at command line.

are these 2 the same log output?


Replies (6)

RE: Main process exited, how to log ? - Added by Pedro Vicente 10 months ago

not sure if this output is relevant ?


127.0.0.1 - - [2023-Jul-10 01:56:58.043] "  HTTP/-1.-1" 400 89
127.0.0.1 - - [2023-Jul-10 01:57:00.077] "  HTTP/-1.-1" 400 89
127.0.0.1 - - [2023-Jul-10 01:57:02.090] "  HTTP/-1.-1" 400 89

RE: Main process exited, how to log ? - Added by Pedro Vicente 10 months ago

To note that the error happens right after message "WebController: timeout: expiring"


Jul 10 02:39:15 revo nostro_web[1049902]: [2023-Jul-10 02:39:15.259] 1049902 [/ 1Zjc7y1nxwF65bLc] [info] "WebController: timeout: expiring"
Jul 10 02:39:16 revo systemd[1]: wt.pvn.service: Main process exited, code=killed, status=11/SEGV
Jul 10 02:39:16 revo systemd[1]: wt.pvn.service: Failed with result 'signal'.

RE: Main process exited, how to log ? - Added by Stefan Bn 10 months ago

I would change the timeout parameter in wt_config.xml to see if this behavior depends on the timeout (the default value is 600s / 10min - that fits to your timing).

The return status in your logs status=11/SEGV indicates a segmentation fault, a bug in your code. When this always happens after the timeout then it means a particular session is automatically shut down by Wt. I would check all the destructors and if all the allocated memory in your app is released accordingly.

Do you have the chance to let your app just run in a debugger and wait/and see what happens at those timepoints? Ideally the debugger should point to where the issue is.

For debugging purposes, somewhere in your code you could also implement a user/timer-triggered call to void Wt::WApplication::quit(), just to see if your app shuts down gracefully.

Best,
Stefan

RE: Main process exited, how to log ? - Added by Pedro Vicente 10 months ago

Thanks, it was indeed the destructor

 ~ContainerHome()
  {
    auto app = dynamic_cast<NostroApplication*>(Wt::WApplication::instance());
    app->pubkey = m_edit_pubkey->text().toUTF8();
  }

So, I have 2 main containers in 2 different HTML "pages" and they both share a variable stored in the main WApplication

I did not recall that the WApplication instance is destroyed every "timeout" , is that the case?

In this case , that variable must be a global variable then

RE: Main process exited, how to log ? - Added by Pedro Vicente 10 months ago

global variables are a bad practice

One way to avoid this in Wt is to define a inherited class from Wt::WServer
and define variables in it.

Would there be any other preferred way to accomplish this?

int main(int argc, char** argv)
{
    Wt::WServer server(argc, argv);
    server.addEntryPoint(Wt::EntryPointType::Application, create_application);
    server.run();
}

RE: Main process exited, how to log ? - Added by Matthias Van Ceulebroeck 10 months ago

I did not recall that the WApplication instance is destroyed every "timeout" , is that the case?

A WApplication essentially is a session specific instance. Each user that connects to an end-point, will instantiate a session. This each has its own WApplication.

Would there be any other preferred way to accomplish this?

My preferred way would be to define a unique pointer to the resource that functions as a singleton, and ensure that this exists whenever necessary. As an example:

class InstanceClass final
{
  InstanceClass()
  {
    // Do construction

    instance_ = this;
  }

  ~InstanceClass()
  {
    instance_ = nullptr;
  }

  // Presents copy-construction
  InstanceClass(const InstanceClass&) = delete;

  // Presents assignment
  InstanceClass& operator=(const InstanceClass&) = delete;

  // Presents copy-construction (rvalue)
  InstanceClass(InstanceClass&&) = delete;

  // Presents assignment (rvalue)
  InstanceClass& operator=(InstanceClass&&) = delete;

  static const InstanceClass* instance() { return instance_; }

private:
  static InstanceClass* instance_ = nullptr;
}

Then you can define in your main function:

int main(int argc, char** argv)
{
  std::make_unique<InstanceClass> instanceClass = std::make_unique<InstanceClass>();

  Wt::WServer server(argc, argv);
  server.addEntryPoint(Wt::EntryPointType::Application, create_application);
  server.run();
}

You then have access to InstanceClass::instance() in every class where it is included.

    (1-6/6)