Sign in Join

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

Mailing lists / fpc-devel / 2014-08

SYSUTILS UTF8String Memory Bug

6 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

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

mark diener

I have been getting some pretty strange errors on Lazarus 1.2.4/FreePascal 2.6.4 on windows 8.1 x64

It looks like some internal system memory cache is croaking while waiting for a free fixed memory chunk.

This is a 2 threaded program using TThread, so the notion of a memory seg fault while "waiting" means the system cache
is apparently not thread safe.

The code passes thru the SYSUTILS_RIGHTSTR many times before faulting, so it

I sent another request for anybody to provide a tip at having the stack trace actually fill in the #1 ?? at :0 entries
in the trace and that would be helpful now.

This is the first time that the problem is squarely inside system.pas/sysutils.pas on the call stack. There are no other dependencies like references to global memory, etc.

We clearly have a call to SYSUTILS.rightstr( ).

Here is the stack trace of the memory exception:

#0 SYSTEM_WAITFREE_FIXED$PMEMCHUNK_FIXED$POSCHUNK at :0 #1 ?? at :0
#2 SYSUTILS_RIGHTSTR$ANSISTRING$LONGINT$$ANSISTRING at :0 #3 LEFTPAD(0x4dbf890 'DE26', 4, 48 '0', 0x0) at
C:\pdev\rpzlib\rpzstring.pas:349
#4 RPZCHKSUMPTR4(0x2dc251
'^i'#31'{66h'#7'O'#150#195'n3BD'#166#243#162'~'#188#184#171'7'#218'E'#227'3!v'#206'L'#179'[ENDE26]', 32, 0x0) at C:\pdev\rpzlib\rpzcrc16.pas:69
#5 TRPZUDPFRAME__RXPUMP(100, <error reading variable>) at C:\pdev\rpzlib\rpzudpframe.pas:401
#6 TRPZUDPSRV__EXECWRAPPER(<error reading variable>) at C:\pdev\rpzlib\rpzudpsrv.pas:228
#7 TRPZUDPSRV__EXECUTE(<error reading variable>) at C:\pdev\rpzlib\rpzudpsrv.pas:171
#8 CLASSES_THREADPROC$POINTER$$LONGINT at :0
#9 SYSTEM_THREADMAIN$POINTER$$LONGINT at :0
#10 KERNEL32!CreateWaitableTimerA at :0
#11 ?? at :0
#12 ?? at :0
#13 ?? at :0
#14 ?? at :0

Now when I run the same test using cmem as the memory manager, I get the following exception violoatoin:

#0 fpc_ansistr_decr_ref at :0
#1 ?? at :0
#2 TAPPLICATION__PROCESSASYNCCALLQUEUE(<error reading variable>) at .\include\application.inc:1079
#3 TAPPLICATION__IDLE(true, <error reading variable>) at .\include\application.inc:389
#4 TAPPLICATION__HANDLEMESSAGE(<error reading variable>) at .\include\application.inc:1273
#5 TAPPLICATION__RUNLOOP(<error reading variable>) at .\include\application.inc:1405
#6 TWIDGETSET__APPRUN(0x422b50 <TAPPLICATION__RUNLOOP>, <error reading variable>) at .\include\interfacebase.inc:54
#7 TAPPLICATION__RUN(<error reading variable>) at
.\include\application.inc:1393
#8 :29

So with the memory manager changed out, the exception now occurs in the GUI main thread instead of the TThread and clearly the fpc_ansistr_decr_ref function is failing.

The lines in question in .\include\application.inc:1079 are as follows:

      // call event
      Event(Data);

This Event variable is a pointer to a function with a single pointer to integer argument.

Anybody got some ideas about this?

Cheers,

Marco

Reply by email

Jonas Maebe
to mark diener
mark diener wrote 13 lines
So with the memory manager changed out, the exception now occurs in the GUI main thread instead of the TThread and clearly the fpc_ansistr_decr_ref function is failing. The lines in question in .\include\application.inc:1079 are as follows: // call event Event(Data); This Event variable is a pointer to a function with a single pointer to integer argument. Anybody got some ideas about this?

