Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono] Make mono_inst_name less misleading #83545

Closed
lambdageek opened this issue Mar 16, 2023 · 7 comments · Fixed by #91042
Closed

[mono] Make mono_inst_name less misleading #83545

lambdageek opened this issue Mar 16, 2023 · 7 comments · Fixed by #91042
Labels
area-VM-meta-mono good first issue Issue should be easy to implement, good for first-time contributors help wanted [up-for-grabs] Good issue for external contributors in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@lambdageek
Copy link
Member

lambdageek commented Mar 16, 2023

Currently mono_inst_name is defined like this:

const char*
mono_inst_name (int op) {
#ifndef DISABLE_LOGGING
	if (op >= OP_LOAD && op <= OP_LAST)
		return (const char*)&opstr + opidx [op - OP_LOAD];
	if (op < OP_LOAD)
		return mono_opcode_name (op);
	g_error ("unknown opcode name for %d", op);
	return NULL;
#else
	g_error ("unknown opcode name for %d", op);
	g_assert_not_reached ();
#endif
}

The problem is that when logging is disabled, this function is uncallable (the #else branch, above). Any call to it will crash the runtime.

On Android, iOS and WASM we build the runtime with DISABLE_LOGGING defined. Below is Android, but wasm and ios are similar:

      <_MonoCMakeArgs Include="-DENABLE_MINIMAL=ssa,logging" />

Why this is bad:

If someone incorrectly leaves in a call to mono_inst_name in a branch that isn't guarded by #ifndef DISABLE_LOGGING, the runtime will crash. We tend to use mono_inst_name in code that is trying to provide additional diagnostics. So something bad has already happened, we try to gather more info, and instead we crash the runtime.

What we should do instead:

Wrap both the declaration and definition of mono_inst_name in #ifndef DISABLE_LOGGING. Turn any use of mono_inst_name that isn't protected by #ifndef DISABLE_LOGGING into a compile-time error that will fail to build the runtime.

That way, we don't get random crashes during unrelated investigations just because we called some diagnostic functionality

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Mar 16, 2023
@lambdageek lambdageek removed the untriaged New issue has not been triaged by the area owner label Mar 16, 2023
@lambdageek lambdageek added this to the 8.0.0 milestone Mar 16, 2023
@lambdageek
Copy link
Member Author

/cc @steveisok @SamMonoRT

@lambdageek
Copy link
Member Author

luckily mono_inst_name isn't in the public API. so we can mess with its declaration

@lambdageek lambdageek added good first issue Issue should be easy to implement, good for first-time contributors help wanted [up-for-grabs] Good issue for external contributors labels Mar 16, 2023
@sayeedkhannabil
Copy link
Contributor

Hi, I'm Abu Sayeed Khan, a final year computer science student. I came across this issue, and I think it's a great opportunity for me to learn more about dotnet. I'm interested in working on this issue, and I'd appreciate any guidance or advice you can provide. Thank you!

@sayeedkhannabil
Copy link
Contributor

Is it okay to define a dummy macro to create compilation error? Something like this:

#ifndef DISABLE_LOGGING
const char* mono_inst_name (int op);
#else
#define mono_inst_name(op) _static_assert_disabled_logging()
static inline void _static_assert_disabled_logging(void)
{
    static_assert(0, "mono_inst_name is not available when DISABLE_LOGGING is defined.");
}
#endif

@lambdageek
Copy link
Member Author

I'm interested in working on this issue, and I'd appreciate any guidance or advice you can provide.

Sure, give it a go. Thanks for helping us!

Is it okay to define a dummy macro to create compilation error? Something like this:

#ifndef DISABLE_LOGGING
const char* mono_inst_name (int op);
#else
#define mono_inst_name(op) _static_assert_disabled_logging()
static inline void _static_assert_disabled_logging(void)
{
    static_assert(0, "mono_inst_name is not available when DISABLE_LOGGING is defined.");
}
#endif

I don't think we need a specialized assertion. Just something like this is enough:

/* in mini.h */
....
#ifndef DISABLE_LOGGING
const char *mono_inst_name (int op);
#endif

The C compiler should error if some code in another file tries to call mono_inst_name when it's undefined.

We compile mono as C99, so static_assert is not available to us. (but it's possible to emulate it with C tricks, so that's not really a total dealbreaker).

The actual issue is, I don't think using a static_assert will work here: it will make the definition of _static_assert_disabled_logging fail to compile even if noone calls it. We would need to make mono_inst_name a macro that expands to a some kind of compilation error. Perhaps something like

#define mono_inst_name(op) _STATIC_COMPILE_ERROR("Not available with DISABLED_LOGGING")

#define _STATIC_COMPILE_ERROR(msg) extern void _fail_the_build(int [sizeof(char[-2])] )

if I call mono_inst_name(123), for me clang and gcc both produce an error like this, which is probably good enough:

$ clang -std=c99 -c foo.c -DFAILME
foo.c:19:2: error: array size is negative
        mono_inst_name(123);
        ^~~~~~~~~~~~~~~~~
foo.c:5:28: note: expanded from macro 'mono_inst_name'
#define mono_inst_name(op) _STATIC_COMPILE_ERROR("Not available with DISABLED_LOGGING")
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
foo.c:7:81: note: expanded from macro '_STATIC_COMPILE_ERROR'
#define _STATIC_COMPILE_ERROR(msg) extern void _fail_the_build(int [sizeof(char[-2])] )
                                                                                ^~
1 error generated.
$ gcc -std=c99 -c foo.c -DFAILME
foo.c: In function ‘main’:
foo.c:7:80: error: size of unnamed array is negative
    7 | #define _STATIC_COMPILE_ERROR(msg) extern void _fail_the_build(int [sizeof(char[-2])] )
      |                                                                                ^
foo.c:5:28: note: in expansion of macro ‘_STATIC_COMPILE_ERROR’
    5 | #define mono_inst_name(op) _STATIC_COMPILE_ERROR("Not available with DISABLED_LOGGING")
      |                            ^~~~~~~~~~~~~~~~~~~~~
foo.c:19:9: note: in expansion of macro ‘mono_inst_name’
   19 |         mono_inst_name(123);
      |         ^~~~~~~~~~~~~~

@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Mar 17, 2023
@akoeplinger
Copy link
Member

Wouldn't it be easier to change mono_inst_name to return the opcode integer value as string instead in the DISABLE_LOGGING case so we don't need to change every caller?

We also seem to be embedding CIL opcodes in mono_opcode_name still since we don't have DISABLE_LOGGING there.

@SamMonoRT
Copy link
Member

Moving this to 9.0.0

@SamMonoRT SamMonoRT modified the milestones: 8.0.0, 9.0.0 Aug 11, 2023
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Aug 23, 2023
sayeedkhannabil added a commit to sayeedkhannabil/runtime that referenced this issue Aug 24, 2023
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Aug 24, 2023
sayeedkhannabil added a commit to sayeedkhannabil/runtime that referenced this issue Aug 28, 2023
akoeplinger added a commit that referenced this issue Apr 9, 2024
Fixes #83545

Co-authored-by: Aleksey Kliger (λgeek) <akliger@gmail.com>
Co-authored-by: Steve Pfister <stpfiste@microsoft.com>
Co-authored-by: Alexander Köplinger <alex.koeplinger@outlook.com>
matouskozak pushed a commit to matouskozak/runtime that referenced this issue Apr 30, 2024
Fixes dotnet#83545

Co-authored-by: Aleksey Kliger (λgeek) <akliger@gmail.com>
Co-authored-by: Steve Pfister <stpfiste@microsoft.com>
Co-authored-by: Alexander Köplinger <alex.koeplinger@outlook.com>
@github-actions github-actions bot locked and limited conversation to collaborators May 10, 2024
Ruihan-Yin pushed a commit to Ruihan-Yin/runtime that referenced this issue May 30, 2024
Fixes dotnet#83545

Co-authored-by: Aleksey Kliger (λgeek) <akliger@gmail.com>
Co-authored-by: Steve Pfister <stpfiste@microsoft.com>
Co-authored-by: Alexander Köplinger <alex.koeplinger@outlook.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-VM-meta-mono good first issue Issue should be easy to implement, good for first-time contributors help wanted [up-for-grabs] Good issue for external contributors in-pr There is an active PR which will close this issue when it is merged
Projects
None yet
4 participants