English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. C/C++

 
 
Thread Tools
Old 30 January 2023, 00:09   #1
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Different Results for malloc(0) Without/With Optimisations with VBCC

Hi there!

I stumble upon a problem with malloc() when the size is 0. I have this piece of code that can receive different sizes (depending on the HTTP answer from a Web server). Essentially:

Code:
	hresp->body     = malloc(number_of_bytes);
	if(hresp->body  == NULL)
	{
		temp_string = NULL;
		log_print_error("_http_request(), could not allocate response body\n");
		goto _RETURN_ERROR;
	}
When compiling without optimisation, when number_of_bytes == 0, malloc returns a non-NULL value (which was fine for the rest of my code). When compiling with optimisation, when number_of_bytes == 0, malloc returns a NULL value (which broke my code, but I fixed it ).

Without optimisation:

Code:
all :  COFLAGS += -O=1 -g -hunkdebug -DFORTIFY -DUNRECOGNISED
all :  ASFLAGS +=
all :  LDFLAGS += -S -s -sc -sd
With optimisation:

Code:
dist : COFLAGS += -O=3 -size -final
dist : ASFLAGS += -opt-size
dist : LDFLAGS +=
I wonder if that's expected, with VBCC v0.9h?

Cheers!

Last edited by tygre; 30 January 2023 at 00:39.
tygre is offline  
Old 30 January 2023, 02:28   #2
coldacid
WinUAE 4000/40, V4SA
 
coldacid's Avatar
 
Join Date: Apr 2020
Location: East of Oshawa
Posts: 538
Why are you allocating 0 bytes, though? Would it be possible to just skip malloc() when you aren't allocating anything?
coldacid is offline  
Old 30 January 2023, 05:32   #3
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi ColdAcid!

Yes, I know have a if that checks for zero value but I preferred my code before, it was simpler, more "linear" .

The reason for have a zero value is that the body of a HTTP response may be of 0-length, for example in the case of a redirect (status code 302).

Still, I wonder if the difference of behaviours is expected wrt. the difference compiler optimisations?

Take care!
tygre is offline  
Old 30 January 2023, 08:39   #4
patrik
Registered User
 
patrik's Avatar
 
Join Date: Jan 2005
Location: Umeå
Age: 43
Posts: 922
Content-Length is not required in the answer and might be missing for unknown reasons. An example where it is always missing is for streaming sources.
patrik is offline  
Old 30 January 2023, 08:41   #5
Karlos
Alien Bleed
 
Karlos's Avatar
 
Join Date: Aug 2022
Location: UK
Posts: 4,121
Have you checked what the C library says about it? It sounds like something that might be undefined behaviour.
Karlos is online now  
Old 30 January 2023, 09:27   #6
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,215
Both is actually allowed.

Quote:
The malloc() function allocates size bytes and returns a pointer to the allocated
memory. The memory is not initialized. If size is 0, then malloc() returns either
NULL, or a unique pointer value that can later be successfully passed to free().
Thomas Richter is offline  
Old 30 January 2023, 10:22   #7
Karlos
Alien Bleed
 
Karlos's Avatar
 
Join Date: Aug 2022
Location: UK
Posts: 4,121
Personally I'd never try to allocate zero bytes. Sounds like a logical error to me.
Karlos is online now  
Old 30 January 2023, 10:34   #8
hooverphonique
ex. demoscener "Bigmama"
 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,624
Quote:
Originally Posted by Thomas Richter View Post
Both is actually allowed.
I like the second one where you don't (as a malloc client) need to treat 0 size as a special case.


On the other hand, if it changes with optimization levels, then not so much.
hooverphonique is offline  
Old 30 January 2023, 15:08   #9
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi all!

Exactly my point, HooverPhonique: I liked the case "a unique pointer value that can later be successfully passed to free()" because it made my code more straightforward

I'm just wondering if it's expected from VBCC (or something else?) to have two different behaviours depending on the compilation options?

