Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2007-06

How to analyze a core dump?

25 messages · 8 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Luca Olivetti

Hello,

I'm trying to debug a segment violation, I compiled the program with -g, but analyzing the core dump isn't really helpful, maybe the "warning can't read pathname for load map" is the cause? Or it's possible that it's caused by some of the c libraries used having no debug symbols? Any hint?
Here's my gdb session:

$ gdb ./botphone core.28682
GNU gdb 6.6-1mdv2007.1 (Mandriva Linux release 2007.1) Copyright (C) 2006 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 "i586-mandriva-linux-gnu"... Using host libthread_db library "/lib/i686/libthread_db.so.1".

warning: Can't read pathname for load map: Input/output error. Reading symbols from /usr/local/lib/liblinphone.so.1...done. Loaded symbols for /usr/local/lib/liblinphone.so.1 Reading symbols from /lib/libusb-0.1.so.4...done.
Loaded symbols for /lib/libusb-0.1.so.4
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/i686/libpthread.so.0...done. Loaded symbols for /lib/i686/libpthread.so.0
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /usr/local/lib/libquickstream.so.0...done. Loaded symbols for /usr/local/lib/libquickstream.so.0 Reading symbols from /usr/lib/libosip2.so.3...done. Loaded symbols for /usr/lib/libosip2.so.3
Reading symbols from /usr/lib/libosipparser2.so.3...done. Loaded symbols for /usr/lib/libosipparser2.so.3
Reading symbols from /lib/libnsl.so.1...done.
Loaded symbols for /lib/libnsl.so.1
Reading symbols from /lib/i686/librt.so.1...done.
Loaded symbols for /lib/i686/librt.so.1
Reading symbols from /lib/libintl.so.8...done.
Loaded symbols for /lib/libintl.so.8
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /usr/local/lib/libmediastreamer.so.0...done. Loaded symbols for /usr/local/lib/libmediastreamer.so.0 Reading symbols from /usr/local/lib/libortp.so.5...done. Loaded symbols for /usr/local/lib/libortp.so.5
Reading symbols from /usr/lib/libasound.so.2...done. Loaded symbols for /usr/lib/libasound.so.2
Reading symbols from /usr/lib/libspeex.so.1...done. Loaded symbols for /usr/lib/libspeex.so.1
Reading symbols from /lib/i686/libm.so.6...done.
Loaded symbols for /lib/i686/libm.so.6
Reading symbols from /lib/libnss_files.so.2...done. Loaded symbols for /lib/libnss_files.so.2
Reading symbols from /lib/libnss_nis.so.2...done.
Loaded symbols for /lib/libnss_nis.so.2
Reading symbols from /lib/libnss_dns.so.2...done.
Loaded symbols for /lib/libnss_dns.so.2
Reading symbols from /lib/libresolv.so.2...done.
Loaded symbols for /lib/libresolv.so.2
Reading symbols from /lib/libgcc_s.so.1...done.
Loaded symbols for /lib/libgcc_s.so.1
Core was generated by `./botphone -v -v -v -c /home/luca/.linphonerc -C /home/luca/agenda'.
Program terminated with signal 11, Segmentation fault. #0 0x080593ea in SYSTEM_GETERRNO$$LONGINT ()
(gdb) bt f
#0 0x080593ea in SYSTEM_GETERRNO$$LONGINT ()
No symbol table info available.
#1 0x08060442 in SYSTEM_REENABLE_SIGNAL$LONGINT$$BOOLEAN () No symbol table info available.
#2 0x08060580 in SYSTEM_SIGNALTORUNERROR$LONGINT$PSIGINFO$PUCONTEXT () No symbol table info available.
#3 0x08059bec in ?? ()
No symbol table info available.
#4 0x0000000b in ?? ()
No symbol table info available.
#5 0xb6b5412c in ?? ()
No symbol table info available.
#6 0xb6b541ac in ?? ()
No symbol table info available.
#7 0x0000000b in ?? ()
No symbol table info available.
#8 0x00000000 in ?? ()
No symbol table info available.
(gdb)

Bye

Luca

Reply by email

John Coppens
to Luca Olivetti
Show quoted text 5 lines
I'm trying to debug a segment violation, I compiled the program with -g, but analyzing the core dump isn't really helpful, maybe the "warning can't read pathname for load map" is the cause? Or it's possible that it's caused by some of the c libraries used having no debug symbols? Any hint?

I'm not too experienced in this, but I suspect a good first step would be to ask for a backtrace (bt) in gdb, after the segfault occured. You'll see the steps that led to the actual segfault, starting from the main program till the library function that failed. Don't immediately suspect the library - go back to the last line of your program and check if all things are normal at _that_ point.

AFAIK, core dumps are not really related with gdb, but are generated by the kernel, and should be the last step to fall back on. A backtrace in gdb is generally more helpful.

John

Reply by email

Luca Olivetti
to John Coppens

En/na John Coppens ha escrit:

Show quoted text 19 lines
On Sun, 10 Jun 2007 21:30:09 +0200 Luca Olivetti wrote: > I'm trying to debug a segment violation, I compiled the program with > -g, but analyzing the core dump isn't really helpful, maybe the > "warning can't read pathname for load map" is the cause? Or it's > possible that it's caused by some of the c libraries used having no > debug symbols? Any hint? I'm not too experienced in this, but I suspect a good first step would be to ask for a backtrace (bt) in gdb, after the segfault occured. You'll see the steps that led to the actual segfault, starting from the main program till the library function that failed. Don't immediately suspect the library - go back to the last line of your program and check if all things are normal at _that_ point. AFAIK, core dumps are not really related with gdb, but are generated by the kernel, and should be the last step to fall back on. A backtrace in gdb is generally more helpful.

I don't know gdb well, but it should be capable to show a backtrace using a core file (that's what I was trying to do). The program doesn't work if I run it under gdb (I don't know why, but I think it has problems with thread), that's why I was trying to use a core. Also it's impossible to debug the program using Lazarus (again, I think, due to threads, and, yes, I tried a separate X server as per the instructions in the wiki)

Bye

Luca

Reply by email

ik
to Luca Olivetti: I'm trying to debug a segment violation, I compiled the program with -g, but analyzing…

Hi,

Luca Olivetti wrote 11 lines
Hello, I'm trying to debug a segment violation, I compiled the program with -g, but analyzing the core dump isn't really helpful, maybe the "warning can't read pathname for load map" is the cause? Or it's possible that it's caused by some of the c libraries used having no debug symbols? Any hint? Here's my gdb session: $ gdb ./botphone core.28682

Try the following:

gdb -c botphone core.28682

inside gdb you can do things such as back-trace.

Show quoted text 84 lines
GNU gdb 6.6-1mdv2007.1 (Mandriva Linux release 2007.1) Copyright (C) 2006 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 "i586-mandriva-linux-gnu"... Using host libthread_db library "/lib/i686/libthread_db.so.1". warning: Can't read pathname for load map: Input/output error. Reading symbols from /usr/local/lib/liblinphone.so.1...done. Loaded symbols for /usr/local/lib/liblinphone.so.1 Reading symbols from /lib/libusb-0.1.so.4...done. Loaded symbols for /lib/libusb-0.1.so.4 Reading symbols from /lib/libdl.so.2...done. Loaded symbols for /lib/libdl.so.2 Reading symbols from /lib/i686/libpthread.so.0...done. Loaded symbols for /lib/i686/libpthread.so.0 Reading symbols from /lib/i686/libc.so.6...done. Loaded symbols for /lib/i686/libc.so.6 Reading symbols from /usr/local/lib/libquickstream.so.0...done. Loaded symbols for /usr/local/lib/libquickstream.so.0 Reading symbols from /usr/lib/libosip2.so.3...done. Loaded symbols for /usr/lib/libosip2.so.3 Reading symbols from /usr/lib/libosipparser2.so.3...done. Loaded symbols for /usr/lib/libosipparser2.so.3 Reading symbols from /lib/libnsl.so.1...done. Loaded symbols for /lib/libnsl.so.1 Reading symbols from /lib/i686/librt.so.1...done. Loaded symbols for /lib/i686/librt.so.1 Reading symbols from /lib/libintl.so.8...done. Loaded symbols for /lib/libintl.so.8 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 Reading symbols from /usr/local/lib/libmediastreamer.so.0...done. Loaded symbols for /usr/local/lib/libmediastreamer.so.0 Reading symbols from /usr/local/lib/libortp.so.5...done. Loaded symbols for /usr/local/lib/libortp.so.5 Reading symbols from /usr/lib/libasound.so.2...done. Loaded symbols for /usr/lib/libasound.so.2 Reading symbols from /usr/lib/libspeex.so.1...done. Loaded symbols for /usr/lib/libspeex.so.1 Reading symbols from /lib/i686/libm.so.6...done. Loaded symbols for /lib/i686/libm.so.6 Reading symbols from /lib/libnss_files.so.2...done. Loaded symbols for /lib/libnss_files.so.2 Reading symbols from /lib/libnss_nis.so.2...done. Loaded symbols for /lib/libnss_nis.so.2 Reading symbols from /lib/libnss_dns.so.2...done. Loaded symbols for /lib/libnss_dns.so.2 Reading symbols from /lib/libresolv.so.2...done. Loaded symbols for /lib/libresolv.so.2 Reading symbols from /lib/libgcc_s.so.1...done. Loaded symbols for /lib/libgcc_s.so.1 Core was generated by `./botphone -v -v -v -c /home/luca/.linphonerc -C /home/luca/agenda'. Program terminated with signal 11, Segmentation fault. #0 0x080593ea in SYSTEM_GETERRNO$$LONGINT () (gdb) bt f #0 0x080593ea in SYSTEM_GETERRNO$$LONGINT () No symbol table info available. #1 0x08060442 in SYSTEM_REENABLE_SIGNAL$LONGINT$$BOOLEAN () No symbol table info available. #2 0x08060580 in SYSTEM_SIGNALTORUNERROR$LONGINT$PSIGINFO$PUCONTEXT () No symbol table info available. #3 0x08059bec in ?? () No symbol table info available. #4 0x0000000b in ?? () No symbol table info available. #5 0xb6b5412c in ?? () No symbol table info available. #6 0xb6b541ac in ?? () No symbol table info available. #7 0x0000000b in ?? () No symbol table info available. #8 0x00000000 in ?? () No symbol table info available. (gdb) Bye -- Luca

