2

安らかなインターフェイスにする必要がある Web アプリがあります。そのため、インバウンド要求を gwan が使用できるものに変更しようとする接続ハンドラーがあります。

このサービスへのすべての接続は同じであるため、すべての接続で置換を行っています。

  #include "gwan.h" // G-WAN exported functions

  #include <stdio.h>
  int init(int argc, char *argv[]){
     u32 *states = (u32*)get_env(argv, US_HANDLER_STATES);
     *states = 1 << HDL_AFTER_READ; // we assume "GET /hello" sent in one shot
     return 0;
  }

  void clean(int argc, char *argv[]){}

  int main(int argc, char *argv[])
  {
     const long state = (long)argv[0];
     if(state == HDL_AFTER_READ) {
        xbuf_t *read_xbuf = (xbuf_t*)get_env(argv, READ_XBUF);
        xbuf_replfrto(read_xbuf, read_xbuf->ptr, read_xbuf->ptr + 16, "/classify.htm?", "/?boost.cpp&");
     }

     return 255;
  }

問題は、負荷がかかると、しばらくすると G-WAN がクラッシュし、エラーが表示されることです。

G-WAN 4.3.14 (pid:20477)

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_S_construct NULL not valid


Signal        : 6:Abort
Signal src    : -6:tkill
errno         : 0
Thread        : 2
Code   Pointer: 7fc5dcd748a5 (module:libc.so.6, function:raise, line:0)
Access Address: 000000004ffd

Registers     : EAX=000000000000 CS=00000033 EIP=7fc5dcd748a5 EFLGS=000000000202
                EBX=0000006693e8 SS=0000000a ESP=7fc5d5c7bf38 EBP=7fc5880008d8
                ECX=ffffffffffffffff DS=0000000a ESI=00000000504e FS=00000033
                EDX=000000000006 ES=0000000a EDI=000000004ffd CS=00000033

Module         :Function        :Line # PgrmCntr(EIP)  RetAddress  FramePtr(EBP)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Aborted (core dumped)

問題は、サーバーに負荷をかけたときだけです。1 台のマシンで 1 秒あたり約 8000 リクエストに達しており、クラッシュするまで約 5 秒かかります。

書き換えを行わず (main.c を main.c_ に移動)、cpp スクリプトを直接呼び出すと、クラッシュは発生しません...

ヘルプ!何か案は?

ありがとう

4

2 に答える 2

1

それはコードの別の部分にありました... 最大の手がかりは、C++ の未処理の例外が発生しているように見えたことです。

ドキュメントによると、G-Wan は C で書かれています。

コードを掘り下げて、コードがクラッシュしていると思われる場所に例外処理を追加したところ、例外が表示されましたが、サーバーは動作し続けました。これは私が望んでいたことです!

私が修正したスニペット:

try {
  get_arg("key=",&name,argc,argv);
  string url = name;

  boost::thread cls(classify_url,url,boost::ref(rp));
  if(!cls.timed_join(boost::posix_time::milliseconds(8))) {
   cls.interrupt();
   rp="{\"c\": [998]}";
  }
}
catch(...) {
   rp="{\"c\": [997]}";
   cout << "EXCEPTION" << endl;
}

try/catch を追加しました。すべて問題ありません。

于 2013-07-09T13:02:03.227 に答える