Segmentation fault mit POSIX-Threads + Die Zweite

Post Reply
Message
Author
User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

Segmentation fault mit POSIX-Threads + Die Zweite

#1 Post by Lateralus »

Ich habe ein kleines Problem mit POSIX-Threads:

Code: Select all

/* max_threads.c
 * testet, wie viele threads ein prozess erzeugen kann.
 */

#include <stdio.h>
#include <pthread.h>

void *do_nothing&#40;void *arg&#41;&#123;
        while&#40;1&#41;
                ;
&#125;

int main&#40;&#41;&#123;
        int i=0;
        while&#40; pthread_create&#40;NULL, NULL, do_nothing, NULL&#41; &#41;
                i++;

        printf&#40;"Das Programm konnte %d threads erzeugen.", i&#41;;
        pthread_exit&#40;NULL&#41;;
&#125;

Code: Select all

$ gcc -pthread -Wall -ggdb max_threads.c  
$ ./a.out
segmentation fault
Warum der segfault?

Der gdb sagt dazu:

Code: Select all

GNU gdb 6.0
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

&#40;gdb&#41; run
Starting program&#58; /home/maik/programming/c/simplescan/a.out 
warning&#58; Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
&#91;Thread debugging using libthread_db enabled&#93;
&#91;New Thread 16384 &#40;LWP 7863&#41;&#93;
&#91;New Thread 32769 &#40;LWP 7866&#41;&#93;
&#91;New Thread 16386 &#40;LWP 7867&#41;&#93;

Program received signal SIGSEGV, Segmentation fault.
&#91;Switching to Thread 16384 &#40;LWP 7863&#41;&#93;
0x40037394 in pthread_create@@GLIBC_2.1 &#40;&#41; from /lib/libpthread.so.0
Statisch gelinkt sieht das so aus:

Code: Select all

$ gcc -static -pthread -Wall -ggdb max_threads.c
$ ./a.out 
Segmentation fault
$ gdb a.out 
GNU gdb 6.0
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

&#40;gdb&#41; run
Starting program&#58; /home/maik/programming/c/simplescan/a.out 

Program received signal SIG32, Real-time event 32.
0x0804ab0f in __pthread_sigsuspend &#40;&#41;
&#40;gdb&#41; 
Last edited by Lateralus on 06. May 2005 18:39, edited 2 times in total.

User avatar
hjb
Pro-Linux
Posts: 3264
Joined: 15. Aug 1999 16:59
Location: Bruchsal
Contact:

#2 Post by hjb »

Hi!

Ich schätze mal, daß das erste Argument nicht NULL sein darf, da darin ein Thread-Handle zurückgegeben wird. Außerdem liefert die Funktion im Erfolgsfall 0, du mußt also ein ! vor die Funktion setzen.

Gruß,
hjb
Pro-Linux - warum durch Fenster steigen, wenn es eine Tür gibt?

User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

#3 Post by Lateralus »

@hjb: Vielen Dank.

Das hier tut den Job. Ich habe noch das aktive Warten in passives geformt.

Code: Select all

/* max_threads.c
 * testet, wie viele threads ein prozess erzeugen kann.
 */

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define TIME_TO_SLEEP 600

void *do_nothing&#40;void *arg&#41;&#123;
        while&#40;1&#41;
                sleep&#40;TIME_TO_SLEEP&#41;;
&#125;

int main&#40;&#41;&#123;
        pthread_t t;
        int i=0;
        while&#40; ! pthread_create&#40;&t, NULL, do_nothing, NULL&#41; &#41;
                i++;

        printf&#40;"Das Programm konnte %d Threads erzeugen.\n", i&#41;;
        return 0;
&#125;


prospero_0

#4 Post by prospero_0 »

das 1. argument darf nicht NULL sein, sondern ein pointer auf ein pthread_t.

siehe auch:
http://www.yolinux.com/TUTORIALS/LinuxT ... reads.html

gruss prospero

User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

#5 Post by Lateralus »

OK, zweites Problem:

Ich habe ein Programm, das so aussieht:

Code: Select all

#include <stdio.h>
#include <pthread.h>

#define THREAD_ANZ 3

struct xyz&#123;
	pthread_t *a_threads;
	pthread_t *b_threads;
&#125;;

