Splint doesn't know that library function is freeing memory - mysql

When using MySQL in C you free the memory using the MySQL API, like so:
MYSQL* connection = NULL;
connection = mysql_init(NULL);
// Stuff...
mysql_close(connection);
But Splint doesn't know that mysql_close is in fact freeing memory, so I get this error:
Fresh storage connection not released before return
A memory leak has been detected. Storage allocated locally is
not released before the last reference to it is lost. (Use
-mustfreefresh to inhibit warning)
How do I tell Splint that mysql_close is deallocating memory? A special annotation to the mysql.h file?
EDIT: OK, maybe the releases *p annotation, if that can be used in a header file. Will try.
EDIT 2: Added /*#releases *sock#*/ to mysql.h, but now get this error:
Releases clauses includes *sock of non-dynamically allocated
type MYSQL
A declaration uses an invalid annotation. (Use -annotationerror to inhibit
warning)
This is the signaure of mysql_close:
void STDCALL mysql_close(/*#notnull#*/ MYSQL *sock) /*#releases *sock#*/;

I believe that proper annotation would be:
void STDCALL mysql_close(/*#special#*/ /*#notnull#*/ MYSQL *sock)
/*#releases sock#*/;
The key, that you have missed is /*#special#*/ annotation, that is required to "activate" so called state clauses. From Splint's documentation, 7.4 State Clauses:
The /*#special#*/ annotation is used to mark a parameter, global
variable, or return value that is described using state clauses.

Related

Expected lifetime of object passed in VkGraphicsPipelineCreateInfo [duplicate]

I'm starting to learn Vulkan, and want to know if VkCreate[...] functions copy the resources pointed in structs into his own buffers.
To clarify my question, in this code I load a SPIR shader into my own mkShader struct and then I create the shadermodule with vkCreateShaderModule.
static VkShaderModule mkVulkanCreateShaderModule(MkVulkanContext *vc,
const char *filename)
{
VkShaderModule shaderModule;
struct mkShader *shader = mkVulkanLoadShaderBinary(filename);
VkShaderModuleCreateInfo createInfo = {0};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = shader->size;
createInfo.pCode = (uint32_t *)shader->buffer;
if (vkCreateShaderModule(vc->device, &createInfo, NULL,
&shaderModule) != VK_SUCCESS) {
printf(ANSI_COLOR_RED
"Failed to create shader module\n" ANSI_COLOR_RESET);
assert(0);
exit(EXIT_FAILURE);
}
mkVulkanFreeShaderBinary(shader);
return shaderModule;
}
As you can see I'm freeing the mkShader struct with mkVulkanFreeShaderBinaryafter shader module creation and I'm not receiving any error from my program. So my question is if this is safe to do, or I have to keep the mkShader struct until I destroy the shader module. And also, if this is valid to all VkCreate[...] functions or not, and if this information is anywhere in the Vulkan spec.
See Object Lifetime of the Vulkan specification.
The ownership of application-owned memory is immediately acquired by any Vulkan command it is passed into. Ownership of such memory must be released back to the application at the end of the duration of the command, so that the application can alter or free this memory as soon as all the commands that acquired it have returned.
In other words, anything you allocate you are free to delete as soon as a Vulkan function call returns. Additionally, once you've created your pipeline, you're free to destroy the VkShaderModule too.

MariaDB non-blocking with EPOLL