Ido

Reply by email

Luca Olivetti
to ik

En/na ik ha escrit:

Show quoted text 18 lines
Hi, On 6/10/07, Luca Olivetti wrote: > Hello, > > I'm trying to debug a segment violation, I compiled the program with -g, > but analyzing the core dump isn't really helpful, maybe the "warning > can't read pathname for load map" is the cause? Or it's possible that > it's caused by some of the c libraries used having no debug symbols? Any > hint? > Here's my gdb session: > > > $ gdb ./botphone core.28682 Try the following: gdb -c botphone core.28682

Yes, that was the first incantation I tried, but it couldn't even resolve the name of the function where the sigsev happened (SYSTEM_GETERRNO$$LONGINT)

Bye

Luca

Reply by email

Luca Olivetti
to Luca Olivetti: I'm trying to debug a segment violation, I compiled the program with -g, but analyzing…

En/na Luca Olivetti ha escrit:

Show quoted text 11 lines
Hello, I'm trying to debug a segment violation, I compiled the program with -g, but analyzing the core dump isn't really helpful, maybe the "warning can't read pathname for load map" is the cause? Or it's possible that it's caused by some of the c libraries used having no debug symbols? Any hint? Here's my gdb session: $ gdb ./botphone core.28682

[...]

Show quoted text 24 lines
Core was generated by `./botphone -v -v -v -c /home/luca/.linphonerc -C /home/luca/agenda'. Program terminated with signal 11, Segmentation fault. #0 0x080593ea in SYSTEM_GETERRNO$$LONGINT () (gdb) bt f #0 0x080593ea in SYSTEM_GETERRNO$$LONGINT () No symbol table info available. #1 0x08060442 in SYSTEM_REENABLE_SIGNAL$LONGINT$$BOOLEAN () No symbol table info available. #2 0x08060580 in SYSTEM_SIGNALTORUNERROR$LONGINT$PSIGINFO$PUCONTEXT () No symbol table info available. #3 0x08059bec in ?? () No symbol table info available. #4 0x0000000b in ?? () No symbol table info available. #5 0xb6b5412c in ?? () No symbol table info available. #6 0xb6b541ac in ?? () No symbol table info available. #7 0x0000000b in ?? () No symbol table info available. #8 0x00000000 in ?? () No symbol table info available. (gdb)

No suggestions? Is there some special option (apart from -g) that I should specify to compile/link my program?

Bye

Luca

Reply by email

Jonas Maebe
to Luca Olivetti
Luca Olivetti wrote
No suggestions? Is there some special option (apart from -g) that I should specify to compile/link my program?

No. But the garbage backtrace means that either your gdb cannot parse the signal handler frame, or that your program corrupted the call stack.

Jonas

Reply by email

Luca Olivetti
to Jonas Maebe

En/na Jonas Maebe ha escrit:

Show quoted text 8 lines
On 14 jun 2007, at 19:04, Luca Olivetti wrote: > No suggestions? Is there some special option (apart from -g) that I > should specify to compile/link my program? No. But the garbage backtrace means that either your gdb cannot parse the signal handler frame, or that your program corrupted the call stack.

Well, I'm starting to get desperate, I cannot debug where the sigsev occurs, I put a bazillion writeln and still I cannot see where the problem is. I can reproduce the sigsev at will, only I cannot see where it happens. I suspect it's one of the threads in the c library (linphonecore, http://www.linphone.org) I'm using (since in all of my threads I put writeln in the critical places, as well as in all the callbacks from said library), alas there's no sigsev when the same library is driven by the c console program that comes with it (linphonec). At one point I though the problem was in CheckSynchronize (since the last writeln before the sigsev was right before calling it), but it was just a timing coincidence (I was calling it with 1000, then when I tried with 0 I saw the sigsev right in the middle of a debugging printf in the library).
Maybe it's not a good idea to mix c multithreaded libraries and pascal code? Any special unit I should use? (I already tried cmem and it made no difference).
If I cannot solve it I think I'll have to write a small backend program in c that communicates with pascal either through stdin/stdout redirection or with a socket.

Bye

Luca

Reply by email

Tom Walsh
to Luca Olivetti
Luca Olivetti wrote 32 lines
En/na Jonas Maebe ha escrit: > > On 14 jun 2007, at 19:04, Luca Olivetti wrote: > >> No suggestions? Is there some special option (apart from -g) that I >> should specify to compile/link my program? > > No. But the garbage backtrace means that either your gdb cannot parse > the signal handler frame, or that your program corrupted the call stack. Well, I'm starting to get desperate, I cannot debug where the sigsev occurs, I put a bazillion writeln and still I cannot see where the problem is. I can reproduce the sigsev at will, only I cannot see where it happens. I suspect it's one of the threads in the c library (linphonecore, http://www.linphone.org) I'm using (since in all of my threads I put writeln in the critical places, as well as in all the callbacks from said library), alas there's no sigsev when the same library is driven by the c console program that comes with it (linphonec). At one point I though the problem was in CheckSynchronize (since the last writeln before the sigsev was right before calling it), but it was just a timing coincidence (I was calling it with 1000, then when I tried with 0 I saw the sigsev right in the middle of a debugging printf in the library). Maybe it's not a good idea to mix c multithreaded libraries and pascal code? Any special unit I should use? (I already tried cmem and it made no difference). If I cannot solve it I think I'll have to write a small backend program in c that communicates with pascal either through stdin/stdout redirection or with a socket. Bye

IIRC, it is 'gcc -c <corefilename>'

TomW

Tom Walsh - WN3L - Embedded Systems Consultant http://openhardware.net http://cyberiansoftware.com http://openzipit.org "Windows? No thanks, I have work to do..." ----------------------------------------------------

Reply by email

Tom Walsh
to Luca Olivetti: En/na Jonas Maebe ha escrit: Well, I'm starting to get desperate, I cannot debug where…
Luca Olivetti wrote 32 lines
En/na Jonas Maebe ha escrit: > > On 14 jun 2007, at 19:04, Luca Olivetti wrote: > >> No suggestions? Is there some special option (apart from -g) that I >> should specify to compile/link my program? > > No. But the garbage backtrace means that either your gdb cannot parse > the signal handler frame, or that your program corrupted the call stack. Well, I'm starting to get desperate, I cannot debug where the sigsev occurs, I put a bazillion writeln and still I cannot see where the problem is. I can reproduce the sigsev at will, only I cannot see where it happens. I suspect it's one of the threads in the c library (linphonecore, http://www.linphone.org) I'm using (since in all of my threads I put writeln in the critical places, as well as in all the callbacks from said library), alas there's no sigsev when the same library is driven by the c console program that comes with it (linphonec). At one point I though the problem was in CheckSynchronize (since the last writeln before the sigsev was right before calling it), but it was just a timing coincidence (I was calling it with 1000, then when I tried with 0 I saw the sigsev right in the middle of a debugging printf in the library). Maybe it's not a good idea to mix c multithreaded libraries and pascal code? Any special unit I should use? (I already tried cmem and it made no difference). If I cannot solve it I think I'll have to write a small backend program in c that communicates with pascal either through stdin/stdout redirection or with a socket. Bye

Nope, it is 'gdb -c <corefilename>'. Sorry :-(

TomW

Tom Walsh - WN3L - Embedded Systems Consultant http://openhardware.net http://cyberiansoftware.com http://openzipit.org "Windows? No thanks, I have work to do..." ----------------------------------------------------

Reply by email

Jonas Maebe
to Luca Olivetti: En/na Jonas Maebe ha escrit: Well, I'm starting to get desperate, I cannot debug where…
Luca Olivetti wrote 9 lines
En/na Jonas Maebe ha escrit: > On 14 jun 2007, at 19:04, Luca Olivetti wrote: >> No suggestions? Is there some special option (apart from -g) that >> I should specify to compile/link my program? > No. But the garbage backtrace means that either your gdb cannot > parse the signal handler frame, or that your program corrupted the > call stack. Well, I'm starting to get desperate

Try compiling everything with -gv and using valgrind

Jonas

Reply by email

Luca Olivetti
to Jonas Maebe

En/na Jonas Maebe ha escrit:

Show quoted text 13 lines
On 25 jun 2007, at 22:44, Luca Olivetti wrote: > En/na Jonas Maebe ha escrit: >> On 14 jun 2007, at 19:04, Luca Olivetti wrote: >>> No suggestions? Is there some special option (apart from -g) that I >>> should specify to compile/link my program? >> No. But the garbage backtrace means that either your gdb cannot parse >> the signal handler frame, or that your program corrupted the call stack. > > Well, I'm starting to get desperate Try compiling everything with -gv and using valgrind

running under valgrind I cannot reproduce the segment violation :-( I should read valgrind documentation to interpret the data it prints out, however there's something that strikes me:

==5051== Thread 1:
==5051== Conditional jump or move depends on uninitialised value(s) ==5051== at 0x808DB59: BUTLER_TBUTLERPHONE_$__RECEIVE$ANSISTRING (butler.pas:444)
==5051== by 0x808F7B4: BUTLER_TSTATUSTHREAD_$__RECEIVE (butler.pas:697) ==5051== by 0x806BAA0: CLASSES_CHECKSYNCHRONIZE$LONGINT (in /home/luca/botphone/botphone)
==5051== by 0x804A96B: main (botphone.lpr:568)

where line 444 is:

442:  L:=length(s);
443:  if L<1 then exit;
444:  case s[1] of

so I can't see how it could possibly be uninitialized.

Bye

Luca

Reply by email

Cesar Romero
to Luca Olivetti

Where S is initialized?
I only see L initialized.

[]s

Cesar Romero

Show quoted text 8 lines
442: L:=length(s); 443: if L<1 then exit; 444: case s[1] of so I can't see how it could possibly be uninitialized. Bye

Reply by email

Luca Olivetti
to Cesar Romero

En/na Cesar Romero ha escrit:

Show quoted text 13 lines
Where S is initialized? I only see L initialized. []s Cesar Romero > > 442: L:=length(s); > 443: if L<1 then exit; > 444: case s[1] of > > so I can't see how it could possibly be uninitialized.

nothwithstanding the fact that if length(s)<1 line 444 won't be executed, so the "uninitialized" should be flagged in line 442, I know that this chunk is inside

procedure TButlerPhone.Receive(s: string);

so s is a parameter.
This procedure is called exclusively from

procedure TStatusThread.Receive;
begin
   FOwner.Receive(FData)
end;

(FOwner is a TButlerPhone)

which in turn is called only here:

           FData:=copy(buffer,i+2,L-1);
           if buffer[i+L+1]=checksum(FData) then
           begin
            if not terminated then synchronize(@Receive);
           end else

Bye

Luca

Reply by email

Vinzent Hoefler
to Luca Olivetti
Luca Olivetti wrote 19 lines
procedure TButlerPhone.Receive(s: string); so s is a parameter. This procedure is called exclusively from procedure TStatusThread.Receive; begin FOwner.Receive(FData) end; (FOwner is a TButlerPhone) which in turn is called only here: FData:=copy(buffer,i+2,L-1); if buffer[i+L+1]=checksum(FData) then begin if not terminated then synchronize(@Receive); end else

Are you passing AnsiString types between threads? If that's the case try using shortstrings or make a local copy of the parameter. And *DO NOT* pass them to a C-library in any way!

I had several problems doing that too (and I don't mean the obvious case if the string is changed in one thread while it's still accessed in the other). There also seemed to be some issues with the reference counting: if I passed a local AnsiString to a thread constructor as argument and left the routine then, this seemed to confuse the thread throwing SIGSEGVs occasionally. Making a copy of the string (means: assigning it to a field in the thread instance before and using this field from now on) inside the constructor solved this problem.

BTW, using the "disassemble" function of gdb sometimes reveals where the unnamed routine really is, so for the

#3  0x08059bec in ?? () No symbol table info available.

"disassemble 0x8059bec" *might* help you invastigating the source of the problem further.

HTH,

Vinzent.

Reply by email

Vinzent Hoefler
to Jonas Maebe: Maybe the parameter was declared as const? In that case, the refcount of the ansistring…
Jonas Maebe wrote 7 lines
On 27 jun 2007, at 08:13, Vinzent Hoefler wrote: > There also seemed to be some issues with the reference > counting: if I passed a local AnsiString to a thread constructor as > argument and left the routine then, this seemed to confuse the > thread throwing SIGSEGVs occasionally. Maybe the parameter was declared as const?

I think so. I always do that. ;)

In that case, the refcount of the ansistring you pass isn't increased,

Meaning that the string will be freed once I leave the routine that called the constructor? That would explain it for sure.

Regards,

Vinzent.

Reply by email

Jonas Maebe
to Vinzent Hoefler: Are you passing AnsiString types between threads? If that's the case try using…
Vinzent Hoefler wrote
There also seemed to be some issues with the reference counting: if I passed a local AnsiString to a thread constructor as argument and left the routine then, this seemed to confuse the thread throwing SIGSEGVs occasionally.

Maybe the parameter was declared as const? In that case, the refcount of the ansistring you pass isn't increased, because the compiler interprets the const as "the ansistring will not be changed in any way as long as that constructor is running". If it's a value parameter, it should work fine (a var parameter obviously wouldn't work either).

Jonas

Reply by email

Luca Olivetti
to Vinzent Hoefler: Are you passing AnsiString types between threads? If that's the case try using…

En/na Vinzent Hoefler ha escrit:

Show quoted text 23 lines
On Tuesday 26 June 2007 17:26, Luca Olivetti wrote: > procedure TButlerPhone.Receive(s: string); > > so s is a parameter. > This procedure is called exclusively from > > procedure TStatusThread.Receive; > begin > FOwner.Receive(FData) > end; > > (FOwner is a TButlerPhone) > > which in turn is called only here: > > FData:=copy(buffer,i+2,L-1); > if buffer[i+L+1]=checksum(FData) then > begin > if not terminated then synchronize(@Receive); > end else Are you passing AnsiString types between threads?

yes and no: the synchronize should assure that TButlerPhone.Receive is called from the main thread, and TStatusThread will wait until completion of the call.

If that's the case try using shortstrings or make a local copy of the parameter

I'll try that (though I think it shouldn't be necessary)

. And *DO NOT* pass them to a C-library in any way!

Not even surrounded by PChar()?
(now that I think of it, it could well be that the library is storing the pointer and using it later when it is no longer valid, let me check....no, it doesn't).

Show quoted text 8 lines
I had several problems doing that too (and I don't mean the obvious case if the string is changed in one thread while it's still accessed in the other). There also seemed to be some issues with the reference counting: if I passed a local AnsiString to a thread constructor as argument and left the routine then, this seemed to confuse the thread throwing SIGSEGVs occasionally. Making a copy of the string (means: assigning it to a field in the thread instance before and using this field from now on) inside the constructor solved this problem.

Do you mean like (absurd example, I know)

TMyThread.Constructor(astring:string);
begin
   FString:=astring;
   FNum:=StrToInt(FString);
   inherited create(false);
end;

instead of

TMyThread.Constructor(astring:string);
begin
   FNum:=StrToInt(astring);
   inherited create(false);
end;

again, I don't think it should be necessary if you're only going to use astring in the constructor.

Show quoted text 9 lines
BTW, using the "disassemble" function of gdb sometimes reveals where the unnamed routine really is, so for the > #3 0x08059bec in ?? () > No symbol table info available. "disassemble 0x8059bec" *might* help you invastigating the source of the problem further.

thanks, I'll give it a try, though the last time I used assembly language was with a Z80 when it was new ;-)

Bye

Luca

Reply by email

Luca Olivetti
to Luca Olivetti

En/na Luca Olivetti ha escrit:

Show quoted text 12 lines
> > BTW, using the "disassemble" function of gdb sometimes reveals where > the unnamed routine really is, so for the > >> #3 0x08059bec in ?? () >> No symbol table info available. > > "disassemble 0x8059bec" *might* help you invastigating the source of > the problem further. thanks, I'll give it a try, though the last time I used assembly language was with a Z80 when it was new ;-)

well, I tried (with a fresh core, so the addresses are different than the previous one, but the result is the same):

Core was generated by `./botphone -c /home/luca/.linphonerc'. Program terminated with signal 11, Segmentation fault. #0 0x0805989a in SYSTEM_GETERRNO$$LONGINT ()
(gdb) bt
#0 0x0805989a in SYSTEM_GETERRNO$$LONGINT ()
#1 0x080608f2 in SYSTEM_REENABLE_SIGNAL$LONGINT$$BOOLEAN () #2 0x08060a30 in SYSTEM_SIGNALTORUNERROR$LONGINT$PSIGINFO$PUCONTEXT () #3 0x0805a09c in ?? ()
#4 0x0000000b in ?? ()
#5 0xb6b6619c in ?? ()
#6 0xb6b6621c in ?? ()
#7 0x0000000b in ?? ()
#8 0x00000000 in ?? ()
(gdb) disassemble 0x0805a09c
Dump of assembler code for function SYSTEM_LINUX_RESTORE_RT: 0x0805a09c <SYSTEM_LINUX_RESTORE_RT+0>: mov $0xad,%eax 0x0805a0a1 <SYSTEM_LINUX_RESTORE_RT+5>: int $0x80 0x0805a0a3 <SYSTEM_LINUX_RESTORE_RT+7>: ret
End of assembler dump.
(gdb) disassemble 0x0000000b
No function contains specified address.
(gdb) disassemble 0xb6b6619c
No function contains specified address.
(gdb) disassemble 0xb6b6621c
No function contains specified address.
(gdb) disassemble 0x00000000
No function contains specified address.
(gdb)

