Odin icon indicating copy to clipboard operation
Odin copied to clipboard

Global assignment via proc not functioning in DLL

Open thePHTest opened this issue 4 years ago • 7 comments
trafficstars

Context

DLL globals assigned via a proc in the DLL are set to 0. I am exporting a function and calling it from an exe via dynlib.load_library and dynlib.symbol_address . I can see the value of the global is 0 by passing a print proc to the dll from the exe. fmt.print and the console logger currently aren't working to print to stdout in the dll due to this bug I believe. Repro: https://github.com/thePHTest/odin-sandbox/tree/main

  • Operating System: Windows 10
  • Please paste odin version output: odin version dev-2021-08:b352b42a

Expected Behavior

globals can be assigned via a proc call when dynlib.load_library is used which calls DLLMain()

Current Behavior

DLL globals assigned via a proc in the DLL are set to 0.

Failure Information (for bugs)

Please help provide information about the failure if this is a bug. If it is not a bug, please remove the rest of this template.

Steps to Reproduce

Please provide detailed steps for reproducing the issue.

  1. Clone the repo: https://github.com/thePHTest/odin-sandbox/tree/main
  2. Run build_debug.bat
  3. Run sandbox_debug.bat

thePHTest avatar Aug 03 '21 19:08 thePHTest

I have confirmed that the function call for global assignment is at least being outputted to the dll via dumpbin. I wrote the assignment function like so to be able to search for the hex sequence and confirm as well as cross verify with a functioning c++ dll.

GlobalAssign::proc() -> u64 { return 0xa0a0a0a0a0a0a0a0; }

Now the question is why this isn't called from dllmain_crt_process_attach() like how it is done in the functioning c++ dll. I am able to break at dllmain_crt_process_attach in remedybg when the odin dll is loaded which I believe at least confirms win32.load_library_w is working as expected.

thePHTest avatar Aug 05 '21 20:08 thePHTest

See https://github.com/odin-lang/Odin/pull/1069 for a potential fix.

thePHTest avatar Aug 06 '21 17:08 thePHTest

Another victim:

Commit 0db86a0638d417583a042ea7b3c2e5304d653a17 exposed a bug in DLL global.

When compiling core:math/big as part of an EXE, initialize_constants(); gets called from the global scope, correctly setting globals including MUL_KARATSUBA_CUTOFF.

When compiled as a DLL, initialize_constants doesn't get called automatically. Even when manually calling the procedure, MUL_KARATSUBA_CUTOFF remains unset, which means that div calls recursive division for inputs it shouldn't handle.

  • Operating System:
  • Please paste odin version output: odin version dev-2021-08:3f29a0d6

Expected Behavior

I expect global calls to be executed in a DLL same as they would in an EXE, and for globals in a DLL to be modified correctly as they should.

Steps to Reproduce

Compile core:math/big as a DLL: odin build . -build-mode:shared -show-timings -o:speed -no-bounds-check Use the minrep to load and call it.

package minrep;

import "core:fmt";
import big "core:math/big"
import "core:dynlib"

Init_Proc :: proc "c" () -> u64;
Div_Proc  :: proc "c" (a, b: cstring) -> big.PyRes;

main :: proc() {

	biglib, loaded := dynlib.load_library("big.dll");
	fmt.printf("biglib: %v  | loaded: %v\n", biglib, loaded);
	assert(loaded);

	init_ptr, init_found := dynlib.symbol_address(biglib, "test_initialize_constants");
	fmt.printf("init_test_initialize_constants: %v | found:  %v\n", init_ptr, init_found);
	assert(init_found);

	div_ptr, div_found := dynlib.symbol_address(biglib, "test_div");
	fmt.printf("div_ptr: %v | found:  %v\n", div_ptr, div_found);
	assert(div_found);

	my_init := cast(Init_Proc)init_ptr;
	my_div  := cast(Div_Proc)div_ptr;

	a := cstring("9c40000000000044c00000000000079"); // 12980742146337069150589594264770969721
	b := cstring("4000000000000000");                // 4611686018427387904

	init_res := my_init();
	fmt.printf("init: %v\n", init_res);

	quotient := my_div(a, b);
	fmt.printf("my_div: %v\n", quotient);

	unloaded := dynlib.unload_library(biglib);
	fmt.printf("unloaded: %v\n", unloaded);
}

Kelimion avatar Aug 14 '21 14:08 Kelimion

I believe this is fixed by today's commit: https://github.com/odin-lang/Odin/commit/fb0a3ab7c14d4bc3b821cef723ec6ea3e956c956

Closing this issue,

thePHTest avatar Jan 12 '22 23:01 thePHTest

It's not fully fixed for *nix yet. I think I might have the wrong linker flags still, unfortunately. Getting the runtime to start correctly is really hard.

gingerBill avatar Jan 12 '22 23:01 gingerBill

Ah, I'll re-open this issue then if it helps for tracking. The current fix works for me on Windows.

thePHTest avatar Jan 12 '22 23:01 thePHTest

Hello!

I am marking this issue as stale as it has not received any engagement from the community or maintainers 120 days. That does not imply that the issue has no merit! If you feel strongly about this issue

  • open a PR referencing and resolving the issue;
  • leave a comment on it and discuss ideas how you could contribute towards resolving it;
  • leave a comment and describe in detail why this issue is critical for your use case;
  • open a new issue with updated details and a plan on resolving the issue.

The motivation for this automation is to help prioritize issues in the backlog and not ignore, reject, or belittle anyone..

github-actions[bot] avatar Jul 24 '22 21:07 github-actions[bot]