Cheers!
tygre is offline  
Old 30 January 2023, 15:44   #10
Karlos
Alien Bleed
 
Karlos's Avatar
 
Join Date: Aug 2022
Location: UK
Posts: 4,121
Quote:
Originally Posted by tygre View Post
Hi all!

Exactly my point, HooverPhonique: I liked the case "a unique pointer value that can later be successfully passed to free()" because it made my code more straightforward

I'm just wondering if it's expected from VBCC (or something else?) to have two different behaviours depending on the compilation options?

Cheers!
I don't remember the last iteration of libc I've used were free(0) wasn't a no-op.
Karlos is online now  
Old 30 January 2023, 16:04   #11
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
PS. Here is the problem is with malloc(0)
tygre is offline  
Old 30 January 2023, 17:41   #12
vbc
Registered User
 
Join Date: Jan 2021
Location: Germany
Posts: 18
Quote:
Originally Posted by tygre View Post
When compiling without optimisation, when number_of_bytes == 0, malloc returns a non-NULL value (which was fine for the rest of my code). When compiling with optimisation, when number_of_bytes == 0, malloc returns a NULL value (which broke my code, but I fixed it ).
What target configuration are you using? I think the vbcc libraries for m68k-amigaos and m68k-kick13 both explicitly check for 0 and return 0.
Quote:
With optimisation:

Code:
dist : COFLAGS += -O=3 -size -final
Btw. -O=3 is probably not what you want. For high optimization level use option -O3 with vc or -O=-1 when calling vbcc directly (although using the frontend is recommended as it takes care of some other stuff).
vbc is offline  
Old 30 January 2023, 17:56   #13
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi VBC!

I'm targetting m86k-amigos, compiling against NDK v3.2R4.

Thanks for the tip about the optimisation!
Update: I tried O=-1 and the resulting object files are broken: they are between 28 and 40 bytes instead of "normal" sizes

Cheers!

Last edited by tygre; 30 January 2023 at 18:12.
tygre is offline  
Old 30 January 2023, 18:42   #14
vbc
Registered User
 
Join Date: Jan 2021
Location: Germany
Posts: 18
Quote:
Originally Posted by tygre View Post
I'm targetting m86k-amigos, compiling against NDK v3.2R4.
Strange. I double-checked the vc.lib from the target-archive and it does contain a check for 0 in malloc(). Are you sure about the malloc(0)?

Quote:
Update: I tried O=-1 and the resulting object files are broken: they are between 28 and 40 bytes instead of "normal" sizes
Without knowing your build commands, I would suggest removing -final. This option requires that the entire source code is passed to vbcc in a single invocation and everything that is not reached from main() or objects marked __entry is removed. With separate compilation it will pretty much remove everything. For most normal cases you can omit it and the linker will do an adequate job.
vbc is offline  
Old 30 January 2023, 20:17   #15
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Quote:
Originally Posted by vbc View Post
Strange. I double-checked the vc.lib from the target-archive and it does contain a check for 0 in malloc(). Are you sure about the malloc(0)?
Yes, absolutely sure
It bit my behind when I released the "release" version of my code (with the optimisations), in which malloc(0) was now returning NULL instead of a "valid" pointer.

Quote:
Originally Posted by vbc View Post
Without knowing your build commands, I would suggest removing -final. This option requires that the entire source code is passed to vbcc in a single invocation and everything that is not reached from main() or objects marked __entry is removed. With separate compilation it will pretty much remove everything. For most normal cases you can omit it and the linker will do an adequate job.
Exactly that, thanks
tygre is offline  
Old 31 January 2023, 17:33   #16
vbc
Registered User
 
