Search code examples
pthreadsarmdisassemblyqemu

Why is qemu-arm running pthread_join repeatedly in this arm assembly code?


I wrote this arm assembler code calling pthread to implement multi-threading features. I wrote two similar files, but this one is quite tricky.

The main function is:

main:
stmfd           sp!, {fp,lr}

add             fp, sp, #4
sub             sp, sp, #8

sub             r3, sp, #8
mov             r0, r3
mov             r1, #0
ldr             r2, .l_thrd1
mov             r3, #0
bl              pthread_create

ldr r3, [fp, #-8]
mov r0, r3
mov r1, #0
bl pthread_join
...

use objdump to see the related disassembled code:

00405468 <pthread_join>:
  405468:       e5903068        ldr     r3, [r0, #104]  ; 0x68
  40546c:       e92d45f0        push    {r4, r5, r6, r7, r8, sl, lr}
  405470:       e3530000        cmp     r3, #0
  405474:       e24dd014        sub     sp, sp, #20
  405478:       e1a05000        mov     r5, r0
  40547c:       e1a06001        mov     r6, r1
  405480:       ba00004a        blt     4055b0 <pthread_join+0x148>
  405484:       e590321c        ldr     r3, [r0, #540]  ; 0x21c
  ....

It looks normal, unless it caused the segment error. The qemu.log looks messy and crappy around this:

----------------
IN: pthread_join
INST: isa=[0] opk=[JMP_OP] src={-,-,-,-} dst={-,-} shift={-,-,-} c=[1] s=[-] imm=[24,74] rotate_reg=[-] vfp={-,-,-,-} vfp_val={-,-,-,-} ### 
0x00405468:  e5903068      ### ldr  r3, [r0, #104]
0x0040546c:  e92d45f0      ### push     {r4, r5, r6, r7, r8, sl, lr}
0x00405470:  e3530000      ### cmp      r3, #0  ; 0x0
0x00405474:  e24dd014      ### sub      sp, sp, #20     ; 0x14
0x00405478:  e1a05000      ### mov      r5, r0
0x0040547c:  e1a06001      ### mov      r6, r1
0x00405480:  ba00004a      ### b.lt     0x4055b0

----------------
IN: pthread_join
INST: isa=[0] opk=[JMP_OP] src={-,-,-,-} dst={-,-} shift={-,-,-} c=[1] s=[-] imm=[24,74] rotate_reg=[-] vfp={-,-,-,-} vfp_val={-,-,-,-} ### 
0x00405468:  e5903068      ### ldr  r3, [r0, #104]
0x0040546c:  e92d45f0      ### push----------------
IN: start_thread
INST: isa=[0] opk=[JMP_OP] src={-,-,-,-} dst={-,-} shift={-,-,-} c=[0] s=[-] imm=[24,4148] rotate_reg=[-] vfp={-,-,-,-} vfp_val={-,-,-,-} ### 
0x00404274:  e7802003      ###    str{r4, r5      , r6, r7r2, ,r8,  sl[r0, , lrr3}]
0x00405470:  e3530000      ###
....

Obviously, pthread_join has been entered twice. And at the second time, the 'push' instruction seems not to have been fully executed. The registers also seem normal. I just do not get it.

Another code runs in the right order. They almost same coded.


Solution

  • Nobody's got an answer for the question. I got to answer it myself.

    The problem was caused by because stack pointer (r13) was unintentionally saved on the memory and changed by another thread. So r13 pointed to another memory address and caused the segment error.