Frage

ich einen seltsamen Fehler in meinem Programm haben, scheint es mir, dass malloc () ist eine SIGSEGV verursacht, die so weit wie mein Verständnis geht keinen Sinn nicht. Ich verwende eine Bibliothek namens simclist für dynamische Listen.

Hier ist eine Struktur, die später Bezug genommen wird:

typedef struct {
    int msgid;
    int status;
    void* udata;
    list_t queue;
} msg_t;

Und hier ist der Code:

msg_t* msg = (msg_t*) malloc( sizeof( msg_t ) );

msg->msgid = msgid;
msg->status = MSG_STAT_NEW;
msg->udata = udata;
list_init( &msg->queue );

list_init ist, wo das Programm fehlschlägt, hier ist der Code für list_init:

/* list initialization */
int list_init(list_t *restrict l) {
    if (l == NULL) return -1;

    srandom((unsigned long)time(NULL));

    l->numels = 0;

    /* head/tail sentinels and mid pointer */
    l->head_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
    l->tail_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
    l->head_sentinel->next = l->tail_sentinel;
    l->tail_sentinel->prev = l->head_sentinel;
    l->head_sentinel->prev = l->tail_sentinel->next = l->mid = NULL;
    l->head_sentinel->data = l->tail_sentinel->data = NULL;

    /* iteration attributes */
    l->iter_active = 0;
    l->iter_pos = 0;
    l->iter_curentry = NULL;

    /* free-list attributes */
    l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *));
    l->spareelsnum = 0;

#ifdef SIMCLIST_WITH_THREADS
    l->threadcount = 0;
#endif

    list_attributes_setdefaults(l);

    assert(list_repOk(l));
    assert(list_attrOk(l));

    return 0;
}

die Linie l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * ist, wo die SIGSEGV nach dem Stack-Trace verursacht wird. Ich bin mit GDB / Nemiver für das Debuggen aber bin ratlos. Das erste Mal, diese Funktion aufgerufen wird es funktioniert gut, aber es nicht immer zum zweiten Mal. Wie kann malloc () verursachen eine SIGSEGV?

Dies ist der Stack-Trace:

#0  ?? () at :0
#1  malloc () at :0
#2  list_init (l=0x104f290) at src/simclist.c:205
#3  msg_new (msg_switch=0x1050dc0, msgid=8, udata=0x0) at src/msg_switch.c:218
#4  exread (sockfd=8, conn_info=0x104e0e0) at src/zimr-proxy/main.c:504
#5  zfd_select (tv_sec=0) at src/zfildes.c:124
#6  main (argc=3, argv=0x7fffcabe44f8) at src/zimr-proxy/main.c:210

Jede Hilfe oder Einsicht wird sehr geschätzt!

War es hilfreich?

Lösung

malloc kann zum Beispiel segfault wenn der Heap beschädigt ist. Überprüfen Sie, ob Sie nicht schreiben, etwas über die Grenzen einer früheren Zuordnung.

Andere Tipps

Wahrscheinlich tritt Speicherverletzung in einem anderen Teil des Codes. Wenn Sie auf Linux sind, sollten Sie auf jeden Fall valgrind versuchen. Ich würde nie meine eigene C-Programme vertrauen, wenn es valgrind geht.

EDIT: ein weiteres nützliches Tool Elektrozaun ist. Glibc liefert auch die MALLOC_CHECK_ Umgebungsvariable Debug-Speicherprobleme zu helfen. Diese beiden Methoden haben keinen Einfluss auf Geschwindigkeit läuft so viel wie valgrind.

Sie haben wahrscheinlich Sie vor diesem Aufruf durch einen Pufferüberlauf Haufen irgendwo beschädigt oder durch free mit einem Zeiger aufrufen, die nicht durch malloc zugewiesen wurde (oder das wurde bereits freigegeben).

Wenn die internen Datenstrukturen von malloc verwendeten diese Weise werden beschädigt, malloc ungültige Daten verwendet, und möglicherweise zum Absturz bringen.

Es gibt unzählige Möglichkeiten der Auslösung eines Core Dump von malloc() (und realloc() und calloc()). Dazu gehören:

  • Pufferüberlauf. Über das Ende des zugewiesenen Speicherplatz zu schreiben (Steuerinformationen Trampel, dass malloc() es wurde zu halten)
  • Pufferunterlauf:. Schreiben vor Beginn des zugewiesenen Raum (Steuerinformationen Trampeln, dass malloc() es wurde zu halten)
  • Befreit Speicher, der nicht von malloc() zugeordnet wurde. In einem gemischten C und C ++ Programm, das würde zu befreien Speicher in C ++ zugewiesen durch new.
  • Freigeben eines Zeigers, der von malloc() zugeordnet teilweise durch einen Speicherblock Punkte -., Die ein Sonderfall der vorherigen Fall ist
  • Befreit einen Zeiger, der bereits freigegeben wurde -. Die berüchtigte 'Double Free'

Mit einer Diagnoseversion von malloc() oder ermöglicht Diagnose in der Standardversion Ihres Systems helfen, einige dieser Probleme identifizieren können. Zum Beispiel kann es in der Lage sein, kleine Unterschreitungen und überläuft zu erkennen (weil sie mehr Platz reserviert eine Puffer-Zone um den Raum zur Verfügung zu stellen, die Sie angefordert), und es kann wohl versucht, freie Speicher erkennen, die nicht zugewiesen wurden oder dass bereits befreit oder Zeiger teilweise durch den Raum zugeordnet - weil es die Informationen separat von dem zugewiesenen Speicherplatz speichern. Die Kosten sind, dass die Debugging-Version mehr Platz in Anspruch nimmt. Ein wirklich gutes allocator in der Lage, die Stack-Trace und Zeilennummern notieren, die Ihnen sagen, wo die Zuordnung in Ihrem Code aufgetreten ist, oder wo das erste freie aufgetreten.

Sie sollten versuchen, diesen Code zu debuggen, in Isolation, um zu sehen, ob das Problem tatsächlich befindet, wo die segfault erzeugt wird. (Ich vermute, dass es nicht ist).

Das bedeutet:

# 1:. Kompilieren Sie den Code mit -O0, um sicherzustellen, dass gdb korrekte Zeilennummerierung Informationen erhält

# 2: Schreiben Sie einen Komponententest, die diesen Teil des Codes ruft

.

Meine Vermutung ist, dass der Code korrekt funktionieren, wenn sie getrennt verwendet. Anschließend können Sie Ihre andere Module in der gleichen Art und Weise testen, bis Sie herausfinden, was den Fehler verursacht.

Mit Valgrind, wie andere vorgeschlagen haben, ist auch eine sehr gute Idee.

Der Code ist problematisch. Wenn malloc NULL zurückgibt, wird dieser Fall nicht richtig in Ihrem Code behandelt. Sie nehmen einfach an, dass der Speicher für Sie zugewiesen wurde, wenn es tatsächlich nicht gewesen. Dies kann Speicherfehler verursachen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top