Обсуждение: seg fault on dsm_create call

Поиск
Список
Период
Сортировка

seg fault on dsm_create call

От
Max Fomichev
Дата:
Hello,
sorry for my repost from psql-novice, probably it was not a right place 
for my question.

I'm trying to understand how to work with dynamic shared memory, message 
queues and workers.
The problem is I can not initialize any dsm segment -
    void _PG_init() {        ...        dsm_segment *seg = dsm_create(32768, 0); // Segmentation fault 
here        ...        BackgroundWorker worker;        sprintf(worker.bgw_name, "mystem wrapper process");
worker.bgw_flags= BGWORKER_SHMEM_ACCESS;        worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
worker.bgw_restart_time= BGW_NEVER_RESTART;        worker.bgw_main = mainProc;        worker.bgw_notify_pid = 0;
RegisterBackgroundWorker(&worker);   }
 

Also I was trying to move dsm_create call to a worker, but with the same 
result -
    static void mainProc(Datum) {        ...        dsm_segment *seg = dsm_create(32768, 0); // Segmentation fault 
here        ...        pqsignal(SIGTERM, mystemSigterm);        BackgroundWorkerUnblockSignals();        ...

What could be a reason and what am I doing wrong?

PS
test/modules/test_shm_mq works fine...
dynamic_shared_memory_type = posix
OSX 10.11.5
PostgreSQL 9.5.3

-- 
Best regards,
Max Fomichev




Re: seg fault on dsm_create call

От
Robert Haas
Дата:
On Tue, Jun 28, 2016 at 10:11 AM, Max Fomichev <max.fomitchev@gmail.com> wrote:
> Hello,
> sorry for my repost from psql-novice, probably it was not a right place for
> my question.
>
> I'm trying to understand how to work with dynamic shared memory, message
> queues and workers.
> The problem is I can not initialize any dsm segment -
>
>     void _PG_init() {
>         ...
>         dsm_segment *seg = dsm_create(32768, 0); // Segmentation fault here
>         ...
>         BackgroundWorker worker;
>         sprintf(worker.bgw_name, "mystem wrapper process");
>         worker.bgw_flags = BGWORKER_SHMEM_ACCESS;
>         worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
>         worker.bgw_restart_time = BGW_NEVER_RESTART;
>         worker.bgw_main = mainProc;
>         worker.bgw_notify_pid = 0;
>         RegisterBackgroundWorker(&worker);
>     }
>
> Also I was trying to move dsm_create call to a worker, but with the same
> result -
>
>     static void mainProc(Datum) {
>         ...
>         dsm_segment *seg = dsm_create(32768, 0); // Segmentation fault here
>         ...
>         pqsignal(SIGTERM, mystemSigterm);
>         BackgroundWorkerUnblockSignals();
>         ...
>
> What could be a reason and what am I doing wrong?

I think there are two problems.

1. You need to set up a ResourceOwner before you can attach to a DSM
segment.  Something like: CurrentResourceOwner =
ResourceOwnerCreate(NULL, "name of my extension").

2. You can't do this from inside a _PG_init() block.  That will run in
every process that loads this, which is probably not what you want,
and it will run in the postmaster also, which will not work: the
postmaster cannot use DSM.

Actually, I'd like to change #1 at some point, so that if
CurrentResourceOwner = NULL and you create or attach to a DSM, you
just get a backend-lifespan mapping.  The current setup is annoying
rather than helpful.  But currently that's how it is.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company



Re: seg fault on dsm_create call

От
Max Fomichev
Дата:
On 28/06/16 19:24, Robert Haas wrote:
> On Tue, Jun 28, 2016 at 10:11 AM, Max Fomichev <max.fomitchev@gmail.com> wrote:
>> Hello,
>> sorry for my repost from psql-novice, probably it was not a right place for
>> my question.
>>
>> I'm trying to understand how to work with dynamic shared memory, message
>> queues and workers.
>> The problem is I can not initialize any dsm segment -
>>
>>      void _PG_init() {
>>          ...
>>          dsm_segment *seg = dsm_create(32768, 0); // Segmentation fault here
>>          ...
>>          BackgroundWorker worker;
>>          sprintf(worker.bgw_name, "mystem wrapper process");
>>          worker.bgw_flags = BGWORKER_SHMEM_ACCESS;
>>          worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
>>          worker.bgw_restart_time = BGW_NEVER_RESTART;
>>          worker.bgw_main = mainProc;
>>          worker.bgw_notify_pid = 0;
>>          RegisterBackgroundWorker(&worker);
>>      }
>>
>> Also I was trying to move dsm_create call to a worker, but with the same
>> result -
>>
>>      static void mainProc(Datum) {
>>          ...
>>          dsm_segment *seg = dsm_create(32768, 0); // Segmentation fault here
>>          ...
>>          pqsignal(SIGTERM, mystemSigterm);
>>          BackgroundWorkerUnblockSignals();
>>          ...
>>
>> What could be a reason and what am I doing wrong?
> I think there are two problems.
>
> 1. You need to set up a ResourceOwner before you can attach to a DSM
> segment.  Something like: CurrentResourceOwner =
> ResourceOwnerCreate(NULL, "name of my extension").
>
> 2. You can't do this from inside a _PG_init() block.  That will run in
> every process that loads this, which is probably not what you want,
> and it will run in the postmaster also, which will not work: the
> postmaster cannot use DSM.
>
> Actually, I'd like to change #1 at some point, so that if
> CurrentResourceOwner = NULL and you create or attach to a DSM, you
> just get a backend-lifespan mapping.  The current setup is annoying
> rather than helpful.  But currently that's how it is.
>
Thanks.
It works now with CurrentResourceOwner = ResourceOwnerCreate(NULL, "name 
of my extension")

I am a little bit confused about test/modules/test_shm_mq, where 
CurrentResourceOwner is set up before dsm_attach, not dsm_create -
    /*     * Connect to the dynamic shared memory segment.     *     * The backend that registered this worker passed
usthe ID of a shared     * memory segment to which we must attach for further instructions.  In     * order to attach
todynamic shared memory, we need a resource owner.     * Once we've mapped the segment in our address space, attach to

the table     * of contents so we can locate the various data structures we'll 
need to     * find within the segment.     */    CurrentResourceOwner = ResourceOwnerCreate(NULL, "test_shm_mq
worker");   seg = dsm_attach(DatumGetInt32(main_arg));
 

-- 
Best regards,
Max Fomichev




Re: seg fault on dsm_create call

От
Robert Haas
Дата:
On Tue, Jun 28, 2016 at 12:45 PM, Max Fomichev <max.fomitchev@gmail.com> wrote:
> On 28/06/16 19:24, Robert Haas wrote:
> Thanks.
> It works now with CurrentResourceOwner = ResourceOwnerCreate(NULL, "name of
> my extension")
>
> I am a little bit confused about test/modules/test_shm_mq, where
> CurrentResourceOwner is set up before dsm_attach, not dsm_create -

You need a resource owner for either dsm_attach or dsm_create.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company