2013-08-07 3 views
0

Я запускаю vxWorks 6.3 и столкнулся с проблемой. У меня есть ряд задач, выполняющихся как в RTP. Я создаю задачу, делаю вещи, а затем уничтожаю задачу. Затем создайте две задачи, очень близко друг к другу, сделайте что-нибудь и уничтожьте их. Эти задачи должны делать сумасшедшие вещи, такие как malloc и свободная память. К сожалению, если я сделаю это достаточно времени, одна из задач застрянет в памяти (как malloc, так и бесплатно) подпрограмм на семафоре. Это всегда вторая задача, которая «теряется» в самом начале задачи либо в свободном, либо в malloc. После сбоя я все еще могу создавать задачи, и я все еще могу хранить память. Неудачная задача сидит вечно, ожидая семафора ... Семафор, который другие задачи ДОЛЖНЫ использовать.Vxworks застрял в подпрограммах памяти

Кто-нибудь знает, как задача может застрять в подпрограммах памяти?

0x08265e58 malloc  +0x2c : 0x082416f4() 
0x08267e50 memPartAlloc +0x28 : 0x08241734() 
0x08267e0c memPartAlignedAlloc+0x70 : 0x08267c04() 
0x08267c7c memPartFree +0xfc : 0x08240654() 
0x082753c0 semTake  +0x90 : 0x08242534() 
0x082752ec semUMTake +0xd8 : 0x08242514() 
---- system call boundary ---- 

-> tw 0x69d21b0 
    NAME  ENTRY  TID  STATUS DELAY OBJ_TYPE OBJ_ID OBJ_NAME 
---------- ---------- ---------- ---------- ----- ---------- ---------- -------- 
tHttp631-2 0x827dbfc 0x69d21b0 PEND   0 SEM_M  0x6859650 N/A 

Semaphore Id  : 0x6859650 
Semaphore Type  : MUTEX 
Task Queuing  : PRIORITY 
Pended Tasks  : 1 
Owner    : 0x69d1a08 Deleted! 
Options    : 0xd  SEM_Q_PRIORITY 
           SEM_DELETE_SAFE 
           SEM_INVERSION_SAFE 
VxWorks Events 
-------------- 
Registered Task  : NONE 
Event(s) to Send : N/A 
Options    : N/A 
Pended Tasks 
------------ 
    NAME  TID PRI TIMEOUT 
---------- -------- --- ------- 
tHttp631-25502 69d21b0 120  0 
value = 0 = 0x0 
-> 

ответ

0

Несколько вопросов:

  • ли все задачи созданы/удалены в РПТ?
  • Как вы «разрушаете задачу»?
  • Когда тогда заданные блоки являются новыми созданиями malloc/tasks в одном RTP или другом RTP?
  • Вы удаляете все RTP?

Похоже, вы используете taskDelete из одной задачи для уничтожения других задач. Если это так, то возможно, что задача удаляется в середине операции с памятью.

Поскольку это операция malloc в RTP, каждый созданный RTP содержит свой собственный куча (malloc) семафора. Я бы подумал, что это будет семафор.

Я предлагаю связаться с поддержкой Wind River. Это может быть проблема, с которой они знакомы.

+0

Нет, мы не используем taskDelete. Задачи завершают свою работу и возвращаются из вызывающей функции. Все задействованные задачи относятся к одному и тому же процессу RTP. RTP продолжает работать; он не выходит. Мне жаль, что у меня не было возможности связаться с WindRiver, но мы прекратили наш контракт поддержки несколько лет назад. – GailG

1

Рекомендуется выделить достаточное количество памяти для наихудшего случая во время инициализации, а затем просто повторно использовать эту память на протяжении всей вашей программы. Особенно, если у вас действительно есть требования в реальном времени, поскольку malloc/free являются недетерминированными операциями, я также рекомендую повторно использовать задачи, а не воссоздавать новые задачи во время выполнения, а затем использовать семафор или msgQueue для запуска соответствующих задач в соответствующие моменты времени , Таким образом, ваш поток программы может выглядеть примерно так:

initTime() 
{ 
    t1mem = malloc(t1memSize); 
    t2mem = malloc(t2memSize); 
    t3mem = malloc(t3memSize); 
    t1q = msgQCreate(qlen, msglen, MSG_Q_FIFO); 
    t2q = msgQCreate(qlen, msglen, MSG_Q_FIFO); 
    t3q = msgQCreate(qlen, msglen, MSG_Q_FIFO); 
    rspq = msgQCreate(qlen, msglen, MSG_Q_FIFO); 
    taskSpawn("t1", t1pri, ..., t1Entry, t1mem, t1q, rspq, ...); 
    taskSpawn("t2", t2pri, ..., t2Entry, t2mem, t2q, rspq, ...); 
    taskSpawn("t3", t3pri, ..., t3Entry, t3mem, t3q, rspq, ...); 

    runTime(t1sem, t2sem, t3sem, rspq); 

    msgQDelete(t1q); 
    msgQDelete(t2q); 
    msgQDelete(t3q); 
    msgQDelete(rspq); 
    free(t1mem); 
    free(t2mem); 
    free(t3mem); 
} 