Oh well, I can always run the program under "valgrind --tool=none" :-P

Bye

Luca

Reply by email

Luca Olivetti
to Luca Olivetti: En/na Cesar Romero ha escrit: nothwithstanding the fact that if length(s)<1 line 444…

En/na Luca Olivetti ha escrit:

Show quoted text 39 lines
En/na Cesar Romero ha escrit: > Where S is initialized? > I only see L initialized. > > []s > > > Cesar Romero >> >> 442: L:=length(s); >> 443: if L<1 then exit; >> 444: case s[1] of >> >> so I can't see how it could possibly be uninitialized. nothwithstanding the fact that if length(s)<1 line 444 won't be executed, so the "uninitialized" should be flagged in line 442, I know that this chunk is inside procedure TButlerPhone.Receive(s: string); so s is a parameter. This procedure is called exclusively from procedure TStatusThread.Receive; begin FOwner.Receive(FData) end; (FOwner is a TButlerPhone) which in turn is called only here: FData:=copy(buffer,i+2,L-1); if buffer[i+L+1]=checksum(FData) then begin if not terminated then synchronize(@Receive); end else

And another writeln confirms that L is 1 when valgrind complains, so the string is definitely initialized.

Bye

Luca

Reply by email

Vincent Snijders
to Luca Olivetti
Show quoted text 43 lines
En/na Luca Olivetti ha escrit: > En/na Cesar Romero ha escrit: >> Where S is initialized? >> I only see L initialized. >> >> []s >> >> >> Cesar Romero >>> >>> 442: L:=length(s); >>> 443: if L<1 then exit; >>> 444: case s[1] of >>> >>> so I can't see how it could possibly be uninitialized. > > nothwithstanding the fact that if length(s)<1 line 444 won't be > executed, so the "uninitialized" should be flagged in line 442, I know > that this chunk is inside > > procedure TButlerPhone.Receive(s: string); > > so s is a parameter. > This procedure is called exclusively from > > procedure TStatusThread.Receive; > begin > FOwner.Receive(FData) > end; > > (FOwner is a TButlerPhone) > > which in turn is called only here: > > FData:=copy(buffer,i+2,L-1); > if buffer[i+L+1]=checksum(FData) then > begin > if not terminated then synchronize(@Receive); > end else > And another writeln confirms that L is 1 when valgrind complains, so the string is definitely initialized.

