Browse Source

NSM Proxy: Detect, log, and display startup errors of proxied process.

tags/non-daw-v1.2.0
Jonathan Moore Liles 10 years ago
parent
commit
e230929a57
2 changed files with 119 additions and 11 deletions
  1. +56
    -0
      session-manager/src/nsm-proxy-gui.C
  2. +63
    -11
      session-manager/src/nsm-proxy.C

+ 56
- 0
session-manager/src/nsm-proxy-gui.C View File

@@ -26,6 +26,7 @@
#define APP_TITLE "NSM Proxy" #define APP_TITLE "NSM Proxy"


#include <FL/Fl_File_Chooser.H> #include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Text_Display.H>
#include "NSM_Proxy_UI.H" #include "NSM_Proxy_UI.H"
#include <lo/lo.h> #include <lo/lo.h>
#include <signal.h> #include <signal.h>
@@ -38,6 +39,8 @@ lo_address nsmp_addr;


static NSM_Proxy_UI *ui; static NSM_Proxy_UI *ui;


static char *client_error;

int int
osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data )
{ {
@@ -73,6 +76,16 @@ osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_me
else if ( argv[0]->i == SIGHUP ) else if ( argv[0]->i == SIGHUP )
ui->stop_signal_choice->value( 2 ); ui->stop_signal_choice->value( 2 );
} }
if (!strcmp( path, "/nsm/proxy/client_error" ))
{
if ( client_error != NULL )
free(client_error);

client_error = NULL;

if ( strlen(&argv[0]->s) > 0 )
client_error = strdup(&argv[0]->s);
}


Fl::unlock(); Fl::unlock();


@@ -101,6 +114,7 @@ init_osc ( const char *osc_port )
lo_server_thread_add_method( loth, "/nsm/proxy/label", "s", osc_update, NULL ); lo_server_thread_add_method( loth, "/nsm/proxy/label", "s", osc_update, NULL );
lo_server_thread_add_method( loth, "/nsm/proxy/save_signal", "i", osc_update, NULL ); lo_server_thread_add_method( loth, "/nsm/proxy/save_signal", "i", osc_update, NULL );
lo_server_thread_add_method( loth, "/nsm/proxy/stop_signal", "i", osc_update, NULL ); lo_server_thread_add_method( loth, "/nsm/proxy/stop_signal", "i", osc_update, NULL );
lo_server_thread_add_method( loth, "/nsm/proxy/client_error", "s", osc_update, NULL );


lo_server_thread_start( loth ); lo_server_thread_start( loth );
} }
@@ -202,6 +216,46 @@ connect_ui ( void )




void cb_dismiss_button ( Fl_Widget *w, void *v )
{
w->window()->hide();
}

void
check_error ( void *v )
{
if ( client_error )
{
{
Fl_Double_Window *o = new Fl_Double_Window(600,300+15,"Abnormal Termination");
{
Fl_Box *o = new Fl_Box(0+15,0+15,600-30,50);
o->box(FL_BORDER_BOX);
o->color(FL_RED);
o->labelcolor(FL_WHITE);
o->align(FL_ALIGN_CENTER|FL_ALIGN_WRAP);
o->copy_label( client_error );
}
{
Fl_Text_Display *o = new Fl_Text_Display(0+15,50+15,600-30,300-75-30);
o->buffer(new Fl_Text_Buffer());
o->buffer()->loadfile( "error.log" );
}
{
Fl_Button *o = new Fl_Button(600-75-15,300-25,75,25,"Dismiss");
o->callback(cb_dismiss_button,0);
}

o->show();
}
free(client_error);
client_error = NULL;
}
Fl::repeat_timeout( 0.5f, check_error, v );
}

