Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Parrot interpreter segfaults in embedding context upon sleep #798

Closed
bdw opened this Issue · 12 comments

4 participants

@bdw

A fresh morning, gives us a fresh segmentation violation. And, I even know where.
When (in the embedded context of mod_parrot) I call upon 'sleep(1)' to wait for a second I receive a segmentation violation, with the following backtrace:

#0 0xb78269b7 in Parrot_cx_stop_task (interp=0x80099270, next=0x8059182c)
at src/scheduler.c:328
#1 0xb7827450 in Parrot_cx_schedule_sleep (interp=0x80099270, time=1,
next=0x8059182c) at src/scheduler.c:641
#2 0xb77b3467 in Parrot_sleep_ic (cur_opcode=0x80591824, interp=0x80099270)
at src/ops/core_ops.c:22117
#3 0xb78201d7 in runops_fast_core (interp=0x80099270,
runcore_unused=0x8016e660, pc=0x80591824) at src/runcore/cores.c:499
#4 0xb781f719 in runops_int (interp=0x80099270, offset=0)
at src/runcore/main.c:220
#5 0xb77f6be0 in runops (interp=0x80099270, offs=0) at src/call/ops.c:126
#6 0xb77f001c in Parrot_pcc_invoke_from_sig_object (interp=0x80099270,
sub_obj=0x801c1a30, call_object=0x801aebbc) at src/call/pcc.c:338
#7 0xb77d2823 in Parrot_api_pmc_invoke (
interp_pmc=interp_pmc@entry=0x8016a400, sub=0x801c1a30,
signature=0x801aebbc) at src/embed/pmc.c:544
#8 0xb7fda7b4 in mod_parrot_run (interp=interp@entry=0x8016a400,
req=req@entry=0x800f9390, compilerName=0x80086348 "winxed")
at mod_parrot_run.c:66

(The rest is all apache). Closer inspection gives us that interp->cur_task is 0x0, and the local task variable is the same. Thus we crash at exactly line 328 of src/scheduler.c, which looks like this:

#327 PMC * const task = Parrot_cx_current_task(interp);
#328 Parrot_Task_attributes * const tdata = PARROT_TASK(task);

My gut feeling is that this is an embedding API issue. Any comments are greatly appreciated.

@niner
Collaborator
@bdw

The other way to start parrot executing code is to:

  • Load bytecode using Parrot_api_load_bytecode_file
  • 'Readify' this bytecode using Parrot_api_ready_bytecode (i.e., bring it into the interpreter, returning its main subroutine)
  • Invoke this subroutine using Parrot_pmc_invoke

And this is useful for me as it allows me to pass multiple (complex) arguments to my loader functions, one of which is a pointer.
The workarround means passing those same arguments in an array, which is kludgey from my perspective.
In short, I believe the 'subroutine invocation' flow I described is legitimate.

@leto
Owner

I agree that @bdw's workflow is legitimate. It is just that nobody has tickled this codepath from the new embedding API, previously. @niner what are our options for making it work?

@rurban
Collaborator

@bdw: Can you please try the threads branch? I assume it will work over there.

@bdw

@rurban The fault persists with the threads branch. I somehow can't get debugging symbols with my local installation of gdb, unfortunately, so I can't really help with.

For others whishing to reproduce it, just clone mod_parrot.git, run Configure.pl, and type 'make test'. It should eventually launch gdb. Then, request http://localhost:8000/streaming.wxd; this should hang, and gdb should have caught a segfault.

I'm thinking of ways to make it work, but most of them require some restructuring of parrot as far as i can tell.
For the record and those worrying, I'm not stuck on this, there are plenty of other things I can and need to do.

@niner
Collaborator
@bdw

@niner It is a bit more subtle than that. If, for example, you run a compiler via the api, you can do this now, but only using pmc_invoke. You can use Parrot_api_pmc_invoke for callling different functions of a script (or different methods on an object); I think this is useful for an embedded language. For me, this is convenience; for other uses it is a necessity. I will post a report on the call stack for both approaches here.

@bdw

What is boils down to:
Parrot_api_pmc_invoke calls Parrot_pcc_invoke_from_sig_object, and this starts running code
Parrot_api_run_bytecode calls Parrot_pf_execute_bytecode_program which calls Parrot_cx_begin_execution which calls Parrot_cx_outer_runloop which calls Parrot_ext_call which calls Parrot_pcc_invoke_from_sig_object

Now, I am confused, because there is no obvious method to make the first and the second method converge somewhere before Parrot_pcc_invoke_from_sig_object.
I am very confused in general.
Would it be a reasonable thing to create a task for the interpreter upon running construction?
I'm thinking some more on this.

@niner
Collaborator
@niner
Collaborator

I have implemented my suggestion in the gh798_embed_api_green_threads branch (based on the threads branch). Does it fix the issue for you?

The existing tests do pass with this branch, but it's incomplete, since in the examples the scheduler's initialization is not done fully. Have to move threading initialization out of Parrot_cx_begin_execution and somewhere where it's run even in embedding situations, e.g. Parrot_api_make_interpreter

@bdw

Yes, this does fix it. So, I'm happy for now.

@rurban
Collaborator

This fix d215d68 is in master

@rurban rurban closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.