Did you write to that string or merely set its length using SetLength?

Vincent

Reply by email

Luca Olivetti
to Vincent Snijders

En/na Vincent Snijders ha escrit:

Show quoted text 45 lines
On Wed, 27 Jun 2007 19:38:03 +0200 Luca Olivetti wrote: > En/na Luca Olivetti ha escrit: >> En/na Cesar Romero ha escrit: >>> Where S is initialized? >>> I only see L initialized. >>> >>> []s >>> >>> >>> Cesar Romero >>>> 442: L:=length(s); >>>> 443: if L<1 then exit; >>>> 444: case s[1] of >>>> >>>> so I can't see how it could possibly be uninitialized. >> nothwithstanding the fact that if length(s)<1 line 444 won't be >> executed, so the "uninitialized" should be flagged in line 442, I know >> that this chunk is inside >> >> procedure TButlerPhone.Receive(s: string); >> >> so s is a parameter. >> This procedure is called exclusively from >> >> procedure TStatusThread.Receive; >> begin >> FOwner.Receive(FData) >> end; >> >> (FOwner is a TButlerPhone) >> >> which in turn is called only here: >> >> FData:=copy(buffer,i+2,L-1); >> if buffer[i+L+1]=checksum(FData) then >> begin >> if not terminated then synchronize(@Receive); >> end else >> > And another writeln confirms that L is 1 when valgrind complains, so the > string is definitely initialized. Did you write to that string or merely set its length using SetLength?

