Старт потока

Тема в разделе "WASM.BEGINNERS", создана пользователем OFFSIDE, 30 июн 2008.

  1. OFFSIDE

    OFFSIDE New Member

    Публикаций:
    0
    Регистрация:
    23 сен 2006
    Сообщения:
    106
    При создании потока функцией CreateThread создается поток, в нем инициализируются локальные переменные(вместе со структурами примерно 8 кб), затем идет вызов подпрограммы, в которой инициализация переменных приводит к краху приложения. Поток создается в длл, под отладчиком все работает замечательно. Если перед вызовом подпрограммы вывести мессаджбокс то по его закрытию приложение продолжает работу без проблем...
    Код длл:

    Код (Text):
    1. Creating_ars struct
    2.     Ip      DB 128  dup(?)
    3.     Port    DB 128  dup(?)
    4.     RemIP   DB 128  dup(?)
    5.     Number  DB 128  dup(?)
    6.     User    DB 128  dup(?)
    7.     CID     DB 128  dup(?)
    8.     NUM     DB 128  dup(?)
    9.     Expir   DB 128  dup(?)
    10.     Auth    DB 256  dup(?)
    11.     Data    DB 1536 dup(?)
    12.     tag     DB 128  dup(?)
    13.     intag   DB 128  dup(?)
    14.     port    dd  ?
    15. Creating_ars ends
    16.  
    17. Parsing_ars struct
    18.     Typ        db 128 dup(?)
    19.     From       db 128 dup(?)
    20.     To         db 128 dup(?)
    21.     VIA        db 128 dup(?)
    22.     cyseq      db 128 dup(?)
    23.     Auth       db 256 dup(?)
    24.     tag        db 128 dup(?)
    25.     intag      db 128 dup(?)
    26.     Contact    db 128 dup(?)
    27.     Call_ID    db 128 dup(?)
    28.     ToNum      db 128 dup(?)
    29.     Expir      db 128 dup(?)
    30. Parsing_ars ends
    31.  
    32. Ringing struct
    33.     hiThr   dd ?
    34.     Number  db 16 dup (?)
    35. Ringing ends
    36.  
    37. InitThread struct
    38.     AddrOf  dd  ?               ;адрес структуры
    39.     CHN     DD  ?           ;номер канала
    40.     Evnt    dd  ?               ;Event управления потоком
    41.     StopEv  dd  ?               ;Event остановки потоков
    42.     isFree  dd  ?               ;flag освобождения канала
    43.     EventSt dd  ?               ;Event
    44.     ownPort dd  ?               ;порт управления на клиенте
    45.     RemPort dd  ?               ;порт управления на сервере
    46.     SDPport dd  ?               ;порт для РТП потока
    47.     s       dd  ?           ;socket для управления
    48.     sSDP    dd  ?               ;socket для РТП потока
    49.     hClb    dd  ?               ;колбэк функция
    50.     regTm   dd  ?               ;время регистрации
    51.     fName   dd  ?               ; имя файла для проигрывания
    52.     User    DB  32 DUP (?)      ; Имя пользователя
    53.     Pass    DB  32 DUP (?)      ; Пароль
    54.     SDPIP   db  32 dup (?)      ; адрес для РТП потока
    55.     ownIP   db  32 dup (?)
    56.     remIP   db  32 dup (?)
    57.     CID     db  128 dup (?)
    58.     datas   db  2048    dup(?)  ;передаваемые в поток данные
    59. InitThread ends
    60.  
    61.  
    62. ProbeRing proc Number:dword,fName:dword
    63. LOCAL rin:Ringing,TID:InitThread
    64. LOCAL chn:dword,td:dword
    65.  mov chn,0
    66.     .while TRUE
    67.         mov eax,maxChn
    68.         cmp chn,eax
    69.         je m2
    70.         mov eax,4
    71.         mov ecx,chn
    72.         mul ecx
    73.         lea ebx,ManageTh
    74.         add ebx,eax
    75.         mov eax,[ebx]
    76.         mov td,eax
    77.         invoke RtlMoveMemory,addr TID,td,sizeof TID
    78.         cmp TID.isFree,0
    79.         jne m1
    80.         invoke CreateEvent,0,TRUE,FALSE,0
    81.         mov TID.Evnt,eax
    82.         m2m TID.fName,fName
    83.         mov ebx,TID.AddrOf
    84.         invoke RtlMoveMemory,[ebx],addr TID,sizeof TID
    85.         invoke lstrcpy,addr rin.Number,Number
    86.         m2m rin.hiThr,TID.CHN
    87.         invoke CreateThread,0,0,addr RingOut,addr rin,0,0
    88.         cmp eax,0
    89.         je m2
    90.         invoke CloseHandle,eax
    91.         invoke WaitForSingleObject,TID.Evnt,INFINITE
    92.         mov eax,chn
    93.         ret
    94. m1:
    95.         inc chn
    96.     .endw
    97. m2:
    98.     mov eax,-1
    99.     ret
    100.  
    101. ProbeRing endp
    102.  
    103. RingOut proc parm:dword
    104. LOCAL CID1 [64]:byte,CID [64]:byte
    105. LOCAL Parse:Parsing_ars,User [16]:byte,PromTAG [32]:byte
    106. LOCAL TID:InitThread,ca:Creating_ars
    107. LOCAL EP [2]:dword,rin:Ringing
    108. LOCAL td:dword,i:dword,hClb:dword,TNO:dword
    109. LOCAL ress:dword,tHR:dword
    110.     invoke RtlZeroMemory,addr ca,sizeof ca
    111.     invoke RtlZeroMemory,addr rin,sizeof rin
    112.     invoke RtlZeroMemory,addr TID,sizeof TID
    113.     invoke RtlZeroMemory,addr Parse,sizeof Parse
    114.     invoke RtlZeroMemory,addr User,sizeof User
    115.     invoke RtlZeroMemory,addr PromTAG,sizeof PromTAG
    116.     invoke RtlZeroMemory,addr CID1,sizeof CID1
    117.     invoke RtlZeroMemory,addr CID,sizeof CID
    118.     invoke RtlZeroMemory,addr EP,sizeof EP
    119.     invoke RtlMoveMemory,addr rin,parm,sizeof rin
    120.     INVOKE LocalAlloc,LMEM_FIXED OR LMEM_ZEROINIT,2048
    121.     INVOKE LocalLock,eax
    122.     mov ress,eax
    123.     mov eax,4
    124.     mul rin.hiThr
    125.     lea ebx,ManageTh
    126.     add ebx,eax
    127.     mov eax,[ebx]
    128.     mov td,eax
    129.     invoke RtlMoveMemory,addr TID,td,sizeof TID
    130. ChistInv:
    131.     invoke GetTickCount
    132.     invoke lstrcpy,addr CID1,str$(eax)
    133.     invoke GetTickCount
    134.     invoke lstrcpy,addr CID1+8,str$(eax)
    135.     invoke procMD5hash,addr CID1,32
    136.     invoke lstrcpyn,addr CID,addr CID1,32
    137.     m2m hClb,TID.hClb
    138.     invoke EnterCriticalSection,addr CRS
    139.     inc NumberReq
    140.     invoke LeaveCriticalSection,addr CRS
    141.     invoke RtlZeroMemory,addr ca,sizeof ca
    142.     m2m ca.port,TID.s
    143.     invoke lstrcpy,addr ca.Ip,addr TID.ownIP
    144.     invoke lstrcpy,addr ca.Port,str$(TID.ownPort)
    145.     invoke lstrcpy,addr ca.NUM,str$(NumberReq)
    146.     invoke lstrcpy,addr ca.RemIP,addr TID.remIP
    147.     invoke lstrcpy,addr ca.User,addr TID.User
    148.     invoke lstrcpy,addr ca.CID,addr CID
    149.     invoke lstrcpy,addr TID.CID,addr ca.CID
    150.     invoke lstrcpy,addr ca.Number,addr rin.Number
    151.     invoke lstrcpy,addr ca.tag,CTXT("tag=")
    152.     invoke lstrcat,addr ca.tag,addr PromTAG
    153.     invoke lstrcpy,addr ca.Expir,str$(TID.regTm)
    154.     MOV ca.Auth,0
    155.     MOV ca.tag,0
    156.     MOV ca.intag,0
    157.     ;invoke MessageBox,0,0,0,MB_OK
    158.     invoke CreateInvite,addr ca
    159.     invoke lstrcpy,ress,eax
    160. .....
    161.  
    162.  
    163. ret
    164. RingOut endp
    165.  
    166. CreateInvite proc CA:dword
    167. LOCAL Result [2048]:byte
    168. LOCAL ca:Creating_ars
    169. LOCAL Parse:Parsing_ars
    170. LOCAL Result1 [512]:byte
    171. invoke RtlZeroMemory,addr ca,sizeof ca
    172. invoke RtlMoveMemory,addr ca,CA,sizeof ca
    173. invoke RtlZeroMemory,addr Result,sizeof Result
    174. invoke RtlZeroMemory,addr Result1,sizeof Result1
    175. invoke RtlZeroMemory,addr Parse,sizeof Parse
    176. ...
    177.  
    178. ret
    179. RingOut endp
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Код (Text):
    1.     mov eax,4
    2.     mul rin.hiThr ;<--Не совсем понятно, ты обращаешься к перменной в стеке другого потока?
    3.     lea ebx,ManageTh
    4.     add ebx,eax
     
  3. OFFSIDE

    OFFSIDE New Member

    Публикаций:
    0
    Регистрация:
    23 сен 2006
    Сообщения:
    106
    Скажем проще;)

    Код (Text):
    1. WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
    2.     mov     eax,uMsg
    3.     .if eax==WM_INITDIALOG
    4.         push    hWin
    5.         pop     hWnd
    6.         invoke CreateThread,0,0,addr prose,0,0,0
    7.     .elseif eax==WM_COMMAND
    8.         mov     eax,wParam
    9.         and     eax,0FFFFh
    10.         .if eax==IDM_FILE_EXIT
    11.             invoke SendMessage,hWin,WM_CLOSE,0,0
    12.         .elseif eax==IDM_HELP_ABOUT
    13.             invoke ShellAbout,hWin,addr AppName,addr AboutMsg,NULL
    14.         .endif
    15. ;   .elseif eax==WM_SIZE
    16.     .elseif eax==WM_CLOSE
    17.         invoke DestroyWindow,hWin
    18.     .elseif uMsg==WM_DESTROY
    19.         invoke PostQuitMessage,NULL
    20.     .else
    21.         invoke DefWindowProc,hWin,uMsg,wParam,lParam
    22.         ret
    23.     .endif
    24.     xor    eax,eax
    25.     ret
    26.  
    27. WndProc endp
    28.  
    29. prose proc param:dword
    30.  
    31. LOCAL mi [18024]:byte
    32.     invoke pros2,0
    33.     ret
    34.  
    35. prose endp
    36.  
    37. pros2 proc param:dword
    38.     invoke MessageBox,0,0,0,MB_OK
    39.     ret
    40.  
    41. pros2 endp
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    OFFSIDE
    Видимо выскакиваешь за сторожевую страницу стека. При выделении больших объемов локальных переменных нужно пробежаться по страницам стека "сверху вниз" от ebp к esp, читая по одному дворду из каждой страницы
     
  5. OFFSIDE

    OFFSIDE New Member

    Публикаций:
    0
    Регистрация:
    23 сен 2006
    Сообщения:
    106
    leo
    Приблизительный код?
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Приблизительно так:
    Код (Text):
    1.  lea eax,[ebp-4]
    2. @@:
    3.   test [eax],eax
    4.   sub eax,1000h
    5.   cmp eax,esp
    6.   jge @B
     
  7. OFFSIDE

    OFFSIDE New Member

    Публикаций:
    0
    Регистрация:
    23 сен 2006
    Сообщения:
    106
    leo


    Спасибо, проблема решена. Очень плохо, что компилятор или система не справляется с данной задачей.
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Смотря какой компилятор ;) В языках высокого уровня код probe_stack вставляется автоматически, если размер локальных переменных превышает 4К. Ну а на асме ес-но все приходится делать ручками, хотя в принципе при использовании макросов LOCAL\locals можно было бы делать подсчет общего размера локальных переменных и при необходимости вставлять код probe_stack
    PS: система ес-но этим заниматься не должна, т.к. использование сторожевой страницы стека помимо обеспечения его динамического роста по мере необходимости, также дает доп.защиту от ошибок
     
  9. OFFSIDE

    OFFSIDE New Member

    Публикаций:
    0
    Регистрация:
    23 сен 2006
    Сообщения:
    106
    Насколько я понимаю, в ebp и esp как раз и находится размер локальных переменных. По поводу системы можно было бы и поспорить:). А компилятор масма хотелось бы и подновить.
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    И что ? Вставлять probe_stack в каждую функцию ? По хорошему размер нужно анализировать не в рантайме, а на этапе компиляции и вставлять probe_stack только в случае необходимости (что собс-но высокоуровневые компилеры и делают)

    Можно, но бесполезно ;) По сложившейся традиции стек растет сверху вниз и для экономии памяти винда обеспечивает динамический рост стека при обращении к сторожевой странице, передвигая ее вниз. Доступ к страницам ниже сторожевой запрещен и добраться до них можно только последовательно перемещая сторожевую страницу