runTime(MSG_Q_ID t1q, MSG_Q_ID t2q, MSG_Q_ID t3q, MSG_Q_ID rspq) 
{ 
    while (programRun) 
    { 
     tasksDone = 0; 
     msgQSend(t1q, t1start, msglen, 100, MSG_PRI_NORMAL); 
     if (msgQReceive(rspq, buf, msglen, errorCaseTimeout) == OK) 
     { 
      // check to make sure the msg is t1done... 
      // report error if it isn't... 
      msgQSend(t2q, t2start, msglen, 100, MSG_PRI_NORMAL); 
      msgQSend(t3q, t3start, msglen, 100, MSG_PRI_NORMAL); 
      for (int x = 0; x < 2; x++) 
      { 
       if (msgQReceive(rspq, buf, msglen, errorCaseTimeout) == OK) 
       { 
        // check to make sure the msg is t2done/t3done... 
        // report error if it isn't... 
        tasksDone++; 
       } 
      } 
     } 
     if (tasksDone == 2) 
     { 
      // everything is good... keep on running... 
     } 
     else 
     { 
      // a task didnt finish within the errorCaseTimeout time... 
      // report error or something, maybe set programRun to false... 
     } 
    } 
} 

t1Entry(void* mem, MSG_Q_ID q, MSG_Q_ID rspq) 
{ 
    while (programRun) 
    { 
     if (msgQReceive(q, buf, msglen, 100) == OK) 
     { 
      doTask1(mem); 
      msgQSend(rspq, t1done, msglen, 100, MSG_PRI_NORMAL); 
     } 
    } 
} 

t2Entry(void* mem, MSG_Q_ID q, MSG_Q_ID rspq) 
{ 
    while (programRun) 
    { 
     if (msgQReceive(q, buf, msglen, 100) == OK) 
     { 
      doTask2(mem); 
      msgQSend(rspq, t2done, msglen, 100, MSG_PRI_NORMAL); 
     } 
    } 
} 

t3Entry(void* mem, MSG_Q_ID q, MSG_Q_ID rspq) 
{ 
    while (programRun) 
    { 
     if (msgQReceive(q, buf, msglen, 100) == OK) 
     { 
      doTask3(mem); 
      msgQSend(rspq, t3done, msglen, 100, MSG_PRI_NORMAL); 
     } 
    } 
} 

Очевидно, что приведенный выше код не очень DRY, и не во всех случаях ошибки полностью обработаны, но это начало и имеет хорошие шансы работать детерминировано.

+0

Когда мы попадаем в состояние сбоя, у нас есть 19meg free (и не требуется нигде рядом с ним), поэтому я уверен, что у нас не хватает памяти. Если бы это было просто «из памяти», я должен получить сообщение на консоли, которое я не получаю.Да, моя следующая попытка работать вокруг шла именно так. У меня было два потока, которые я мог бы повторно использовать. Я попробовал пару других работ, но это, похоже, переместило проблему где-то в другом месте. Я надеялся найти основную причину проблемы, чтобы я мог с некоторой уверенностью сказать, что мое окончательное решение не просто маскирует реальную проблему. – GailG

+0

Действительно, я не предполагал, что у вас заканчивается память, вместо этого я предлагаю другой подход, который использует принципы, которые более распространены в системах реального времени/встраиваемых системах. Действительно, вы правы, если есть проблема, этот подход может скрыть это. –

+0

Я также заметил следующее на выходе выше: Владелец: 0x69d1a08 Удаляется! К сожалению, у меня больше нет доступа к системе, источнику или документам vxworks. Но это вызывает беспокойство, если владелец мьютекса был удален, то он никогда не сможет дать семафор, поэтому ваш ожидающий поток (0x69d21b0) будет блокироваться навсегда. –

0

Это может быть связано с проблемой, которую я испытываю, хотя я вижу другой симптом. В обоих случаях владелец семафора удаляется. В моем случае у меня есть зависание и трассировка tWebTask с отсутствующим владельцем семафора в веб-сокете.

Here's the link to my SO question.

Смежные вопросы