I have single threaded server written in C that accepts TCP/UDP connections based on EPOLL and supports plugins for the multitude of protocol layers we need to support. That bit is fine.
Due to the single threaded nature, I wanted to implement a database layer that could utilize the same EPOLL architecture rather then separately iterating over all of the open connections.
We use MariaDB and the MariaDB connector that supports non blocking functions in it's API.
https://mariadb.com/kb/en/mariadb/using-the-non-blocking-library/
But what I'm finding is not what I expected, and what I was expecting is described below.
First I fire the mysql_real_connect_start() and if it returns zero we dispatch the query immediately as this indicates no blocking was required, although this never happens.
Otherwise, I fetch the file descriptor that seems to be immediate and register it with EPOLL and bail back to the main EPOLL loop waiting for events.
s = mysql_get_socket(mysql);
if(s > 0)
{
brt_socket_set_fds(endpoint, s);
struct epoll_event event;
event.data.fd = s;
event.events = EPOLLRDHUP | EPOLLIN | EPOLLET | EPOLLOUT;
s = epoll_ctl(efd, EPOLL_CTL_ADD, s, &event);
if (s == -1) {
syslog(LOG_ERR, "brd_db : epoll error.");
// handle error.
}
...
So, then some time later I do get the EPOLLOUT indicating the socket has been opened.
And I dutifully call mysql_real_connect_cont() but at this stage it is still returning a non-zero value, indicating I must wait longer?
But then that is the last EPOLL event I get, except for the EPOLLRDHUP when I guess the MariaDB hangs up after 10 seconds.
Can anyone help me understand if this idea is even workable?
Thanks... Thanks... so much Thanks.
OK for anyone else that lands here, I fixed it or rather un-broke it.
Notice that - from the examples - the returned status from _start / _cont calls are passed in as a parameter to the next _cont. Turns out this is critical.
The status contains flags MYSQL_WAIT_READ, MYSQL_WAIT_WRITE, MYSQL_WAIT_EXCEPT, MYSQL_WAIT_TIMEOUT, and if not passed to the next _cont my guess is you are messing with the _cont state-machine.
I was not saving the state of status between different places where _start and _cont were being called.
struct MC
{
MYSQL *mysql;
int status;
} MC;
...
// Initial call
mc->status = mysql_real_connect_start(&ret, mc->mysql, host, user, password, NULL, 0, NULL, 0);
// EPOLL raised calls.
mc->status = mysql_real_connect_cont(&ret, mc->mysql, mc->status);
if(mc->status) return... // keep waiting check for errors.

MmFile Empty Files throws Exception in Destructor

I'm having trouble getting MmFile to work in a directory scanning algorithm.
When I'm stress-testing it as follows
foreach (dent; dirEntries(..)) {
const size_t K = ...;
const ulong size = ...;
scope auto mf = new MmFile(dent.name, MmFile.Mode.read, size, null, win)
}
I can't find a combination of size and win that works for all cases when reading data.
When I set
const size = 0;
const win = 64*1024;
the length gets calculated correctly.
But when dent.name is an existing empty file it crashes in the destruction of the MMFile throwing a
core.exception.FinalizeError...std.exception.ErrnoException#std.mmfile.d(490): munmap failed (Invalid argument).
And I can't recover this error by catching core.exception.FinalizeError because its thrown in the destructor. I haven't tried
try { delete mm; } catch (core.exception.FinalizeError) { ; /* pass */}
Maybe that works.
Is this the default behavior when calling mmap in C on existing empty files?
If so I think that MmFile should check for this error during construction.
The except gets thrown also when I replace scope with an explicit delete.
For now I simply skip calling MmFile on empty files.
It sounds like a bug to me for MmFile to barf on empty files regardless of what mmap itself does. Please report it.
On a side note, I'd advise against using either scope or delete, as they're going to be removed from the language, because they're both unsafe. std.typecons.scoped replaces scope in this context if you want to do that (though it's still unsafe). And as for delete, destroy will destroy the object without freeing its memory, and core.memory can be used to free memory if you really want to, but in general, if you want to be worrying about freeing memory, then you should be manually managing your memory (with malloc and free and possibly emplace) and not using the GC at all.

mysql_use_result stomping over used memory Ansi-C

