Untitled

 avatar
unknown
plain_text
a year ago
4.4 kB
28
Indexable
The error "signal 13 received but handler not on signal stack" combined with "non-Go code set up signal handler without SA_ONSTACK flag" indicates that IBM MQ's C library is setting up signal handlers in a way that conflicts with Go's runtime expectations. Setting MQS_NO_SYNC_SIGNAL_HANDLING=true doesn't seem to fully address the issue.

To handle this situation, you might need to combine several approaches to ensure that your Go application sets up its own signal handlers and that these handlers are not overridden by IBM MQ's handlers. Here’s an approach that involves both setting the environment variable and using cgo to handle the signals properly:

Create a separate C file to set up the signal handler:
Create a file sigsegv_handler.c:

c
Copiar código
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define STACK_SIZE (64 * 1024)
static char sigstack[STACK_SIZE];

void sigsegv_handler(int sig, siginfo_t *info, void *context) {
    printf("Received signal: %d\n", sig);
    exit(1);
}

__attribute__((constructor))
void setup_sigsegv_handler() {
    stack_t ss = {
        .ss_sp = sigstack,
        .ss_size = STACK_SIZE,
        .ss_flags = 0,
    };

    if (sigaltstack(&ss, NULL) == -1) {
        perror("sigaltstack");
        exit(1);
    }

    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
    sa.sa_sigaction = sigsegv_handler;

    if (sigaction(SIGSEGV, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }

    if (sigaction(SIGPIPE, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }
}
This C code sets up signal handlers for both SIGSEGV and SIGPIPE using an alternative signal stack.

Create a Go file that includes the C code:
Create a file main.go:

go
Copiar código
package main

/*
#cgo CFLAGS: -Wall
#cgo LDFLAGS: -Wall
#include "sigsegv_handler.c"
*/
import "C"

import (
    "fmt"
    "os"
    "github.com/ibm-messaging/mq-golang/v5/ibmmq"
)

func main() {
    // Set the environment variable to disable MQ's signal handling
    os.Setenv("MQS_NO_SYNC_SIGNAL_HANDLING", "true")

    // Connect to IBM MQ
    queueManager := "QM1"
    queueName := "DEV.QUEUE.1"
    connName := "localhost(1414)"
    channel := "DEV.APP.SVRCONN"
    user := "app"
    password := "password"

    cno := ibmmq.NewMQCNO()
    cno.Options = ibmmq.MQCNO_CLIENT_BINDING

    cd := ibmmq.NewMQCD()
    cd.ChannelName = channel
    cd.ConnectionName = connName
    cno.ClientConn = cd

    sco := ibmmq.NewMQSCO()
    cno.SecurityParms = sco
    sco.UserId = user
    sco.Password = password

    qMgr, err := ibmmq.Connx(queueManager, cno)
    if err != nil {
        fmt.Println("Error connecting to queue manager:", err)
        os.Exit(1)
    }
    defer qMgr.Disc()

    od := ibmmq.NewMQOD()
    od.ObjectName = queueName
    openOptions := ibmmq.MQOO_OUTPUT
    queue, err := qMgr.Open(od, openOptions)
    if err != nil {
        fmt.Println("Error opening queue:", err)
        os.Exit(1)
    }
    defer queue.Close(0)

    msg := ibmmq.NewMQMD()
    pmo := ibmmq.NewMQPMO()
    pmo.Options = ibmmq.MQPMO_NO_SYNCPOINT

    message := "Hello, IBM MQ!"
    buf := []byte(message)

    err = queue.Put(msg, pmo, buf)
    if err != nil {
        fmt.Println("Error putting message on queue:", err)
        os.Exit(1)
    }

    fmt.Println("Message sent to queue successfully")

    // Keep the application running
    select {}
}
Explanation
C Code (sigsegv_handler.c):

Sets up an alternative signal stack using sigaltstack.
Configures signal handlers for both SIGSEGV and SIGPIPE to use the alternative stack.
Go Code (main.go):

Includes the C code using cgo.
Sets the environment variable to disable some of IBM MQ's signal handling.
Establishes a connection to IBM MQ, opens a queue, and sends a message.
Building and Running
Ensure you have both files (sigsegv_handler.c and main.go) in the same directory. Then, build and run the Go application:

bash
Copiar código
go build -o myapp main.go
./myapp
This setup ensures that the signal handlers using SA_ONSTACK are established before the IBM MQ library initializes, avoiding the conflict that causes the "non-Go code set up signal handler without SA_ONSTACK flag" error. If you continue to experience issues, further debugging or consulting IBM MQ documentation/support might be necessary to identify any additional signal handling conflicts.
Editor is loading...
Leave a Comment