I am currently making an embedded system.
For that I have 2 different panic handlers based on whether it is run normally or as a test.
#[cfg(test)]
for the test panic handler and
#[cfg(not(test))]
for the normal panic handler.
rust-analyzer says: code is inactive due to #[cfg] directives: test is enabled
and grays out the function.
Test is never explicitly set so I cant just change it and I don't want to disable the graying out inactive code across the workspace.
Is there a way to either disable rust-analyzer checking the test cfg, or to disable the gray out just for this function
I tried finding infos about the test flag but I couldn't find any, i'm using VS Code if it is important
In VSCode's workspaces settings, set the following:
"rust-analyzer.cargo.extraEnv": {
"RUSTFLAGS": "--cfg rust_analyzer"
}
This will enable the #[cfg(rust_analyzer)] for rust-analyzer metadata inspection.
Then, replace #[cfg(not(test))] with #[cfg(any(not(test), rust_analyzer))], and #[cfg(test)] with #[cfg(all(test, not(rust_analyzer)))]. This will disable and enable the functions for testing as usual, but when running in rust-analyzer, only the no-test function will be enabled.
Important: this will only work if you don't need to set special RUSTFLAGS for your workspace.
Related
I am new to Rust and am looking for a way to enable the deterministic execution flag property on the cranelift complier for my Rust project described here through Cargo.toml.
https://github.com/wasmerio/wasmer/pull/709/files/6ca581279811aee9d26d77ed2b7372a6153fe3bf#
I would like the feature to stay enabled by default.
I tried enabling the feature on Cargo.toml like this way
wasmer-compiler-cranelift = { version = "2.0.0", default-features=false, features=["deterministic-execution"]}
But this doesn't seem to work as on doing cargo check I get an error which states that the compiler does not have this feature.
Android gradle plugin generates tons of .rawproto files in build/android-profile directory. What are they used for? Is there a way to disable this madness or automatically delete them?
I've been bugged by it for a long time, and now that I noticed there's gigabytes of this hogging my smallish SSD, I've decided to figure out a way to disable it. For me the most annoying thing before occupying too much space was gradlew clean leaving a build folder behind.
Only tested with com.android.tools.build:gradle:3.0.1, so YMMV.
TL;DR
For global application read last section, per-project use this in rootProject's build.gradle:
com.android.build.gradle.internal.profile.ProfilerInitializer.recordingBuildListener =
new com.android.build.gradle.internal.profile.RecordingBuildListener(
com.android.builder.profile.ProcessProfileWriter.get());
// and then `gradlew --stop && gradlew clean` to verify no build folder is left behind
Investigation
Thanks to https://stackoverflow.com/a/43910084/253468 linked by #JeffRichards mentioning ProcessProfileWriterFactory.java, I've put a breakpoint there and checked who's calling it by running gradlew -Dorg.gradle.debug=true --info (not to be confused with --debug) and attaching a remote debugger.
I followed the trail and found that ProcessProfileWriter.finishAndMaybeWrite creates the folder and writes. Backtracing on method calls I found that ProfilerInitializer.recordingBuildListener controls whether it's called ... and that is initialized directly by BasePlugin (apply plugin: 'com.android.*').
So in order to prevent anything from happening I opted to try to disable the guard, by pre-initialized that static field. Thankfully Groovy (and hence Gradle) doesn't give a * about JVM visibility modifiers, so without reflection here's the magic line:
com.android.build.gradle.internal.profile.ProfilerInitializer.recordingBuildListener =
new com.android.build.gradle.internal.profile.RecordingBuildListener(
com.android.builder.profile.ProcessProfileWriter.get());
I know, it's a bit verbose, but it works, and if you import stuff it looks better:
ProfilerInitializer.recordingBuildListener = new RecordingBuildListener(ProcessProfileWriter.get());
Applying the magic
In a single-project build (one build.gradle) you must apply this before
apply plugin: 'com.android.application'
In multi-project builds (most template projects: app folder, settings.gradle, and many build.gradles) I suggest you apply it around the buildscript block:
buildscript {
// ...
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
}
}
// magic line here
Make sure it's before any apply plugin:s, and not inside a buildscript block.
Applying the magic globally
Obviously if it bothers us in one project, it will in all cases, so following Gradle's manual, create a file in ~/.gradle/init.gradle or %USERPROFILE%\.gradle\init.gradle (mind you this folder can be relocated with GRADLE_USER_HOME) with the following contents:
// NB: any changes to this script require a new daemon (`gradlew --stop` or `gradlew --no-daemon <tasks>`)
rootProject { rootProject -> // see https://stackoverflow.com/a/48087543/253468
// listen for lifecycle events on the project's plugins
rootProject.plugins.whenPluginAdded { plugin ->
// check if any Android plugin is being applied (not necessarily just 'com.android.application')
// this plugin is actually exactly for this purpose: to get notified
if (plugin.class.name == 'com.android.build.gradle.api.AndroidBasePlugin') {
logger.info 'Turning off `build/android-profile/profile-*.(rawproto|json)` generation.'
// execute the hack in the context of the buildscript, not in this initscript
new GroovyShell(plugin.class.classLoader).evaluate("""
com.android.build.gradle.internal.profile.ProfilerInitializer.recordingBuildListener =
new com.android.build.gradle.internal.profile.RecordingBuildListener(
com.android.builder.profile.ProcessProfileWriter.get());
""")
}
}
}
I use debug strings for debugging Loopback 2.0 application. Loopback documentation says:
The LoopBack framework has a number of built-in debug strings to help
with debugging. Specify a string on the command-line via an
environment variable as follows:
MacOS and Linux
$ DEBUG=<pattern>[,<pattern>...] node .
Is it possible to change patterns dynamically in runtime? Or is it possible to use environment-specific configuration?
Before I get deeper note that this debug logging facility uses visionmedia's debug module which handles almost all of the logic.
Is it possible to change patterns dynamically in runtime?
Well before any module is loaded, safest and best way I believe is to just manipulate the environmental variables:
if (process.env.NODE_ENV === 'development') {
process.env.DEBUG = process.env.DEBUG + ',loopback:*';
}
Another way would be to load debug and use it's .enable method:
require('debug').enable('loopabck:*');
But note that it only works if you do this before Loopback is required since it only allows changes before it's instances are created, which is in this case before loopback is loaded. Another thing is that, there might be multiple debug modules installed depending on the dependencies and your package manager(npm#3, npm#2 and yarn behave differently). debug might be in your node_modules directory, or it might be in loopback each module, node_modules directory. So make sure you require all instances of it and enable, if you want to do it this way.
Now if don't want to do it on the startup, well API doesn't allow changes in the runtime. You can view the discussion regarding this here. Though there are some dirty ways to go around it, but these might possibly break in the future so be careful.
Firstly, there's a module called hot-debug which supposedly makes require('debug').enable work on previously created instances also, but when I tried it, it didn't work perfectly and it was buggy, but it's possible it might work fine for you.
If that doesn't work for you another way is to override require('debug').log method. If this is defined, debug will call this method instead of console.log with the formatted the arguments. You can set DEBUG=* and then filter it yourself:
require('debug').log = function (string) {
if (string.contains('loopback:security')) {
console.log(string);
}
};
This way will be slow in production though as all the debug output will be formatted before being filtered even though nothing might be outputted to console.
Another thing to override the require('debug').init method. This is called everytime a new debug instance is created. Since every debug instance uses an enabled property to check if it's enabled we can toggle that.
const debug = require('debug');
const { init } = debug;
const instances = [];
debug.init = function(debugInstance) {
init(debugInstance);
instances.push(debugInstance);
};
// You can call this function later to enable a given namespace like loopback.security.acl
function enableNamespace(namespace) {
instances.forEach(instance => {
instance.enabled = instance.namespace === namespace;
});
}
Though there's a lot of improvement can be done on this, but you get the idea.
I can change debug namespace dynamically with the hot-debug module.
In my app, I've just created a function for this :
require('hot-debug')
const debug = require('debug')
function forceDebugNamespaces (namespaces) {
debug.enable(namespaces)
}
// Usage
forceDebugNamespaces('*,-express:*,-nodemon:*,-nodemon')
In my case, I have a config file which allow me to set process.env.DEBUG but I needed to find a way to update debug namespaces without restarting my app (the config file is watched for changed by my app).
I started using a Web API cache which I add to particular methods by using an aspect [Cache]. Everything worked great. Later on I changed this method to be async, but since then the compiler started throwing following warnings:
The parameter 'region' of method 'GetTree(System.String,
System.String, System.String[])' has been optimized out by the
compiler and will not be available to the aspect. Disable compiler
optimizations to access the parameter.
Here you can see an example of how I am using Postsharp:
[Cache]
public async Task<IEnumerable<Node>> GetTree(
[FromUri] string region,
[FromUri] string language,
[FromUri] string[] networks)
{
...
await ...
}
What do I need to do in order to get rid of the warning?
The C# compiler optimizations remove the parameters from the state machine class if these parameters are not used anywhere inside the async method. This happens regardless of whether you use PostSharp or not. PostSharp shows you the warning to notify that the removed parameters cannot be accessed inside the aspect.
It's recommended to upgrade to the latest build of PostSharp - the newer versions can handle this issue by re-introducing the missing parameters back into the state machine.
If you cannot upgrade, then the workaround is to disable "Optimize code" in the build page of the project properties for release builds (it's disabled for debug builds by default).
I notice Debug.Assert does not trigger in Metro apps, however, if the project is a traditional one like Console or WinForm, it does trigger. And yes, I am in Debug mode.
Is it a setting not properly set in Visual Studio (11 Beta)? Or Debug.Assert is intended to be disabled in metro apps?
I know many exceptions are swallowed during the execution of Metro apps, but Debug.Assert is so handy that I can't think of a reason why it should be disabled.
Seems like a bug. I would roll out my own assert method. Something like:
[Conditional("DEBUG")]
public static void Assert(bool condition)
{
if (!condition)
System.Diagnostics.Debugger.Break();
}
It does trigger, look in the Output window. It just doesn't automatically prompt you to ask if you want a debugger break and thus just keeps motoring.
The DefaultTraceListener.AssertUIEnabled property is false. That's an implementation problem, can't display a message box on top of Metro UI. Which does actually work but the monitor switches to the desktop, pretty undesirable when you would have liked to click No. Hard to solve and no doubt on the todo list. You can't easily get to the property to set it to true, it is inaccessible from the metadata. Filip's workaround sounds half-decent.
There is the same problem with F# in WinRT, in VS2013. The assert statement, which is an alias for System.Diagnostics.Debug.Assert, does not raise an exception, so unless you are watching the Output window then your assertions can fail without being noticed. Even if you are watching, it is hard to find the spot where the assertion was raised.
I followed Filip's suggestion and wrote a short utility, as follows:
namespace MyProj.Infrastructure
module Diagnostics =
let Assert condition = if not condition then
System.Diagnostics.Debugger.Break()
I chose Debugger.Break over raising an exception because it stops the debugger at the place the assertion fails. However, raising an exception is an acceptable alternative.
I didn't have any suitable global projects or modules already in my solution, so I had to create them just for this, which was quite annoying.