Setting process name (as seen by `ps`) in Go - linux

The following (rightfully) doesn't work:
package main
import (
"os"
"time"
)
func main() {
os.Args[0] = "custom name"
println("sleeping")
time.Sleep(1000 * time.Second)
println("done")
}
Some languages provide this feature of setting process name as a built-in functionality (in Ruby, for instance, it is only a matter of assigning to $0) or as a third-party library (Python).
I'm looking for a solution that works, at least, on Linux.

There are multiple ways to accomplish this, and many of them only work in certain situations. I don't really recommend doing it, as (for one thing) it can result in your process showing up with different names in different situations. They require using syscall and/or unsafe, and so you're deliberately subverting the safety of the Go language. That said, however, your options seem to be:
Modify argv[0]
func SetProcessName(name string) error {
argv0str := (*reflect.StringHeader)(unsafe.Pointer(&os.Args[0]))
argv0 := (*[1 << 30]byte)(unsafe.Pointer(argv0str.Data))[:argv0str.Len]
n := copy(argv0, name)
if n < len(argv0) {
argv0[n] = 0
}
return nil
}
In Go, you don't have access to the actual argv array itself (without calling internal runtime functions), so you are limited to a new name no longer than the length of the current process name.
This seems to mostly work on both Darwin and Linux.
Call PR_SET_NAME
func SetProcessName(name string) error {
bytes := append([]byte(name), 0)
ptr := unsafe.Pointer(&bytes[0])
if _, _, errno := syscall.RawSyscall6(syscall.SYS_PRCTL, syscall.PR_SET_NAME, uintptr(ptr), 0, 0, 0, 0); errno != 0 {
return syscall.Errno(errno)
}
return nil
}
The new name can be at most 16 bytes.
This doesn't work on Darwin, and doesn't seem to do much on Linux, though it succeeds and PR_GET_NAME reports the correct name afterward. This may be something peculiar about my Linux VM, though.

To change a process name on Linux, you need to use the prctl system call combined with the PR_SET_NAME option.
At the moment, I don't think you can do this in Go code. You can, however, build a small C module to do this and then integrate it into your Go build.

I don't think that "process title" is a well defined term. Anyway, what has Ruby to do with Go? The documentation for os.Args doesn't mention any "process title", nor it says any magic will happen on assigning to a slice item. The later is actually a general property of Go. There's no magic getters/setters for struct fields, variables of array/slice items, so a simple assignment simply assigns and does nothing more and cannot do anything more.
In short, the lack of magic is the expected, correct behavior.
For fiddling with process properties other than the portably accessible ones via the 'os' package, one has to use package 'syscall' in a platform specific way. But then the build constraints (discussed here) can help to correctly handle stuff across platforms.

Related

How to import platform-specific struct?

I've got a struct in a file that begins with this line:
// +build windows
Therefore it will only be built on Windows. However, the part of the application that initializes everything needs to check if it is running on Windows and if so, create an instance of the struct. I have no idea how to do this without breaking things on other platforms.
For example, if the file contains a function newWindowsSpecificThing() and I compile on Linux, the function won't exist because it is defined in a file that isn't being compiled. (And, of course, this will produce an error.)
How do I work around this dilemma?
I think your solution would be to have some method on your struct which is used on all platforms. Look at how the dir_*.go files work for the os package. The func (file *File) readdirnames(n int) (names []string, err error) is available on all platforms by providing it in dir_plan9.go, dir_unix.go and dir_windows.go.
For your problem, I'd take the same approach but with some generic method that does internal work. In your application logic you'd call that function and in your file_unix.go file you'd define that function to do nothing (empty body).
Somewhere you clearly have a function that calls newWindowsSpecificThing(). That should be in a Windows-specific file. If it were, then it wouldn't matter that it isn't available. The fact that you have something "check if it is running on Windows" suggests a if runtime.GOOS == "windows" statement somewhere. Rather than have that, move the entire if into a function that is defined in a Windows-specific file. You'll also need to define that function in a !windows file, which is fine.
As an example from my code, I have a function:
func Setup() *config {
var cfg *config
// setup portable parts of cfg
return PlatformSpecificSetup(cfg)
}
I then have a file marked // +build windows that defines PlatformSpecificSetup() one way, and another marked // +build !windows that defines it another. I never have to check runtime.GOOS and I never have to deal with undefined data types. The config struct itself is defined in those files, so it can have different fields for each platform (as long as they agree enough for Setup()). If I were being more careful, I could create a struct like:
type config struct {
// independent stuff
plat *platformConfig
}
And then just define platformConfig in each platform file, but in practice I've found that more trouble than it's worth.

Verilog: variable assignment to virtual interface?