Your program probably contains a memory corruption bug that messes up the heap state. To find it, you can try enabling range and class type checking (-CRr) and enabling heaptrc (-gh), or using the C memory manager and running the program through Dr Memory (http://www.drmemory.org )

Jonas

Reply by email

mark diener
to Jonas Maebe

Jonas:

I am working on the heaptrc and DrMemory analysis today.

Switching to range checks (-CRr) begins a new round of code changing to handle compile errors as shown by example below.

How would you begin to clean up the code so that range checks

Your response appreciated,

Marco

************************************

For example:

Compile Error Message:

C:\pdev\rpzlib\rpzopsyswin32.pas(46,37) Error: range check error while
evaluating constants

Offending code:

nres := ioctlsocket(socket,FIONBIO,@nblock) ;

So my FIONBIO constant is triggering a compile time error.

From winsock2.pas:
const
  FIONBIO      = ULONG(IOC_IN or { set/clear non-blocking i/o }
    ((Longint(SizeOf(Longint)) and IOCPARM_MASK) shl 16) or
    (Longint(Byte('f')) shl 8) or 126);
function ioctlsocket( const s: TSocket; cmd: Longint; argp: pu_long ):
Longint; stdcall;external WINSOCK2_DLL name 'ioctlsocket';
Jonas Maebe wrote 28 lines
On 09/08/14 20:06, mark diener wrote: > So with the memory manager changed out, the exception now occurs in the > GUI main thread instead of the TThread and clearly the > fpc_ansistr_decr_ref function is failing. > > The lines in question in .\include\application.inc:1079 are as follows: > > // call event > Event(Data); > > This Event variable is a pointer to a function with a single pointer to > integer argument. > > Anybody got some ideas about this? > Your program probably contains a memory corruption bug that messes up the heap state. To find it, you can try enabling range and class type checking (-CRr) and enabling heaptrc (-gh), or using the C memory manager and running the program through Dr Memory (http://www.drmemory.org ) Jonas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Marco van de Voort
to mark diener

In our previous episode, mark diener said:

Show quoted text 20 lines
Compile Error Message: C:\pdev\rpzlib\rpzopsyswin32.pas(46,37) Error: range check error while evaluating constants Offending code: nres := ioctlsocket(socket,FIONBIO,@nblock) ; So my FIONBIO constant is triggering a compile time error. >From winsock2.pas: const FIONBIO = ULONG(IOC_IN or { set/clear non-blocking i/o } ((Longint(SizeOf(Longint)) and IOCPARM_MASK) shl 16) or (Longint(Byte('f')) shl 8) or 126); function ioctlsocket( const s: TSocket; cmd: Longint; argp: pu_long ): Longint; stdcall;external WINSOCK2_DLL name 'ioctlsocket';

You pass an unsigned ULONG (FIONBIO) constant to a signed (cmd) parameter, so that is correct, the ranges don't match.

Also, in the constant, most of the expression is longint, while IOC_IN ($8000000) is beyond that range.

Reply by email

mark diener
to Jonas Maebe: Your program probably contains a memory corruption bug that messes up the heap state. To…

Jonas,

I ran heaptrc AND Dr memory and there are definitely some issues. I posted a separate thread to focus on baseline Dr Memory errors for lazarus/freepascal

One of my problems is the stack reported by the results.txt file shows the same code point: rpzstring.pas:193.

Any ideas on how to improve the reported code location. I can promise you that fpc_ansistr_setlength is not located in rpzstring.pas. It's in the RTL!!!

Project compiled with CMEM, Dwarf2 (-gw2) and requested by Dr Memory docs.

Cheers,

marco

Error #62: POSSIBLE LEAK 26 direct bytes 0x05183f70-0x05183f8a + 0 indirect bytes
# 0
replace_malloc
[d:\drmemory_package\common\alloc_replace.c:2320]
# 1
CMEM_CGETMEM$LONGWORD$$POINTER
[../rpzlib/rpzstring.pas:193]
# 2
SYSTEM_GETMEM$POINTER$LONGWORD
[../rpzlib/rpzstring.pas:193]
# 3
fpc_ansistr_setlength
[../rpzlib/rpzstring.pas:193]
# 4
LAZUTF8_UTF16TOUTF8$UNICODESTRING$$ANSISTRING
[../rpzlib/rpzstring.pas:193]
# 5
LCLPROC_UTF16TOUTF8$UTF16STRING$$ANSISTRING
[../rpzlib/rpzstring.pas:193]
# 6
WIN32PROC_GETCONTROLTEXT$LONGWORD$$ANSISTRING
[../rpzlib/rpzstring.pas:193]
# 7
WIN32WSSTDCTRLS_TWIN32WSCUSTOMEDIT_$__GETTEXT$TWINCONTROL$ANSISTRING$$BOOLEAN [../rpzlib/rpzstring.pas:193]
# 8
CONTROLS_TWINCONTROL_$__REALGETTEXT$$TTRANSLATESTRING [../rpzlib/rpzstring.pas:193]
# 9
CONTROLS_TCONTROL_$__GETTEXT$$TTRANSLATESTRING
[../rpzlib/rpzstring.pas:193]
#10
MAINFM_TFMMAIN_$__RXLISTENCLICK$TOBJECT
[C:/pdev/rpztestudphv//mainfm.pas:94]
#11
CONTROLS_TCONTROL_$__CLICK
[../rpzlib/rpzstring.pas:193]

Jonas Maebe wrote 28 lines
On 09/08/14 20:06, mark diener wrote: > So with the memory manager changed out, the exception now occurs in the > GUI main thread instead of the TThread and clearly the > fpc_ansistr_decr_ref function is failing. > > The lines in question in .\include\application.inc:1079 are as follows: > > // call event > Event(Data); > > This Event variable is a pointer to a function with a single pointer to > integer argument. > > Anybody got some ideas about this? > Your program probably contains a memory corruption bug that messes up the heap state. To find it, you can try enabling range and class type checking (-CRr) and enabling heaptrc (-gh), or using the C memory manager and running the program through Dr Memory (http://www.drmemory.org ) Jonas _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply by email

Jonas Maebe
to mark diener
mark diener wrote 14 lines
I ran heaptrc AND Dr memory and there are definitely some issues. I posted a separate thread to focus on baseline Dr Memory errors for lazarus/freepascal One of my problems is the stack reported by the results.txt file shows the same code point: rpzstring.pas:193. Any ideas on how to improve the reported code location. I can promise you that fpc_ansistr_setlength is not located in rpzstring.pas. It's in the RTL!!!

It shows the last code for which it has debug information. If you compile the RTL (and LCL) with -gw2 (and make sure your program uses those recompiled units), then you will get source code information for them too.

Project compiled with CMEM, Dwarf2 (-gw2) and requested by Dr Memory docs.

The issue you posted below is unlikely to be related to the crashing problems you have. It only talks about a *possible* leak. Memory leaks do not lead to crashes, unless you exhaust all available memory or address space (which is not the case here). Additionally, it is probably a false detection, possibly triggered by the fact that ansistrings point past the header of the allocated block (an ansistring consists of an, internal implementation-defined, header followed by the string data, and the ansistring points to the string data).

Jonas

Reply by email