0

Fedora 18、2 GB の RAM を搭載した ARMv7-A マシンでアプリケーションを実行しています。

アプリケーションは次のように終了します。

130413 15:49:34 19344 Xrd: PhyConnection: Can't run reader thread: out of system resources. Critical error.

その場合strace、新しいスレッドのスタックの割り当てが失敗することがわかります。

mmap2(NULL, 8388608, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = -1 ENOMEM (Cannot allocate memory)
gettimeofday({1365921367, 588018}, NULL) = 0
gettid()                                = 6309
writev(2, [{"130414 02:36:07 6309 ", 21}, {"Xrd", 3}, {"", 0}, {": ", 2}, {"PhyConnection: Can't run reader "..., 80}, {"\n", 1}], 6130414 02:36:07 6309 Xrd: PhyConnection: Can't ru
n reader thread: out of system resources. Critical error.
) = 107
munmap(0x48172000, 292)                 = 0
munmap(0x48225000, 292)                 = 0

実際のコード:

253       if (fReaderthreadhandler[i]->Run(this)) {
254          Error("PhyConnection",
255                "Can't run reader thread: out of system resources. Critical error.");
256 // HELP: what do we do here
257          exit(-1);
258       }

アプリケーションの仮想メモリ サイズは 300 ~ 350MB で、常駐メモリ サイズは最大 250MB です。高メモリ制限は 1.3GB です。仮想アドレス空間は制限されていません:

-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8192
-c: core file size (blocks)         0
-m: resident set size (kbytes)      unlimited
-u: processes                       1024
-n: file descriptors                1024
-l: locked-in-memory size (kbytes)  64
-v: address space (kbytes)          unlimited
-x: file locks                      unlimited
-i: pending signals                 15870
-q: bytes in POSIX msg queues       819200
-e: max nice                        0
-r: max rt priority                 0
-N 15:                              unlimited

しかし、GDBからは機能します! また、GDB から報告される制限も調べましたが、それらは同じです。したがって、GDB は継承されるソフト制限を調整しません。

概要:

  • アプリケーションを実行するのに十分なメモリがあります。GDB内でも問題なく動作します。
  • リソース制限に達していないようです。
  • GDB で動作しますが、外部では動作しません。

ここで何が間違っている可能性があるかのヒントはありますか?

4

1 に答える 1

0

GDB で動作しますが、外部では動作しません。

「GDB 内」で異なる点の 1 つは、アドレス レイアウト (ランダム化) です。

デバッグを容易にするために、GDB はデフォルトで ASLR を無効にします。あなたはそれを再びオンにすることができます

(gdb) set disable-randomization off

その後、アプリを数回実行し、引き続き確実に動作するかどうかを確認します。

アプリケーションを実行するのに十分なメモリがあります。

失敗している割り当て (マッピング) は 8MB の連続メモリを要求しますが、アドレス空間が断片化されている場合はこれが不足する可能性があります。実際に 8MB のスタックを必要としない場合(ほとんどのアプリケーションでは必要ありません)、大幅に小さい値に設定ulimit -s(またはアプリケーション内から使用) することで、さらに多くのスレッドを取得できます。setrilimit(RLIMIT_STACK, ...)

于 2013-04-14T16:03:39.203 に答える