Sorry if I had this stupid question...I've been trying to google for answer but couldn't find one. :(
I have a problem assigning a variable to a virtual interface. For example:
Param.sv
...
string MyInput[3];
MyInput[0] = Signal_CLK; //Storing SignalName to in an Array.
MyInput[1] = Signal_Tx;
MyInput[2] = Signal_Rx;
...
MyInterface.sv
...
Signal_CLK = dut.MicroController.Source.clk; //Signal destination
Signal_Tx = dut.MicroController.Tx_01;
Signal_Rx = dut.MicroController.Rx_01;
...
Test.sv
virtual MyInterface my_vif
logic [7:0] read_value;
....
for (i = 0; i <3; i++ )
begin
read_value = my_vif.My_Input[i];
..
//some logic to compare read_value with spec//
..
end
The problem is when compiling, it doesn't translate my_vif.My_Input[0] into my_vif.***dut.MicroController.Source.clk***. Instead, it thinks that the path is my_vif.***My_Input[i]***.
The reason the compiler thinks you are trying to access my_vif.My_Input[i] is because you are. The My_Input[] array is a completely separate string array; not part of the virtual interface. When using the "thing.thing.thing" syntax, the compiler will loyally follow it, so it will expect there to be something called My_Input that has some elements (as its an array) as a member of the interface given by my_vif.
However, looking over youre code, you are trying to have My_Input[i] replaced at compile time, which is very different. The compiler will not run your loop, look in My_Input[i] and find the string "Signal_CLK" and replace that as part of the path to get the path my_vif.Signal_CLK. Nor can it do that at run time.
I dont know of a generic solution to looking over any variables in an interface; though Im also not sure if thats really what you want. IF you provide more details on the rest of your checker, we might be able to help you more.
You cannot use strings to look up identifiers by name within SystemVerilog. There are tool specific and C interfaces that may let you do this, but that would be very inefficient. The best way to do this by using a combination of abstract/concrete classes and the bind construct. See these references: http://events.dvcon.org/2012/proceedings/papers/01P_3.pdf and http://www.doulos.com/knowhow/sysverilog/DVCon08/DVCon08_SysVlog.php

golang bufio in object

I'm fairly new to Golang; previously used Python.
I am having difficult time to apply bufio in the object.
type fout struct {
filename string
fo File
bfo Writer
}
func (a *fout) init() {
a.fo,_:=os.Open(a.filename)
a.bfo:=bufio.NewWriter(fo)
}
Basically, I like to create objects; each will have it's filename, and bufio will be used.
Can anyone help me please?
Thank you
Few things in the code sample:
Every use of a name from another package needs to be prefixed with the package name--so fo File has to be fo *os.File.
You normally declare *bufio.Writer and *os.File as pointers (see the bufio and file docs at http://golang.org/pkg)
You want plain =, not :=, for assigning to attributes like a.fo and a.bfo.
Don't throw away errors, particularly if you're used to exceptions, or you'll have impossible-to-debug problems. (For a trivial script for learning you can if err != nil { panic(err) }, but for real use, you almost always want to return them.)
It could also help to review the tour, pick up some tricks/advice from the various talks and blog posts, maybe walk through Go By Example (I admit I haven't persionally used it but sounds like it could be useful when getting started), look at some open-source Go code (projects on Github, the stdlib, anything), and run through the surprisingly readable spec once you're at the level where you want to know how the language really works.

In Go, why does "File.Readdirnames" make a "clock_gettime" system call?

As a follow up to this question, I am trying to write a Go program that only lists a files name in an efficient matter without unnecessary system calls. This is what I have thus far:
package main
import (
"os"
"fmt"
"log"
)
func main() {
// Open directory and check for errors
f, err := os.Open(".")
if err != nil {
log.Fatal(err)
}
// Get file names
files, err := f.Readdirnames(0)
if err != nil {
log.Fatal(err)
}
// Print files
fmt.Print(files, "\n")
}
However, when I run an strace, I see many of the following:
clock_gettime(CLOCK_REALTIME, {1406822401, 824793686}) = 0
What does that pertain to? How can I make this code more efficient?
I am spitballing, but I would think that it is related to Go's built-in scheduler and garbage collection.
Short answer is, go will never be quite as fast as C because it provides all of that extra runtime functionality which C doesn't.
The code you listed is probably the fastest way to do what you want in Go.
clock_gettime is just a system call,which is called in go's runtime. runtime do a lot of things, schedual, and so on, so it's normal for so many clock_gettime.
I don't think you can make this program more efficient, 'cause it is just for so tiny function .You shouldn't mind it.

how to use dll injecting?

i was looking how to inject a dll into a program (exe, or dll, etc). i have been googleing dll injecting but i have not found anything that is very helpful :(. i have not worked with dlls very much so im not sure on what to do, i really could use some help on this.
uhh the only thing i have really found is setwindowshookex but i can't find any examples for it and i don't how to use it. any questions just ask and i'll try to help.
EDIT hey i was googling and this looks like something about dll injecting that is worth looking at but i can't get the code to run :\ (How to hook external process with SetWindowsHookEx and WH_KEYBOARD)
The method I'm most familiar with was is was described by Jefferey Richter in Programming Applications for Microsoft Windows. I mention this because even if you don't get your hands on the book itself there is probably sample code floating around. I think he may have also written some journal articles. He, also mentions a couple of alternative approaches, of which I will describe only one, from memory. He also may have written some MSJ / MSDN articles that are relevant.
Anyway, the basic idea is to cause the process that you want to load your DLL to issue a call to LoadLibrary. This is done using CreateRemoteThread with the address of LoadLibary for lpStartAddress and the address of a string naming your DLL in for lpParameter. Arranging for and locating the string is done using VirtualAllocEx to allocate some memory in the remote process, and WriteProcessMemory to fill it with the string.
PSEUDO CODE:
void InjectDllIntoProcess(DWORD processId, char *dllName)
{
HANDLE hRemoteProcess = OpenProcess(
// Assumes that dll and function addresses are the same in different processes
// on the same system. I think that this is true even with ASLR, only issue I
// can think of is to make sure that the source and target process are both 32
// or both 64 bit, not a mixture.
// Note that it is asking for the ASCII version
HMODULE hDll = LoadLibrary(_T("Kernel32.dll"));
void *loadLibAddr = GetProcAddress(hDll, _T("LoadLibraryA"));
// Inject the DLL name
char * remoteAddr =
(char *)VirtualAllocEx(hRemoteProcess, NULL, strlen(dllName) + 1, ...
WriteProcessMemory(hRemoteProcess, remoteAddr, dllName, strlen(dllName) + 1 ...
CreateRemoteThread(hRemoteProcess, ??, 0, loadLibAddr, remoteAddr, ...
}

Resources