Bug Maria_Connect() FWH-24.07 64 bits ???
- Enrico Maria Giordano
- Posts: 8728
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
This is a very good question! I will investigate, than you for the idea.
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
Yes, it works fine.I would be extremely thankful if you kindly take a little more trouble by testing this variation.
This would help me to narrow down the problem
Thank you, Mr. Rao and Mr. Enrico, for your concern in solving this issue. It is very important for those of us who have chosen xHarbour and Maria_Connect for all our developments.
Saludos,
Carlos Gallego
*** FWH-24.07, xHarbour 1.3.1 Build 20240624, Borland C++7.70, PellesC ***
Carlos Gallego
*** FWH-24.07, xHarbour 1.3.1 Build 20240624, Borland C++7.70, PellesC ***
- Enrico Maria Giordano
- Posts: 8728
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
I've sent a private email to Ron and he has responded! He's very busy with a big project but he'll try to help us with this problem.
- nageswaragunupudi
- Posts: 10691
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Contact:
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
Only for xHarbour 64 bit users.It is very important for those of us who have chosen xHarbour and Maria_Connect for all our developments.
All others are working happily.
Regards
G. N. Rao.
Hyderabad, India
G. N. Rao.
Hyderabad, India
- nageswaragunupudi
- Posts: 10691
- Joined: Sun Nov 19, 2006 5:22 am
- Location: India
- Contact:
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
Testing further.
There are other FWH classes having DESTRUCTOR methods. I did not experience any problem with them. Not also with FWMariaConnection class.
The only problem is with FWMariaRowSet class.
My knowledge is limited.
I would seek the guidance of my seniors to go through the destructor method of rowset class and see what modifications can resolve the conflict, also keeping in view that the problem is only with 64 bits xHarbour.
There are other FWH classes having DESTRUCTOR methods. I did not experience any problem with them. Not also with FWMariaConnection class.
The only problem is with FWMariaRowSet class.
My knowledge is limited.
I would seek the guidance of my seniors to go through the destructor method of rowset class and see what modifications can resolve the conflict, also keeping in view that the problem is only with 64 bits xHarbour.
Regards
G. N. Rao.
Hyderabad, India
G. N. Rao.
Hyderabad, India
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
Does it mean that it's the end of the road for xHarbour, which is now a stagnant river?
Saludos,
Carlos Gallego
*** FWH-24.07, xHarbour 1.3.1 Build 20240624, Borland C++7.70, PellesC ***
Carlos Gallego
*** FWH-24.07, xHarbour 1.3.1 Build 20240624, Borland C++7.70, PellesC ***
- Enrico Maria Giordano
- Posts: 8728
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
Please compare the changelogs of Harbour and xHarbour. At least they are both "stagnant rivers".
Anyway, we are working to fix the problem. At this stage, it is not yet clear where the problem is, if in xHarbour or in FWH.
Anyway, we are working to fix the problem. At this stage, it is not yet clear where the problem is, if in xHarbour or in FWH.
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
I have same problem with xharbour and bcc 64 blits, searching internet i found:
The code you provided uses pointer arithmetic, which can behave differently between 32-bit and 64-bit environments. This is especially relevant when you deal with data structures that involve pointers, as the size of pointers differs between 32-bit and 64-bit systems (4 bytes vs. 8 bytes, respectively).
To make your code compatible with both 32-bit and 64-bit environments, you should address the following points:
1. Pointer Arithmetic Considerations
In 64-bit mode, the size of pointers is 8 bytes, so pointer arithmetic needs to account for this difference. The line:
cpp
Copy code
( s_pCurrBlock + 1 )
adds 1 to a pointer, which in C/C++ means it advances by the size of the object the pointer points to (based on the type of s_pCurrBlock).
2. Make Sure s_pCurrBlock is Correctly Sized
If s_pCurrBlock is a structure or class, ensure that the addition of 1 is appropriately aligned. Pointer arithmetic in C++ is based on the size of the object, so s_pCurrBlock + 1 will skip the size of the object.
For example:
In 32-bit mode: If sizeof(s_pCurrBlock) is 4 bytes, adding 1 will move the pointer by 4 bytes.
In 64-bit mode: If sizeof(s_pCurrBlock) is 8 bytes, adding 1 will move the pointer by 8 bytes.
3. Using uintptr_t for Portability
If you are working with pointer arithmetic in a way that needs to be independent of pointer size, you can cast to uintptr_t. This is a type that is guaranteed to be able to hold a pointer regardless of whether the platform is 32-bit or 64-bit.
The code you provided uses pointer arithmetic, which can behave differently between 32-bit and 64-bit environments. This is especially relevant when you deal with data structures that involve pointers, as the size of pointers differs between 32-bit and 64-bit systems (4 bytes vs. 8 bytes, respectively).
To make your code compatible with both 32-bit and 64-bit environments, you should address the following points:
1. Pointer Arithmetic Considerations
In 64-bit mode, the size of pointers is 8 bytes, so pointer arithmetic needs to account for this difference. The line:
cpp
Copy code
( s_pCurrBlock + 1 )
adds 1 to a pointer, which in C/C++ means it advances by the size of the object the pointer points to (based on the type of s_pCurrBlock).
2. Make Sure s_pCurrBlock is Correctly Sized
If s_pCurrBlock is a structure or class, ensure that the addition of 1 is appropriately aligned. Pointer arithmetic in C++ is based on the size of the object, so s_pCurrBlock + 1 will skip the size of the object.
For example:
In 32-bit mode: If sizeof(s_pCurrBlock) is 4 bytes, adding 1 will move the pointer by 4 bytes.
In 64-bit mode: If sizeof(s_pCurrBlock) is 8 bytes, adding 1 will move the pointer by 8 bytes.
3. Using uintptr_t for Portability
If you are working with pointer arithmetic in a way that needs to be independent of pointer size, you can cast to uintptr_t. This is a type that is guaranteed to be able to hold a pointer regardless of whether the platform is 32-bit or 64-bit.
Nicanor Martinez M.
Auditoria y Sistemas Ltda.
MicroExpress Ltda.
FW + FWH + XHARBOUR + HARBOUR + PELLES C + XDEVSTUDIO + XEDIT + BCC + VC_X86 + VCC_X64 + MINGW + R&R Reports + FastReport + Tdolphin + ADO + MYSQL + MARIADB + ORACLE
nnicanor@yahoo.com
Auditoria y Sistemas Ltda.
MicroExpress Ltda.
FW + FWH + XHARBOUR + HARBOUR + PELLES C + XDEVSTUDIO + XEDIT + BCC + VC_X86 + VCC_X64 + MINGW + R&R Reports + FastReport + Tdolphin + ADO + MYSQL + MARIADB + ORACLE
nnicanor@yahoo.com
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
Hi,
Error is not related with FWMARIA it is related with xharbour, my program uses TDolphin and closes unexpectly not only reading mysql data with those errors in evenlogs,
Abortada conexión 66 para db: 'wadmonbq' usuario: 'wadmon_admin' servidor: 'localhost' (Obtenido un error leyendo paquetes de comunicación)
For more information, see Help and Support Center at http://www.mysql.com.
Nombre de la aplicación con errores: SQLWAdmonXBC64.EXE, versión: 3.0.0.1, marca de tiempo: 0x00000000
Nombre del módulo con errores: SQLWAdmonXBC64.EXE, versión: 3.0.0.1, marca de tiempo: 0x00000000
Código de excepción: 0xc0000005
Desplazamiento de errores: 0x00000000000e2074
Identificador del proceso con errores: 0xb32c
Hora de inicio de la aplicación con errores: 0x01db0e2fd5323833
Ruta de acceso de la aplicación con errores: H:\ProyectosFW\SQLWadmon\bin64\SQLWAdmonXBC64.EXE
Ruta de acceso del módulo con errores: H:\ProyectosFW\SQLWadmon\bin64\SQLWAdmonXBC64.EXE
Identificador del informe: 4a7c231f-8ea1-4368-82d3-6b47a408f9e6
Nombre completo del paquete con errores:
Identificador de aplicación relativa del paquete con errores:
Error is not related with FWMARIA it is related with xharbour, my program uses TDolphin and closes unexpectly not only reading mysql data with those errors in evenlogs,
Abortada conexión 66 para db: 'wadmonbq' usuario: 'wadmon_admin' servidor: 'localhost' (Obtenido un error leyendo paquetes de comunicación)
For more information, see Help and Support Center at http://www.mysql.com.
Nombre de la aplicación con errores: SQLWAdmonXBC64.EXE, versión: 3.0.0.1, marca de tiempo: 0x00000000
Nombre del módulo con errores: SQLWAdmonXBC64.EXE, versión: 3.0.0.1, marca de tiempo: 0x00000000
Código de excepción: 0xc0000005
Desplazamiento de errores: 0x00000000000e2074
Identificador del proceso con errores: 0xb32c
Hora de inicio de la aplicación con errores: 0x01db0e2fd5323833
Ruta de acceso de la aplicación con errores: H:\ProyectosFW\SQLWadmon\bin64\SQLWAdmonXBC64.EXE
Ruta de acceso del módulo con errores: H:\ProyectosFW\SQLWadmon\bin64\SQLWAdmonXBC64.EXE
Identificador del informe: 4a7c231f-8ea1-4368-82d3-6b47a408f9e6
Nombre completo del paquete con errores:
Identificador de aplicación relativa del paquete con errores:
Nicanor Martinez M.
Auditoria y Sistemas Ltda.
MicroExpress Ltda.
FW + FWH + XHARBOUR + HARBOUR + PELLES C + XDEVSTUDIO + XEDIT + BCC + VC_X86 + VCC_X64 + MINGW + R&R Reports + FastReport + Tdolphin + ADO + MYSQL + MARIADB + ORACLE
nnicanor@yahoo.com
Auditoria y Sistemas Ltda.
MicroExpress Ltda.
FW + FWH + XHARBOUR + HARBOUR + PELLES C + XDEVSTUDIO + XEDIT + BCC + VC_X86 + VCC_X64 + MINGW + R&R Reports + FastReport + Tdolphin + ADO + MYSQL + MARIADB + ORACLE
nnicanor@yahoo.com
- Enrico Maria Giordano
- Posts: 8728
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
Thank you for the info. I dug down the crash here:
It is inside the function hb_clsFinalize() that is in classes.c:
https://github.com/xHarbour-org/xharbou ... es.c#L4076
Can you help me to find the problem, please?
Code: Select all | Expand
hb_vmPushSymbol( pDestructor );
hb_vmPush( pObject ); /* Do NOT Forward!!! */
hb_vmSend( 0 ); <-- CRASH HERE!
https://github.com/xHarbour-org/xharbou ... es.c#L4076
Can you help me to find the problem, please?
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
Hi,
This can help
To resolve the issue you're encountering when running the code in Borland C 64-bit, which fails at the `hb_vmSend( 0 );` call, the problem likely arises from differences in memory handling and data types between 32-bit and 64-bit environments. Here are several approaches to debug and potentially avoid the crash:
### 1. **Check Data Types**
The first step is to ensure that the data types you're using are compatible between 32-bit and 64-bit environments. For example, `USHORT`, `BOOL`, and other types may have different sizes in a 64-bit system. Consider replacing `USHORT` with `UINT16` or using fixed-size types from `<stdint.h>` (like `uint16_t`), which will work correctly on both architectures.
### 2. **Review Pointer Usage**
In 64-bit environments, pointers are larger (64-bit compared to 32-bit in 32-bit environments). Review how pointers such as `PHB_ITEM` and `PHB_SYMB` are handled, ensuring there are no pointer truncation issues. Make sure you're not inadvertently casting between 32-bit and 64-bit values, which could lead to problems.
### 3. **Check Stack State**
The `hb_vmSend()` function relies on the state of the Harbour VM stack. Ensure that the stack is in a valid state before invoking `hb_vmSend(0)`. Use debugging tools to verify that the objects being pushed onto the stack (like `pDestructor` and `pObject`) are correct and in the right order. Specifically:
- Ensure that `pDestructor` is valid and not `NULL` before calling `hb_vmSend(0)`.
- Check that `pObject` is a valid reference to a Harbour object.
### 4. **Destructor Control**
In the part of your code controlling whether destructors are enabled:
You might want to add more thorough checks, such as verifying that the stack is indeed ready using `hb_stack_ready`.
### 5. **Error Handling Around `hb_vmSend()`**
To capture more details about the failure, you can add more explicit error checking before calling `hb_vmSend()`. For example:
### 6. **Verify `hb_vmSend()` Compatibility**
Make sure that the `hb_vmSend()` function implementation is 64-bit compatible and that it’s not performing operations that are specific to 32-bit environments (like assuming fixed data sizes).
### 7. **Compile with Correct Flags**
Ensure that you're compiling the code with the correct flags for 64-bit. In Borland C, make sure you're using the proper flags to compile for 64-bit, like `-m64` (if applicable), and avoid flags that might force 32-bit compilation.
### 8. **Debug with 64-bit Tools**
Use a 64-bit debugger to analyze memory and stack state right before the `hb_vmSend(0)` call. This can help identify whether the crash is due to a stack overflow, invalid memory access, or another issue specific to 64-bit execution.
By following these steps, you should be able to narrow down the cause of the crash and adjust your code accordingly to work properly in the 64-bit Borland C environment.
This can help
To resolve the issue you're encountering when running the code in Borland C 64-bit, which fails at the `hb_vmSend( 0 );` call, the problem likely arises from differences in memory handling and data types between 32-bit and 64-bit environments. Here are several approaches to debug and potentially avoid the crash:
### 1. **Check Data Types**
The first step is to ensure that the data types you're using are compatible between 32-bit and 64-bit environments. For example, `USHORT`, `BOOL`, and other types may have different sizes in a 64-bit system. Consider replacing `USHORT` with `UINT16` or using fixed-size types from `<stdint.h>` (like `uint16_t`), which will work correctly on both architectures.
### 2. **Review Pointer Usage**
In 64-bit environments, pointers are larger (64-bit compared to 32-bit in 32-bit environments). Review how pointers such as `PHB_ITEM` and `PHB_SYMB` are handled, ensuring there are no pointer truncation issues. Make sure you're not inadvertently casting between 32-bit and 64-bit values, which could lead to problems.
### 3. **Check Stack State**
The `hb_vmSend()` function relies on the state of the Harbour VM stack. Ensure that the stack is in a valid state before invoking `hb_vmSend(0)`. Use debugging tools to verify that the objects being pushed onto the stack (like `pDestructor` and `pObject`) are correct and in the right order. Specifically:
- Ensure that `pDestructor` is valid and not `NULL` before calling `hb_vmSend(0)`.
- Check that `pObject` is a valid reference to a Harbour object.
### 4. **Destructor Control**
In the part of your code controlling whether destructors are enabled:
Code: Select all | Expand
if( s_AllowDestructors /* && hb_stack_ready */ )
### 5. **Error Handling Around `hb_vmSend()`**
To capture more details about the failure, you can add more explicit error checking before calling `hb_vmSend()`. For example:
Code: Select all | Expand
if (pDestructor && pObject)
{
hb_vmPushSymbol(pDestructor);
hb_vmPush(pObject); /* Do NOT Forward!!! */
if (!hb_vmSend(0))
{
// Error handling here, log more details if needed
hb_errInternal(HB_EI_ERRUNRECOV, "Error in hb_vmSend on Borland C 64", NULL, NULL);
}
}
else
{
// Log errors if pDestructor or pObject are invalid
hb_errInternal(HB_EI_ERRUNRECOV, "pDestructor or pObject invalid in Borland C 64", NULL, NULL);
}
Make sure that the `hb_vmSend()` function implementation is 64-bit compatible and that it’s not performing operations that are specific to 32-bit environments (like assuming fixed data sizes).
### 7. **Compile with Correct Flags**
Ensure that you're compiling the code with the correct flags for 64-bit. In Borland C, make sure you're using the proper flags to compile for 64-bit, like `-m64` (if applicable), and avoid flags that might force 32-bit compilation.
### 8. **Debug with 64-bit Tools**
Use a 64-bit debugger to analyze memory and stack state right before the `hb_vmSend(0)` call. This can help identify whether the crash is due to a stack overflow, invalid memory access, or another issue specific to 64-bit execution.
By following these steps, you should be able to narrow down the cause of the crash and adjust your code accordingly to work properly in the 64-bit Borland C environment.
Nicanor Martinez M.
Auditoria y Sistemas Ltda.
MicroExpress Ltda.
FW + FWH + XHARBOUR + HARBOUR + PELLES C + XDEVSTUDIO + XEDIT + BCC + VC_X86 + VCC_X64 + MINGW + R&R Reports + FastReport + Tdolphin + ADO + MYSQL + MARIADB + ORACLE
nnicanor@yahoo.com
Auditoria y Sistemas Ltda.
MicroExpress Ltda.
FW + FWH + XHARBOUR + HARBOUR + PELLES C + XDEVSTUDIO + XEDIT + BCC + VC_X86 + VCC_X64 + MINGW + R&R Reports + FastReport + Tdolphin + ADO + MYSQL + MARIADB + ORACLE
nnicanor@yahoo.com
- Enrico Maria Giordano
- Posts: 8728
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
I don't need AI response, I need a real help.
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
More information it maybe help
To optimize the function and avoid unexpected crashes in Borland C 64-bit, you can take a methodical approach focusing on improving type safety, error handling, and ensuring compatibility with the 64-bit architecture. Here are specific optimizations you can apply:
### 1. **Improve Type Safety**
Make sure that all data types are correctly sized for a 64-bit environment. This is especially important for types like `USHORT`, `BOOL`, and pointers. Use fixed-size types from `<stdint.h>` to guarantee consistency across different platforms. For example:
- Replace `USHORT` with `uint16_t`.
- Ensure that pointer types (like `PHB_ITEM` and `PHB_SYMB`) are correctly defined for 64-bit.
### 2. **Validate Pointers Before Access**
In 64-bit, pointer mismanagement is a common source of crashes. Before accessing or using any pointers, ensure they are valid by checking for `NULL` or other invalid states. For example:
This ensures you avoid dereferencing invalid pointers.
### 3. **Use Robust Error Handling**
Ensure robust error handling around critical operations, particularly where you're interacting with the Harbour VM and using stack-based operations (`hb_vmSend`). Add more comprehensive error checks before calling these functions:
This ensures that if something fails during `hb_vmSend(0)`, the failure is handled gracefully rather than causing a crash.
### 4. **Minimize Stack Usage**
The Harbour VM stack could be another point of failure, especially if it becomes corrupted or misaligned. Minimize direct stack manipulations unless necessary. Check the stack state before and after every operation involving the stack (`hb_stackPush()`, `hb_stackPopState()`).
Ensure the stack is not too deeply nested, as excessive nesting can cause a stack overflow in 64-bit:
[/code]
if (hb_stackBaseItem() == NULL || hb_stackSelfItem() == NULL)
{
// Handle stack corruption or invalid stack state
hb_errInternal(HB_EI_ERRUNRECOV, "Invalid stack state", NULL, NULL);
return;
}
[/code]
### 5. **Disable/Enable Garbage Collection Wisely**
The function disables garbage collection (`hb_gcSetCollecting(TRUE)`) during the destructor call. Be very cautious when disabling and re-enabling garbage collection, and ensure it is balanced and applied correctly. If the destructor fails unexpectedly, you want to make sure the garbage collection state is restored properly:
### 6. **Isolate Problematic Sections**
If you know where the crash is likely happening (for example, around `hb_vmSend(0)`), isolate that code into a separate function and handle exceptions locally, so they don't propagate and crash the entire program. You can use structured exception handling (`try/catch`) or equivalent mechanisms in your environment to catch and handle failures gracefully.
### 7. **Check Compatibility with 64-bit Stack Size**
Borland C 64-bit environments handle the stack differently from 32-bit. Make sure you aren't inadvertently exceeding the stack size or encountering memory alignment issues. If necessary, allocate large objects on the heap instead of the stack.
This ensures that larger objects are safely allocated in heap memory, which can handle bigger allocations in 64-bit environments.
### 8. **Compile with Appropriate Flags**
Ensure that your project is being compiled with the correct flags for 64-bit support. These flags ensure correct memory alignment, stack size, and handling of pointers. In Borland C, use the following:
- `-m64`: For 64-bit compilation.
- Ensure optimization flags are enabled for error checking (e.g., `-O2` for optimization, `-g` for debugging).
- If available, enable additional warning levels to catch potential issues at compile time (`-Wall` or equivalent).
### 9. **Use 64-bit Debugging Tools**
Utilize 64-bit debugging tools to check memory, stack, and pointers during runtime. Tools such as Valgrind (for memory checks), gdb (for stack traces), or specialized 64-bit debuggers in Borland C++ can help identify the exact source of the crash.
### Final Optimized Example:
By following these steps, you can improve the robustness of your function and reduce the likelihood of unexpected crashes in Borland C 64-bit.
Alterantive function by claude maybe help:
To optimize the function and avoid unexpected crashes in Borland C 64-bit, you can take a methodical approach focusing on improving type safety, error handling, and ensuring compatibility with the 64-bit architecture. Here are specific optimizations you can apply:
### 1. **Improve Type Safety**
Make sure that all data types are correctly sized for a 64-bit environment. This is especially important for types like `USHORT`, `BOOL`, and pointers. Use fixed-size types from `<stdint.h>` to guarantee consistency across different platforms. For example:
- Replace `USHORT` with `uint16_t`.
- Ensure that pointer types (like `PHB_ITEM` and `PHB_SYMB`) are correctly defined for 64-bit.
Code: Select all | Expand
#include <stdint.h> // for uint16_t
void hb_clsFinalize( PHB_ITEM pObject )
{
HB_THREAD_STUB
uint16_t uiClass; // Changed from USHORT to uint16_t
if( HB_IS_OBJECT( pObject ) )
uiClass = pObject->item.asArray.value->uiClass;
else
return;
In 64-bit, pointer mismanagement is a common source of crashes. Before accessing or using any pointers, ensure they are valid by checking for `NULL` or other invalid states. For example:
Code: Select all | Expand
if (pObject == NULL || pObject->item.asArray.value == NULL)
{
// Log or handle the error
return;
}
### 3. **Use Robust Error Handling**
Ensure robust error handling around critical operations, particularly where you're interacting with the Harbour VM and using stack-based operations (`hb_vmSend`). Add more comprehensive error checks before calling these functions:
Code: Select all | Expand
if (pClass->pDestructor && pObject)
{
hb_vmPushSymbol(pClass->pDestructor->pMessage->pSymbol);
hb_vmPush(pObject);
// Add error handling for hb_vmSend
if (!hb_vmSend(0)) // Handle the case where hb_vmSend fails
{
hb_errInternal(HB_EI_ERRUNRECOV, "hb_vmSend failed", NULL, NULL);
return;
}
}
else
{
hb_errInternal(HB_EI_ERRUNRECOV, "Invalid destructor or object", NULL, NULL);
}
### 4. **Minimize Stack Usage**
The Harbour VM stack could be another point of failure, especially if it becomes corrupted or misaligned. Minimize direct stack manipulations unless necessary. Check the stack state before and after every operation involving the stack (`hb_stackPush()`, `hb_stackPopState()`).
Ensure the stack is not too deeply nested, as excessive nesting can cause a stack overflow in 64-bit:
[/code]
if (hb_stackBaseItem() == NULL || hb_stackSelfItem() == NULL)
{
// Handle stack corruption or invalid stack state
hb_errInternal(HB_EI_ERRUNRECOV, "Invalid stack state", NULL, NULL);
return;
}
[/code]
### 5. **Disable/Enable Garbage Collection Wisely**
The function disables garbage collection (`hb_gcSetCollecting(TRUE)`) during the destructor call. Be very cautious when disabling and re-enabling garbage collection, and ensure it is balanced and applied correctly. If the destructor fails unexpectedly, you want to make sure the garbage collection state is restored properly:
Code: Select all | Expand
BOOL bCollecting = hb_gcSetCollecting(TRUE);
PHB_SYMB pDestructor = pClass->pDestructor->pMessage->pSymbol;
// Handle errors during destructor execution
if (pDestructor)
{
hb_vmPushSymbol(pDestructor);
hb_vmPush(pObject);
hb_vmSend(0);
}
hb_gcSetCollecting(bCollecting); // Ensure GC is reset even after errors
If you know where the crash is likely happening (for example, around `hb_vmSend(0)`), isolate that code into a separate function and handle exceptions locally, so they don't propagate and crash the entire program. You can use structured exception handling (`try/catch`) or equivalent mechanisms in your environment to catch and handle failures gracefully.
### 7. **Check Compatibility with 64-bit Stack Size**
Borland C 64-bit environments handle the stack differently from 32-bit. Make sure you aren't inadvertently exceeding the stack size or encountering memory alignment issues. If necessary, allocate large objects on the heap instead of the stack.
Code: Select all | Expand
PHB_ITEM* pObjectCopy = (PHB_ITEM*)malloc(sizeof(PHB_ITEM));
if (pObjectCopy == NULL)
{
// Handle memory allocation failure
return;
}
memcpy(pObjectCopy, pObject, sizeof(PHB_ITEM));
### 8. **Compile with Appropriate Flags**
Ensure that your project is being compiled with the correct flags for 64-bit support. These flags ensure correct memory alignment, stack size, and handling of pointers. In Borland C, use the following:
- `-m64`: For 64-bit compilation.
- Ensure optimization flags are enabled for error checking (e.g., `-O2` for optimization, `-g` for debugging).
- If available, enable additional warning levels to catch potential issues at compile time (`-Wall` or equivalent).
### 9. **Use 64-bit Debugging Tools**
Utilize 64-bit debugging tools to check memory, stack, and pointers during runtime. Tools such as Valgrind (for memory checks), gdb (for stack traces), or specialized 64-bit debuggers in Borland C++ can help identify the exact source of the crash.
### Final Optimized Example:
Code: Select all | Expand
void hb_clsFinalize( PHB_ITEM pObject )
{
HB_THREAD_STUB
uint16_t uiClass;
if (!pObject || !HB_IS_OBJECT(pObject) || !pObject->item.asArray.value) {
// Handle invalid object
return;
}
uiClass = pObject->item.asArray.value->uiClass;
if (uiClass && uiClass <= s_uiClasses)
{
PCLASS pClass = s_pClasses + (uiClass - 1);
if (pClass->pDestructor)
{
if (pClass->uiScope & HB_OO_CLS_DESTRUC_SYMB)
{
assert(hb_stack_ready);
if (s_AllowDestructors)
{
if (hb_stackBaseItem() && hb_stackSelfItem() && strcmp(hb_stackBaseItem()->item.asSymbol.value->szName, "__CLSINSTSUPER"))
{
BOOL bCollecting = hb_gcSetCollecting(TRUE);
PHB_SYMB pDestructor = pClass->pDestructor->pMessage->pSymbol;
if (pDestructor && pObject)
{
hb_vmPushSymbol(pDestructor);
hb_vmPush(pObject);
// Call destructor and handle errors
if (!hb_vmSend(0))
{
hb_errInternal(HB_EI_ERRUNRECOV, "Error in hb_vmSend", NULL, NULL);
}
}
hb_gcSetCollecting(bCollecting);
}
}
else
{
hb_errInternal(HB_EI_ERRUNRECOV, "Destructors disabled!", pClass->szName, NULL);
}
}
}
}
}
By following these steps, you can improve the robustness of your function and reduce the likelihood of unexpected crashes in Borland C 64-bit.
Alterantive function by claude maybe help:
Code: Select all | Expand
B_BOOL hb_vm_ready( void )
{
/* Verificar si la pila de la máquina virtual está inicializada */
if( !hb_stack_ready )
{
return HB_FALSE;
}
/* Verificar si el puntero de la máquina virtual es válido */
if( hb_vm_ptr() == NULL )
{
return HB_FALSE;
}
/* Verificar si el área de memoria de la máquina virtual está inicializada */
if( hb_vmMemoryPtr() == NULL )
{
return HB_FALSE;
}
/* Puedes agregar más verificaciones aquí si es necesario */
return HB_TRUE;
}
void hb_clsFinalize( PHB_ITEM pObject )
{
HB_THREAD_STUB
USHORT uiClass;
if( HB_IS_OBJECT( pObject ) )
uiClass = pObject->item.asArray.value->uiClass;
else
return;
if( uiClass && uiClass <= s_uiClasses )
{
PCLASS pClass = s_pClasses + ( uiClass - 1 );
if( pClass->pDestructor )
{
if( pClass->uiScope & HB_OO_CLS_DESTRUC_SYMB )
{
assert( hb_stack_ready );
if( s_AllowDestructors )
{
if( HB_IS_SYMBOL( hb_stackBaseItem() ) &&
( hb_stackBaseItem()->item.asSymbol.pCargo->uiSuperClass == 0 ||
( USHORT ) hb_stackBaseItem()->item.asSymbol.pCargo->uiSuperClass != uiClass ||
( HB_IS_ARRAY( hb_stackSelfItem() ) &&
hb_stackSelfItem()->item.asArray.value != pObject->item.asArray.value ) ) &&
strcmp( hb_stackBaseItem()->item.asSymbol.value->szName, "__CLSINSTSUPER" ) )
{
BOOL bCollecting = hb_gcSetCollecting( TRUE ), bPop = TRUE;
PHB_SYMB pDestructor = pClass->pDestructor->pMessage->pSymbol;
if( HB_IS_ARRAY( &HB_VM_STACK.Return ) &&
HB_VM_STACK.Return.item.asArray.value == pObject->item.asArray.value )
{
bPop = FALSE;
hb_stackPush();
}
else
hb_vmPushState();
hb_vmPushSymbol( pDestructor );
hb_vmPush( pObject );
#ifdef __BORLANDC__
#if __BORLANDC__ > 0x0580 // Ajusta este valor según la versión de Borland C 64-bit
// Alternativa para 64-bit
if (hb_vm_ready()) // Asume que existe una función como esta
{
// Llama directamente al destructor si es posible
if (pDestructor && pDestructor->value)
{
pDestructor->value(pObject);
}
else
{
// Registra un error o maneja la situación de otra manera
hb_errInternal(HB_EI_ERRUNRECOV, "Unable to call destructor", NULL, NULL);
}
}
else
{
hb_errInternal(HB_EI_ERRUNRECOV, "Harbour VM not ready", NULL, NULL);
}
#else
hb_vmSend( 0 );
#endif
#else
hb_vmSend( 0 );
#endif
if( bPop )
hb_vmPopState();
else
hb_stackDec();
hb_gcSetCollecting( bCollecting );
}
}
else
hb_errInternal( HB_EI_ERRUNRECOV, "Destructors disabled! Destructor of class: '%s' can't be executed.", pClass->szName, NULL );
}
}
}
}
Nicanor Martinez M.
Auditoria y Sistemas Ltda.
MicroExpress Ltda.
FW + FWH + XHARBOUR + HARBOUR + PELLES C + XDEVSTUDIO + XEDIT + BCC + VC_X86 + VCC_X64 + MINGW + R&R Reports + FastReport + Tdolphin + ADO + MYSQL + MARIADB + ORACLE
nnicanor@yahoo.com
Auditoria y Sistemas Ltda.
MicroExpress Ltda.
FW + FWH + XHARBOUR + HARBOUR + PELLES C + XDEVSTUDIO + XEDIT + BCC + VC_X86 + VCC_X64 + MINGW + R&R Reports + FastReport + Tdolphin + ADO + MYSQL + MARIADB + ORACLE
nnicanor@yahoo.com
- Enrico Maria Giordano
- Posts: 8728
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
Keep in mind that all is working fine using MSC64, so the problem can't be something related to 64 bit handling. And moreover, I can't trap the crash because the call to hb_vmSend( 0 ) crashes che program and never returns. And I cannot use try/catch, we are using C not C++ in this module.
- Enrico Maria Giordano
- Posts: 8728
- Joined: Thu Oct 06, 2005 8:17 pm
- Location: Roma - Italia
- Contact:
Re: Bug Maria_Connect() FWH-24.07 64 bits ???
I found this in fwmaria.prg:
Consider that MSVC32 is never defined, so why that code? When I try the sample with MSC32 I get:
Code: Select all | Expand
#ifdef MSVC32
#define NXS_MAX_KEYLEN 256
static void nxs_crypt(
const unsigned char * source, HB_SIZE srclen,
const unsigned char * key, HB_SIZE keylen,
unsigned char * cipher );
static void nxs_scramble(
const unsigned char * source, HB_SIZE srclen,
const unsigned char * key, HB_SIZE keylen,
unsigned char * cipher );
static void nxs_partial_scramble(
const unsigned char * source, unsigned char * cipher,
HB_ISIZ * scramble,
HB_SIZE len, HB_SIZE keylen );
static void nxs_xorcode(
unsigned char * cipher, HB_SIZE cipherlen,
const unsigned char * key, HB_SIZE keylen );
static void nxs_xorcyclic(
unsigned char * cipher, HB_SIZE cipherlen,
const unsigned char * key, HB_SIZE keylen );
static HB_U32 nxs_cyclic_sequence( HB_U32 input );
static void nxs_make_scramble(
HB_ISIZ * scramble,
const unsigned char * key,
HB_SIZE keylen );
#else
void nxs_crypt(
const unsigned char *source, HB_SIZE srclen,
const unsigned char *key, HB_SIZE keylen,
unsigned char *cipher );
#endif
Code: Select all | Expand
error LNK2019: unresolved external symbol _nxs_crypt referenced in function _HB_FUN_MYSQL_CRYPT