void *func_b&#40;void *arg&#41;&#123;
	int i;
	struct xyz *my_xyz = &#40;struct xyz *&#41; arg;

	pthread_t myself = pthread_self&#40;&#41;;

	for&#40;i=0; i < THREAD_ANZ; i++&#41;&#123;
		if&#40; pthread_equal&#40;myself, my_xyz->b_threads&#91;i&#93;&#41; &#41;
			fprintf&#40;stderr, "Ich bin Nummer %d in b_threads", i&#41;;
	&#125;

	pthread_exit&#40;NULL&#41;;
&#125;

void *func_a&#40;void *arg&#41;&#123;
	int i;
	struct xyz *my_xyz = &#40;struct xyz *&#41; arg;

	for&#40;i=0; i < THREAD_ANZ; i++&#41;
		pthread_create&#40;&my_xyz->b_threads&#91;i&#93;, NULL, func_b, &#40;void *&#41; &my_xyz&#41;;

	pthread_exit&#40;NULL&#41;;
&#125;

int main&#40;&#41;&#123;
	int i;

	struct xyz my_xyz;

	pthread_t threads_a&#91;THREAD_ANZ&#93;;
	pthread_t threads_b&#91;THREAD_ANZ&#93;;

	my_xyz.a_threads = threads_a;
	my_xyz.b_threads = threads_b;

	for&#40;i=0; i < THREAD_ANZ; i++&#41;
		pthread_create&#40;&my_xyz.a_threads&#91;i&#93;, NULL, func_a, &#40;void *&#41; &my_xyz&#41;;

	while&#40;1&#41;
		;

	return 0;
&#125;
Nach dem Kompilieren bekomme ich beim ausführen einen Segfault:

Code: Select all

$ gdb a.out 
GNU gdb 6.0
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

&#40;gdb&#41; run
Starting program&#58; a.out 
warning&#58; Unable to find dynamic linker breakpoint function.
GDB will be unable to debug shared library initializers
and track explicitly loaded dynamic code.
&#91;Thread debugging using libthread_db enabled&#93;
&#91;New Thread 16384 &#40;LWP 17285&#41;&#93;
&#91;New Thread 32769 &#40;LWP 17288&#41;&#93;
&#91;New Thread 16386 &#40;LWP 17289&#41;&#93;
&#91;New Thread 32771 &#40;LWP 17290&#41;&#93;
&#91;New Thread 49156 &#40;LWP 17291&#41;&#93;
&#91;New Thread 65541 &#40;LWP 17292&#41;&#93;
&#91;New Thread 81926 &#40;LWP 17293&#41;&#93;
&#91;New Thread 98311 &#40;LWP 17294&#41;&#93;

Program received signal SIGSEGV, Segmentation fault.
&#91;Switching to Thread 65541 &#40;LWP 17292&#41;&#93;
0x08048537 in func_b &#40;arg=0xbf7ffac4&#41; at pthread_segfault.c&#58;18
18                      if&#40; pthread_equal&#40;myself, my_xyz->b_threads&#91;i&#93;&#41; &#41;

Warum passiert das?

User avatar
hjb
Pro-Linux
Posts: 3264
Joined: 15. Aug 1999 16:59
Location: Bruchsal
Contact:

#6 Post by hjb »

Hi!

Ich habe dein Programm kurz durch den Debugger gequetscht, aber ich sehe zunächst die Ursache auch nicht.

Wenn ich das recht sehe, erzeugst du zuerst 3 Threads, die func_a ausführen. Jeder von diesen erzeugt 3 Threads, die func_b ausführen. Diese teilen sich aber die 3 Thread-Handles in b_threads. Ob das den Crash verursacht, weiß ich nicht, aber es wäre möglich.

Gruß,
hjb
Pro-Linux - warum durch Fenster steigen, wenn es eine Tür gibt?

squeez
Posts: 9
Joined: 24. Jun 2004 17:05
Location: CH
Contact:

#7 Post by squeez »

tach

Der Segmentation Fault wird hier ausgeloest:
0x08048537 in func_b (arg=0xbf7ffac4) at pthread_segfault.c:18
func_a() Zeile:

Code: Select all

pthread_create&#40;&my_xyz->b_threads&#91;i&#93;, NULL, func_b, &#40;void *&#41;&my_xyz&#41;;
nach

Code: Select all

pthread_create&#40;&my_xyz->b_threads&#91;i&#93;, NULL, func_b, &#40;void *&#41;my_xyz&#41;;
ersetzen.

my_xyz ist ein Zeiger, also enthaelt es bereits die Adresse.

greetz by
squeez
[nothing]

User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

#8 Post by Lateralus »

Vielen Dank!

Post Reply