Join Date: Jan 2021
Location: Germany
Posts: 18
Quote:
Originally Posted by tygre View Post
Yes, absolutely sure
It bit my behind when I released the "release" version of my code (with the optimisations), in which malloc(0) was now returning NULL instead of a "valid" pointer.
Yes, what seems strange to me is that the non-optimized version would have returned non-zero for malloc(0). Are you sure that there are no other differences between those builds?
vbc is offline  
Old 31 January 2023, 20:03   #17
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by tygre View Post
I'm just wondering if it's expected from VBCC (or something else?) to have two different behaviours depending on the compilation options?
Like vbc I see no reason why it should happen with vbcc's vclib. But you should expect different behaviours! For example if you want to compile your source with different compilers or clibs.

Maybe some of your defines in the no-optmisation build (like -DFORTIFY) overload vclib's malloc() and implement your own functions for debugging purposes?

Otherwise, prepare a small example for reproduction and I will happily analyse it.
phx is offline  
Old 01 February 2023, 01:26   #18
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi there

Indeed it could be something like Fortify... let me prepare this MWE and see if I can reproduce this difference!

Will keep you posted!
tygre is offline  
Old 04 February 2023, 17:53   #19
tygre
Returning fan!
 
tygre's Avatar
 
Join Date: Jan 2011
Location: Montréal, QC, Canada
Posts: 1,434
Hi there!

So I created a MWE and, indeed, it's Fortify that changes the behaviour of malloc(0)! With Fortify enabled, malloc(0) returns a non-NULL pointer ("0 bytes in 1 blocks with 104 bytes overheard") while, with Fortify disabled, malloc(0) returns NULL.

Mystery solved!

(I joined this MWE, just (un)comment -DFORTIFY in the makefile to see the difference.)

Cheers!
Attached Files
File Type: zip Malloc0.zip (37.4 KB, 35 views)
tygre is offline  
Old 15 February 2023, 13:15   #20
Olaf Barthel
Registered User
 
Join Date: Aug 2010
Location: Germany
Posts: 532
Quote:
Originally Posted by tygre View Post
Hi there!

I stumble upon a problem with malloc() when the size is 0. I have this piece of code that can receive different sizes (depending on the HTTP answer from a Web server).
Sorry for being late: the effect of malloc(0) is basically implementation-defined. The standard (this being POSIX and the ISO 'C' standard: visit https://pubs.opengroup.org/onlinepub...9.2018edition/ and enter "malloc" into the search form) offers two alternative behaviours. The first being to return NULL and the second returning a pointer to a small memory allocation.

The second behaviour is very common on POSIX systems and the malloc/calloc/realloc implementations in my clib2 code feature this behaviour if you use libunix.a instead of the libc.a variant (which uses the first behaviour).

Small computer systems such as the Amiga tend to have a different view here with regard to what the standard library functions might do. malloc(0) might not yield option #1 (a NULL pointer), option #2 (a pointer to a small memory allocation), but option #3477: memory corruption with or without a crash later or maybe sooner.

All this goes to say that you should never ever put your trust into the 'C' standard library to do right by you under circumstances which challenge the specification of the respective library function. If you read the historic documentation for it, e.g. Manx Aztec 'C' of yore, you will find that it mostly describes the "happy case" and leaves the likely undefined behaviour outside the specified use to the imagination of the reader.

Bottom line is that you need to be most careful on the Amiga, reviewing code you are porting for gotchas such as the malloc(0) jack-in-the-box. Defensive programming is called for, not just for your own code but also for somebody else's...
Olaf Barthel is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
68000 code optimisations pmc Coders. Asm / Hardware 248 17 September 2023 13:20
optimisations for 68000 Galahad/FLT Coders. Asm / Hardware 16 13 January 2023 11:45
AllocSysObject vs malloc? Sim085 Coders. C/C++ 12 17 December 2022 17:47
16x16 CPU tile flip optimisations mcgeezer Coders. Asm / Hardware 51 20 February 2021 11:54
Is there some compiler providing resource tracking for malloc/free/FILE* handles? jotd Coders. C/C++ 3 29 December 2018 11:58

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 21:33.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.10742 seconds with 14 queries