int int
main ( int argc, char **argv ) main ( int argc, char **argv )
{ {
@@ -229,6 +283,8 @@ main ( int argc, char **argv )


Fl::lock(); Fl::lock();


Fl::add_timeout( 0.5f, check_error, NULL );

Fl::run(); Fl::run();


return 0; return 0;


+ 63
- 11
session-manager/src/nsm-proxy.C View File

@@ -51,6 +51,7 @@ static char *nsm_display_name;


#define CONFIG_FILE_NAME "nsm-proxy.config" #define CONFIG_FILE_NAME "nsm-proxy.config"


void show_gui ( void );


class NSM_Proxy { class NSM_Proxy {


@@ -61,25 +62,46 @@ class NSM_Proxy {
int _save_signal; int _save_signal;
int _stop_signal; int _stop_signal;
int _pid; int _pid;
char *_client_error;


public: public:


int stop_signal ( void ) {return _stop_signal;}

NSM_Proxy ( ) NSM_Proxy ( )
{ {
_label = _executable = _arguments = _config_file = 0; _label = _executable = _arguments = _config_file = 0;
_save_signal = 0; _save_signal = 0;
_stop_signal = SIGTERM; _stop_signal = SIGTERM;
_pid = 0; _pid = 0;
_client_error = 0;
} }


~NSM_Proxy ( ) ~NSM_Proxy ( )
{ {
} }

void handle_client_death ( int status )
{
printf( "proxied process died unexpectedly... not dying\n" );
/* proxied process died unexpectedly */

if ( _client_error != NULL )
free(_client_error);

asprintf(&_client_error, "The proxied process terminated abnormally during invocation. Exit status: %i.", status );

show_gui();

_pid = 0;
}

void kill ( void ) void kill ( void )
{ {
if ( _pid ) if ( _pid )
{
::kill( _pid, _stop_signal ); ::kill( _pid, _stop_signal );
}
} }


bool start ( const char *executable, const char *arguments, const char *config_file ) bool start ( const char *executable, const char *arguments, const char *config_file )
@@ -130,11 +152,11 @@ public:
char *cmd; char *cmd;


if ( _arguments ) if ( _arguments )
asprintf( &cmd, "exec %s %s", _executable, _arguments );
asprintf( &cmd, "exec %s %s >error.log 2>&1", _executable, _arguments );
else else
asprintf( &cmd, "exec %s", _executable );
asprintf( &cmd, "exec %s >error.log 2>&1", _executable );


char *args[] = { _executable, strdup( "-c" ), cmd, NULL };
char *args[] = { strdup("/bin/sh"), strdup( "-c" ), cmd, NULL };
setenv( "NSM_CLIENT_ID", nsm_client_id, 1 ); setenv( "NSM_CLIENT_ID", nsm_client_id, 1 );
setenv( "NSM_SESSION_NAME", nsm_display_name, 1 ); setenv( "NSM_SESSION_NAME", nsm_display_name, 1 );
@@ -145,8 +167,7 @@ public:
if ( -1 == execvp( "/bin/sh", args ) ) if ( -1 == execvp( "/bin/sh", args ) )
{ {
WARNING( "Error starting process: %s", strerror( errno ) ); WARNING( "Error starting process: %s", strerror( errno ) );
exit(-1);
exit(1);
} }
} }


@@ -222,7 +243,6 @@ public:
bool restore ( const char *path ) bool restore ( const char *path )
{ {
FILE *fp = fopen( path, "r" ); FILE *fp = fopen( path, "r" );

if ( ! fp ) if ( ! fp )
{ {
WARNING( "Error opening file for restore: %s", strerror( errno ) ); WARNING( "Error opening file for restore: %s", strerror( errno ) );
@@ -285,6 +305,9 @@ public:
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/arguments", "s", _arguments ? _arguments : "" ); lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/arguments", "s", _arguments ? _arguments : "" );
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/config_file", "s", _config_file ? _config_file : "" ); lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/config_file", "s", _config_file ? _config_file : "" );
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/stop_signal", "i", _stop_signal ); lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/stop_signal", "i", _stop_signal );
lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/client_error", "s", _client_error ? _client_error : "" );


} }
}; };


@@ -400,7 +423,7 @@ show_gui ( void )
{ {
WARNING( "Error starting process: %s", strerror( errno ) ); WARNING( "Error starting process: %s", strerror( errno ) );
exit(-1);
exit(1);
} }
} }
@@ -649,10 +672,39 @@ void handle_sigchld ( )
continue; continue;
} }


/* otherwise, it was our proxied process that died, so we should die too */
printf( "proxied process died... nsm-proxy dying too\n" );
if ( WIFSIGNALED(status) )
{
/* process was killed via signal */
if (WTERMSIG(status) == SIGTERM ||
WTERMSIG(status) == SIGHUP ||
WTERMSIG(status) == SIGINT ||
WTERMSIG(status) == SIGKILL )
{
/* process was killed via an appropriate signal */
MESSAGE( "child was killed (maybe by us)\n" );
die_now = 1;
continue;
}
}
else if ( WIFEXITED(status) )
{
/* child called exit() or returned from main() */

MESSAGE( "child exit status: %i", WEXITSTATUS(status) );


die_now = 1;
if ( WEXITSTATUS(status) == 0 )
{
/* apparently normal termination */
MESSAGE( "child exited without error.");
die_now = 1;
continue;
}
else
{
MESSAGE("child exited abnormally.");
nsm_proxy->handle_client_death(WEXITSTATUS(status));
}
}
} }
} }




Loading…
Cancel
Save