The string was passed as a value parameter, coming from fdata:

FData:=copy(buffer,i+2,L-1) (buffer is a static array of char, FData is
a string, field of the class)
if buffer[i+L+1]=checksum(FData) then
   synchronize(@receive) ----->
TStatusThread.Receive;
begin
   FOwner.Receive(FData)

procedure TButlerPhone.Receive(s: string);
....

   L:=length(s);
   writeln('>>>>>>>>>>>>>>>>>>>>>>> ',L);  ---> to confirm, and it's

always >0

   if L<1 then exit;
   case s[1] of  --> here valgrind complains

Anyway, I doubt the problems is here, it only strikes me that valgrind complains.

Bye

Luca

Reply by email

Luca Olivetti
to Luca Olivetti: En/na Jonas Maebe ha escrit: Well, I'm starting to get desperate, I cannot debug where…

En/na Luca Olivetti ha escrit:

Show quoted text 6 lines
Maybe it's not a good idea to mix c multithreaded libraries and pascal code? Any special unit I should use? (I already tried cmem and it made no difference). If I cannot solve it I think I'll have to write a small backend program in c that communicates with pascal either through stdin/stdout redirection or with a socket.

Well, I actually did that and it works pretty well: I hacked the existing linphonec console program to output status codes on stdout, I spawn it using a TProcess to read its input and sending it commands. Everything else in my program is pretty much the same (where before I called a linphone routine, now I write to the TProcess input, where before I gathered status information from a callback[*] now I read from the TProcess output), so I think there's no glaring error in the logic of my program, just something "strange" mixing pascal and c code (note that I'm still using libusb with no apparent issues). I'd really like to debug the original problem, since the current workaround is too hackish to be published, but, alas, every effort to debug it so far has failed.

[*]note that the callbacks were not called at random, but only during a specific call to the linphone library, so there are no synchronization differences between the library calls and the TProcess polling.

Bye

Luca

Reply by email