Trouble with GDB/pthread_create/NC 6.2.1

Hello,

I’ve created a simple program that creates 2 threads and they loop through
outputing simple messages.

When I run the program it runs fine. When I try to debug it, pthread_create
fails with an error status 89.

Can anyone provide some guidence on what I’m doing wrong (or not doing
correctly)?

Thanks,
Jeff Blaalid

gcc -v -g -o main main.c

Reading specs from /usr/lib/gcc-lib/ntox86/2.95.3qnx-nto/specs
gcc version 2.95.3qnx-nto 20010315 (release)

/usr/lib/gcc-lib/ntox86/2.95.3qnx-nto/cpp0 -lang-c -v -D__GNUC__=2 -D__GNUC_
MIN
OR__=95 -D__X86__ -Di386 -Dunix -D__QNXNTO__ -D__QNX__ -D__LITTLEENDIAN__ -D
X8
6
-D__i386__ -D__unix__ -D__QNXNTO__ -D__QNX__ -D__LITTLEENDIAN__ -D__i386
-D_
unix -Asystem(unix) -Asystem(nto) -Asystem(qnxnto) -Asystem(qnx) -Acpu(i386
) -A
machine(i386) -g -idirafter
/usr/include -Acpu(i386) -Amachine(i386) -Di386 -D
_
i386 -D__i386__ main.c /tmp/cc6RpXUH.i
GNU CPP version 2.95.3qnx-nto 20010315 (release) (QNX/Neutrino)
#include “…” search starts here:
#include <…> search starts here:
/usr/lib/gcc-lib/ntox86/2.95.3qnx-nto/include
/usr/lib/gcc-lib/ntox86/2.95.3qnx-nto/…/…/…/…/ntox86/include
/usr/include
End of search list.
The following default directories have been omitted from the search path:
/usr/lib/gcc-lib/ntox86/2.95.3qnx-nto/…/…/…/…/include/g+±3
/usr/lib/gcc-lib/ntox86/2.95.3qnx-nto/…/…/…/…/ntox86/sys-include
End of omitted list.
/usr/lib/gcc-lib/ntox86/2.95.3qnx-nto/cc1 /tmp/cc6RpXUH.i -quiet -dumpbase
main
…c -g -version -o /tmp/ccGeONfp.s
GNU C version 2.95.3qnx-nto 20010315 (release) (ntox86) compiled by GNU C
versio
n 2.95.2 19991024 (release).
/usr/bin/ntox86-as -V -Qy -o /tmp/ccDY2RxH.o /tmp/ccGeONfp.s
GNU assembler version 2.10.1qnx-nto (ntox86) using BFD version 2.10.1qnx-nto
/usr/lib/gcc-lib/ntox86/2.95.3qnx-nto/collect2 -V -Y P,/x86/lib -L
/x86/lib -L
/x86/usr/lib -Qy -m i386nto --dynamic-linker /usr/lib/ldqnx.so.2 -o main
/x86/li
b/crt1.o /x86/lib/crti.o
/x86/lib/crtbegin.o -L/usr/lib/gcc-lib/ntox86/2.95.3qnx
-nto /tmp/ccDY2RxH.o -lgcc -lc -dn -Bstatic -lc -lgcc /x86/lib/crtend.o
/x86/lib
/crtn.o
GNU ld version 2.10.1qnx-nto (with BFD 2.10.1qnx-nto)
Supported emulations:
i386nto
armnto
elf32bmipnto
elf32lmipnto
elf32ppcnto
shlelf_nto
shelf_nto

./main

thread1 now running
thread2 now running
thread2 now running

gdb ./main

GNU gdb 5.2.1qnx-326 QNX Neutrino 6.2.1
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 “ntox86”…
(gdb) r
Starting program: /fnet/QNX/draft1/main
(gdb) b K_newprc
Breakpoint 1 at 0x8048556: file main.c, line 34.
(gdb) c
Continuing.

Breakpoint 1, K_newprc (name=0x80486c9 “Thread1”, entry=0x80484f0 ,
params=0x0) at main.c:34
34 if(sts = pthread_create(&tid, NULL, entry, params))
(gdb) s
36 perror(“pthread_create”);
(gdb) print sts
$1 = 89
(gdb) print tid
$2 = 8
(gdb) print errno
$3 = 0
(gdb) c
Continuing.
pthread_create: No error

Program exited normally.
(gdb) q





kernel.h
/* kernel.h - Publi kernel interface definitions
*/

#ifndef KERNEL_DOT_H
#define KERNEL_DOT_H


#include “compiler.h”
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <sys/queue.h>
#include <sys/neutrino.h>



/***************************************************************************
**
Definitions for various Queue List Headers


*/

/* Generic List header definition for a simple queue structure

  • (doubly-linked list)
    */
    typedef struct _QUEUE
    {
    struct _QUEUE *flink;
    struct _QUEUE blink;
    } QUEUE;


    /
    Process Control Block (PCB) definition
    */
    typedef struct _PCB_t
    {
    struct _PCB_t *flink;
    struct _PCB_t blink;
    u32 priori;
    u16 pid;
    u16 inuse;
    char name [64]; /
    Null-terminated process name
    /
    U_BYTE PPrivate [64];/
    Process’s private storage area
    */
    } PCB_t;

PCB_t K_prctbl[256];

#define KI_INITQ(q) Ki_initq (q)
#define KI_INSQH(q,n) Ki_insqh (q, n)
#define KI_INSQT(q,n) Ki_insqt (q, n)
#define KI_REMQ(n) Ki_remq (n)
#define KI_REMQH(q,o) o = Ki_remqh (q)
#define KI_REMQT(q,o) o = Ki_remqt (q)





/***************************************************************************
**
Global Macros


*/
#define QPTR(L) ((QUEUE *) (L))
#define NEXT(L) (L) → flink
#define Next(L) (L).flink
#define PREV(L) (L) → blink
#define Prev(L) (L).blink
#define EMPTY(L) ((L) → flink == (L))
#define Empty(L) (QPTR((L).flink) == QPTR(&L))
#define NOTEMPTY(L) !EMPTY (L)
#define Notempty(L) !Empty (L)
#define PRIORITY(L) (((PCB_lh *) (L))->priori)

#define Ki_qempty(L) ( *((u32 *)(L)) == ((u32)(L)) )

#endif /* KERNEL_DOT_H */


main.c
#include “kernel.h”

void
thread1( void *not_used)
{
while(1)
{
printf(“thread1 now running\n”);
sleep (5);
}
}

void
thread2( void *not_used)
{
while(1)
{
printf(“thread2 now running\n”);
sleep (2);
}
}

#define NOT_FREE 1

PCB_t *
K_newprc (char *name, void (*entry) (void *), void *params)
{
u32 sts;
PCB_t *p;
pthread_t tid;

if(sts = pthread_create(&tid, NULL, entry, params))
{
perror(“pthread_create”);
exit(1);
}
if( tid >= 0 && tid < 256 )
{
p = &K_prctbl[tid];
strncpy (p->name, name, sizeof (p->name));
}

return (p);
}
/*

Function: main

Arguments: None

Returns: Nothing

Main() is invoked by the C startup module. It simply invokes the
Kernel’s initialization routine while providing it with pointers to
various handlers.

*/

int main (void)
{

K_newprc(“Thread1”, thread1, NULL );
K_newprc(“Thread2”, thread2, NULL );
sleep (500);
return (0); /* Yes … we actually do return */
}

Solved - Don’t try to Step into a Kernel function - use “next” instead of
“step”.