Thread related panic caused by userland process when compiling without -pthread

Stefan Walter sw at gegenunendlich.de
Mon Apr 26 10:57:21 PDT 2004


Hi,

when playing with devel/boost last week, I accidently forgot to add the
-pthread parameter to the g++ call for a couple of small test programs.
The (reproducable) results were:

- [1] crashes with signal 11 on execution if devel/boost was built
  without WITH_DEBUG.
- [1] crashes on execution with the following output if devel/boost was
  built with WITH_DEBUG:
***
count = 1
Assertion failed: (res == 0), function do_wait, file /usr/obj-ports/usr/ports/devel/boost/work/boost_1_31_0/libs/thread/src/condition.cpp, line 371.
***
  The output of a backtrace is attached.
- The attached program 'boostthreads.cpp' causes a panic (with and
  without WITH_DEBUG for devel/boost).

The only option used/not used for building the Boost library is
WITH_DEBUG, everything else was left at the default values.

The results are 100% reproducable on two machines, both running -CURRENT
as of April 6th. The output of a gdb session after the panic, run via

gdb -k /sys/i386/compile/KYUZO/kernel.debug /usr/crashdumps/vmcore.0

is attached as well. (I definitely used the (matching) debug kernel, but
most symbols aren't in the backtrace - why is that?)

Note that the crashes/panics only happen when omitting the -pthread
parameter.

Stefan

[1]: http://www.boost.org/libs/thread/example/thread_group.cpp
-------------- next part --------------
/* A simple test for threads */

#include <boost/thread/thread.hpp>
#include <boost/thread/xtime.hpp>
#include <iostream>
#include <string>

struct thread_action {
	int delay;
	std::string message;
	thread_action(int delay_secs, std::string msg)
		: delay(delay_secs), message(msg) {}
	void operator()() {
		boost::xtime xt;
		boost::xtime_get(&xt, boost::TIME_UTC);
		xt.sec += delay;
		boost::thread::sleep(xt);
		std::cout << message << std::endl;
	}
};

int main(int argc, char* argv[]) {
	std::cout << "Starting up new threads..." << std::endl;
	boost::thread t1(thread_action(1, "Message 1"));
	t1.join();
	boost::thread_group ts;
	for(int i = 0; i < 10; i++)
		ts.create_thread(thread_action(i, "Message"));
	ts.join_all();
}
-------------- next part --------------
Script started on Thu Apr 22 20:00:18 2004
GNU gdb 5.2.1 (FreeBSD)
Copyright 2002 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 "i386-undermydesk-freebsd"...(no debugging symbols found)...
Core was generated by `thread_group'.
Program terminated with signal 6, Aborted.
Reading symbols from /usr/local/lib/libboost_thread.so...done.
Loaded symbols for /usr/local/lib/libboost_thread.so
Reading symbols from /usr/lib/libstdc++.so.4...done.
Loaded symbols for /usr/lib/libstdc++.so.4
Reading symbols from /lib/libm.so.2...done.
Loaded symbols for /lib/libm.so.2
Reading symbols from /lib/libc.so.5...done.
Loaded symbols for /lib/libc.so.5
Reading symbols from /usr/lib/libpthread.so.1...done.
Loaded symbols for /usr/lib/libpthread.so.1
Reading symbols from /libexec/ld-elf.so.1...done.
Loaded symbols for /libexec/ld-elf.so.1
#0  0x2822d41f in pthread_testcancel () from /usr/lib/libpthread.so.1
(gdb) bt
#0  0x2822d41f in pthread_testcancel () from /usr/lib/libpthread.so.1
#1  0x2822e307 in __error () from /usr/lib/libpthread.so.1
#2  0x2821d3dd in pthread_sigmask () from /usr/lib/libpthread.so.1
#3  0x2818bd0c in pthread_sigmask () from /lib/libc.so.5
#4  0x2821d2da in sigprocmask () from /usr/lib/libpthread.so.1
#5  0x281ee066 in abort () from /lib/libc.so.5
#6  0x281cbffb in __assert () from /lib/libc.so.5
#7  0x2807762c in boost::detail::condition_impl::do_wait(pthread_mutex**) (
    this=0xbfbfe9c8, pmutex=0xbfbfe9c0)
    at /usr/obj-ports/usr/ports/devel/boost/work/boost_1_31_0/libs/thread/src/condition.cpp:371
#8  0x2807af3f in do_wait<boost::mutex> (this=0xbfbfe9c4, mutex=@0xbfbfe9c0)
    at /usr/obj-ports/usr/ports/devel/boost/work/boost_1_31_0/boost/thread/condition.hpp:153
#9  0x2807addd in wait<boost::detail::thread::scoped_lock<boost::mutex> > (
    this=0xbfbfe9c4, lock=@0xbfbfe980)
    at /usr/obj-ports/usr/ports/devel/boost/work/boost_1_31_0/boost/thread/condition.hpp:96
#10 0x2807aa16 in (anonymous namespace)::thread_param::wait() (this=0xbfbfe9c0)
    at /usr/obj-ports/usr/ports/devel/boost/work/boost_1_31_0/libs/thread/src/thread.cpp:43
#11 0x280799b4 in thread (this=0x804d170, threadfunc=@0xbfbfea68)
    at /usr/obj-ports/usr/ports/devel/boost/work/boost_1_31_0/libs/thread/src/thread.cpp:139
#12 0x28079f36 in boost::thread_group::create_thread(boost::function0<void, std::allocator<boost::function_base> > const&) (this=0xbfbfea88, threadfunc=@0xbfbfea68)
    at /usr/obj-ports/usr/ports/devel/boost/work/boost_1_31_0/libs/thread/src/thread.cpp:282
#13 0x080491b5 in main ()
#14 0x08049022 in _start ()
(gdb) q

Script done on Thu Apr 22 20:00:20 2004
-------------- next part --------------
Script started on Thu Apr 22 19:54:08 2004
GNU gdb 5.2.1 (FreeBSD)
Copyright 2002 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 "i386-undermydesk-freebsd"...
panic: page fault
panic messages:
---
Fatal trap 12: page fault while in kernel mode
fault virtual address	= 0x40
fault code		= supervisor read, page not present
instruction pointer	= 0x8:0xc04c77f7
stack pointer	        = 0x10:0xe1a06a68
frame pointer	        = 0x10:0xe1a06a90
code segment		= base 0x0, limit 0xfffff, type 0x1b
			= DPL 0, pres 1, def32 1, gran 1
processor eflags	= interrupt enabled, resume, IOPL = 0
current process		= 1038 (boostthreads)
trap number		= 12
panic: page fault
at line 815 in file ../../../i386/i386/trap.c

syncing disks, buffers remaining... 3547 3547 3546 3546 3544 3544 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 3543 
giving up on 2496 buffers
Uptime: 16m44s
Dumping 511 MB
 16 32 48 64 80 96 112 128 144 160 176 192 208 224 240 256 272 288 304 320 336 352 368 384 400 416 432 448 464 480 496
---
Reading symbols from /boot/kernel/miibus.ko...done.
Loaded symbols for /boot/kernel/miibus.ko
Reading symbols from /boot/kernel/if_xl.ko...done.
Loaded symbols for /boot/kernel/if_xl.ko
Reading symbols from /boot/kernel/snd_pcm.ko...done.
Loaded symbols for /boot/kernel/snd_pcm.ko
Reading symbols from /boot/kernel/snd_cmi.ko...done.
Loaded symbols for /boot/kernel/snd_cmi.ko
Reading symbols from /usr/src/sys/i386/compile/KYUZO/modules/usr/src/sys/modules/ugen/ugen.ko.debug...done.
Loaded symbols for /usr/src/sys/i386/compile/KYUZO/modules/usr/src/sys/modules/ugen/ugen.ko.debug
Reading symbols from /usr/src/sys/i386/compile/KYUZO/modules/usr/src/sys/modules/umass/umass.ko.debug...done.
Loaded symbols for /usr/src/sys/i386/compile/KYUZO/modules/usr/src/sys/modules/umass/umass.ko.debug
Reading symbols from /usr/src/sys/i386/compile/KYUZO/modules/usr/src/sys/modules/agp/agp.ko.debug...done.
Loaded symbols for /usr/src/sys/i386/compile/KYUZO/modules/usr/src/sys/modules/agp/agp.ko.debug
Reading symbols from /boot/kernel/geom_bde.ko...done.
Loaded symbols for /boot/kernel/geom_bde.ko
Reading symbols from /boot/kernel/acpi.ko...done.
Loaded symbols for /boot/kernel/acpi.ko
Reading symbols from /boot/kernel/blank_saver.ko...done.
Loaded symbols for /boot/kernel/blank_saver.ko
#0  doadump () at ../../../kern/kern_shutdown.c:236
236		dumping++;
(kgdb) bt
#0  doadump () at ../../../kern/kern_shutdown.c:236
#1  0xc04e66e1 in ?? ()
#2  0xc04e697c in ?? ()
#3  0xc064474e in ?? ()
#4  0xc06444a7 in ?? ()
#5  0xc0644169 in ?? ()
#6  0xc0638ea8 in ?? ()
#7  0xc04c74c6 in ?? ()
#8  0xc04eab09 in ?? ()
#9  0xc04ea377 in ?? ()
#10 0xc04efca8 in ?? ()
#11 0xc06449d7 in ?? ()
#12 0xc0638efd in ?? ()
---Can't read userspace from dump, or kernel process---

(kgdb) l
231	static void
232	doadump(void)
233	{
234	
235		savectx(&dumppcb);
236		dumping++;
237		dumpsys(&dumper);
238	}
239	
240	/*
(kgdb) up 1
#1  0xc04e66e1 in ?? ()
(kgdb) l
241	 *  Go through the rigmarole of shutting down..
242	 * this used to be in machdep.c but I'll be dammned if I could see
243	 * anything machine dependant in it.
244	 */
245	static void
246	boot(int howto)
247	{
248	
249		/* collect extra flags that shutdown_nice might have set */
250		howto |= shutdown_howto;
(kgdb) up 1
#2  0xc04e697c in ?? ()
(kgdb) l
251	
252	#ifdef DDB
253		/* We are out of the debugger now. */
254		db_active = 0;
255	#endif
256	
257	#ifdef SMP
258		if (smp_active)
259			printf("boot() called on cpu#%d\n", PCPU_GET(cpuid));
260	#endif
(kgdb) up 1
#3  0xc064474e in ?? ()
(kgdb) l
261		/*
262		 * Do any callouts that should be done BEFORE syncing the filesystems.
263		 */
264		EVENTHANDLER_INVOKE(shutdown_pre_sync, howto);
265	
266		/* 
267		 * Now sync filesystems
268		 */
269		if (!cold && (howto & RB_NOSYNC) == 0 && waittime < 0) {
270			register struct buf *bp;
(kgdb) up 1
#4  0xc06444a7 in ?? ()
(kgdb) l
271			int iter, nbusy, pbusy;
272			int subiter;
273	
274			waittime = 0;
275			printf("\nsyncing disks, buffers remaining... ");
276	
277			sync(&thread0, NULL);
278	
279			/*
280			 * With soft updates, some buffers that are
(kgdb) up 1
#5  0xc0644169 in ?? ()
(kgdb) l
281			 * written will be remarked as dirty until other
282			 * buffers are written.
283			 */
284			for (iter = pbusy = 0; iter < 20; iter++) {
285				nbusy = 0;
286				for (bp = &buf[nbuf]; --bp >= buf; ) {
287					if ((bp->b_flags & B_INVAL) == 0 &&
288					    BUF_REFCNT(bp) > 0) {
289						nbusy++;
290					} else if ((bp->b_flags & (B_DELWRI | B_INVAL))
(kgdb) up 1
#6  0xc0638ea8 in ?? ()
(kgdb) l
291							== B_DELWRI) {
292						/* bawrite(bp);*/
293						nbusy++;
294					}
295				}
296				if (nbusy == 0)
297					break;
298				printf("%d ", nbusy);
299				if (nbusy < pbusy)
300					iter = 0;
(kgdb) up 1
#7  0xc04c74c6 in ?? ()
(kgdb) l
301				pbusy = nbusy;
302				sync(&thread0, NULL);
303	 			if (curthread != NULL) {
304					DROP_GIANT();
305	   				for (subiter = 0; subiter < 50 * iter; subiter++) {
306	     					mtx_lock_spin(&sched_lock);
307						/*
308						 * Allow interrupt threads to run
309						 */
310	     					mi_switch(SW_VOL);
(kgdb) up 1
#8  0xc04eab09 in ?? ()
(kgdb) l
311	     					mtx_unlock_spin(&sched_lock);
312	     					DELAY(1000);
313	   				}
314					PICKUP_GIANT();
315	 			} else
316				DELAY(50000 * iter);
317			}
318			printf("\n");
319			/*
320			 * Count only busy local buffers to prevent forcing 
(kgdb) up 1
#9  0xc04ea377 in ?? ()
(kgdb) l
321			 * a fsck if we're just a client of a wedged NFS server
322			 */
323			nbusy = 0;
324			for (bp = &buf[nbuf]; --bp >= buf; ) {
325				if (((bp->b_flags&B_INVAL) == 0 && BUF_REFCNT(bp)) ||
326				    ((bp->b_flags & (B_DELWRI|B_INVAL)) == B_DELWRI)) {
327					if (bp->b_dev == NODEV) {
328						TAILQ_REMOVE(&mountlist,
329						    bp->b_vp->v_mount, mnt_list);
330						continue;
(kgdb) up 1
#10 0xc04efca8 in ?? ()
(kgdb) l
331					}
332					nbusy++;
333	#if defined(SHOW_BUSYBUFS) || defined(DIAGNOSTIC)
334					printf(
335				    "%d: dev:%s, flags:%0x, blkno:%ld, lblkno:%ld\n",
336					    nbusy, devtoname(bp->b_dev),
337					    bp->b_flags, (long)bp->b_blkno,
338					    (long)bp->b_lblkno);
339	#endif
340				}
(kgdb) up 1
#11 0xc06449d7 in ?? ()
(kgdb) l
341			}
342			if (nbusy) {
343				/*
344				 * Failed to sync all blocks. Indicate this and don't
345				 * unmount filesystems (thus forcing an fsck on reboot).
346				 */
347				printf("giving up on %d buffers\n", nbusy);
348				DELAY(5000000);	/* 5 seconds */
349			} else {
350				printf("done\n");
(kgdb) up 1
#12 0xc0638efd in ?? ()
(kgdb) l
351				/*
352				 * Unmount filesystems
353				 */
354				if (panicstr == 0)
355					vfs_unmountall();
356			}
357			DELAY(100000);		/* wait for console output to finish */
358		}
359	
360		print_uptime();
(kgdb) up 1
---Can't read userspace from dump, or kernel process---

(kgdb) q

Script done on Thu Apr 22 19:56:24 2004
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 650 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-current/attachments/20040426/5df93d1b/attachment.bin


More information about the freebsd-current mailing list