i got a problem and its driving me nuts.
in a function called cargo_id_whitelist(MYSQL * conexion,struct info * data)
i perform a mysql Query. but every time i call the mysql api funcion
mysql_use_res(conexion) it stomp over used memory, ruining data (mostly of the data structure)
example
printf("-kind-> %d \n",conf_var->next->next->id) //work its display the third node id info;
res=( MYSQL_RES *)mysql_use_result(conexion); //this break my memory
printf("puntero %p \n",res);
printf("-kind-> %d \n",conf_var->next->next->id); //segfault
conf_var is a linked list.
theres is something i need to know?
If, as in your comment, your code is as follows:
MYSQL *conn;
if (!mysql_real_connect(conn, blah, blah, blah)) {
return 1;
}
then you're breaking the rules and all bets are off. The MySQL documentation page for mysql_real_connect() states:
The first parameter should be the address of an existing MYSQL structure. Before calling mysql_real_connect() you must call mysql_init() to initialize the MYSQL structure.
The statement MYSQL *conn; (assuming it's not static storage duration) simply creates a pointer that points to an arbitrary location and, unless you init it, using it is likely to cause you a great deal of grief.
The fix is probably simply replacing:
MYSQL *conn;
with:
MYSQL *conn = mysql_init (NULL);
That will give you a new object, properly initialised, that you can then pass to mysql_real_connect().

org.hibernate.StaleObjectStateException when using Grails with PostgreSQL

I've written a grails service with the following code:
EPCGenerationMetadata requestEPCs(String indicatorDigit, FilterValue filterValue,
PartitionValue partitionValue, String companyPrefix, String itemReference,
Long quantity) throws IllegalArgumentException, IllegalStateException {
//... code
//problematic snippet bellow
def serialGenerator
synchronized(this) {
log.debug "Generating epcs..."
serialGenerator = SerialGenerator.findByItemReference(itemReference)
if(!serialGenerator) {
serialGenerator = new SerialGenerator(itemReference: itemReference, serialNumber: 0l)
}
startingPoint = serialGenerator.serialNumber + 1
serialGenerator.serialNumber += quantity
serialGenerator.save(flush: true)
}
//code continues...
}
Being a grails service a singleton by default, I thought I'd be safe from concurrent inconsistency by adding the synchronized block above. I've created a simple client for testing concurrency, as the service is exposed by http invoker. I ran multiple clients at the same time, passing as argument the same itemReference, and had no problems at all.
However, when I changed the database from MySQL to PostgreSQL 8.4, I couldn't handle concurrent access anymore. When running a single client, everything is fine. However, if I add one more client asking for the same itemReference, I get instantly a StaleObjectStateException:
Exception in thread "main" org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException: Object of class [br.com.app.epcserver.SerialGenerator] with identifier [10]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [br.com.app.epcserver.SerialGenerator#10]
at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:672)
at org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:411)
at org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at org.springframework.orm.hibernate3.HibernateTemplate.flush(HibernateTemplate.java:881)
at org.codehaus.groovy.grails.orm.hibernate.metaclass.SavePersistentMethod$1.doInHibernate(SavePersistentMethod.java:58)
(...)
at br.com.app.EPCGeneratorService.requestEPCs(EPCGeneratorService.groovy:63)
at br.com.app.epcclient.IEPCGenerator$requestEPCs.callCurrent(Unknown Source)
at br.com.app.epcserver.EPCGeneratorService.requestEPCs(EPCGeneratorService.groovy:29)
at br.com.app.epcserver.EPCGeneratorService$$FastClassByCGLIB$$15a2adc2.invoke()
(...)
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [br.com.app.epcserver.SerialGenerator#10]
Note: EPCGeneratorService.groovy:63 refers to serialGenerator.save(flush: true).
I don't know what to think, as the only thing that I've changed was the database. I'd appreciate any advice on the matter.
I'm using:
Grails 1.3.3
Postgres 8.4 (postgresql-8.4-702.jdbc4 driver)
JBoss 6.0.0-M4
MySQL:
mysqld Ver 5.1.41 (mysql-connector-java-5.1.13-bin driver)
Thanks in advance!
That's weird, try disabling transaction.
This is indeed a strange behavior, but you could try to workaround by using a "select ... for upgrade", via hibernate lock method.
Something like this:
def c = SerialGenerator.createCriteria()
serialgenerator = c.get {
eg "itemReferece", itemReference
lock true
}