Local copy 'xxx' of the variable 'xxx' is never modified; - shared-ptr

shared_ptr<int> sp1(new int(10));
shared_ptr<int> sp3(sp1);
*sp3 = 20;
I wrote the code above, but clion advises me that 'Clang-Tidy: Local copy 'sp3' of the variable 'sp1' is never modified; consider avoiding the copy';and clion modifies my code to below:
I want to konw why clion give me that advise
and why const shared_ptr<int>& sp3(sp1); is the best
thank you!

Copying any large object generally costs more than just referencing it (, and the reference can sometimes be optimized by the compiler). clang-tidy is smart enough to detect that you never modify sp3 and the copy can be avoided.
If you only wonder why clang-tidy gives you this suggestion, you can stop here, since it will give you the same suggestion whatever class you use. The following paragraphs explain how copying a shared pointer can be expensive.
This represents your original code:
contains
sp3 --------------
| copy of \
| \ ______________
V contains \ | ... | points to
sp1 --------------------> | new int(10) -+----------> 10
|______________|
control block
By using const shared_ptr<int>& sp3(sp1); you create a reference to sp1, and you can still change the value the raw pointer points to. The const & only means you cannot modify sp1 by sp3.
______________
& contains | ... | points to
sp3 ------>sp1 -----------> | new int(10) -+----------> 10
|______________|
control block
The control block is used for reference counting and ensures thread-safety by atomic operations, which costs much more time than just copying bytes. That's why you should only copy a std::shared_ptr<?> when you really need to. (e.g. Pass it to another thread or store it in a graph structure)

Related

Attaching to a process and call `dup2` on aarch64?

I tried attaching to a running process with gdb to redirect its stdout to an external file with these commands:
#Attaching
gdb -p 123456
#Redirecting (within GDB)
(gdb) p dup2(open("/tmp/my_stdout", 1089, 0777), 1)
I used the number 1089 because it represents O_WRONLY | O_CREAT | O_APPEND.
Firts, GDB just complained about some missing return types:
'open64' has unknown return type; cast the call to its declared return type
So I modified my command to
#Redirecting (within GDB)
(gdb) p (int)dup2((int)open("/tmp/my_stdout", 1089, 0777), 1)
This was successfully executed, and also works.
I'm trying to figure out how can I write a small utility that does the exact same thing as the above:
attaches to a process by PID
calls this (int)dup2((int)open("/tmp/my_stdout", 1089, 0777), 1)
Part2 seems easy, however part1 doesn't seem to work on aarch64. I could manage to work it on arm though.
There are a quite a few solutions which tries to solve this problem:
reptyr (doesn't work on process started by systemctl)
reredirect (doesn't support aarch64 at all)
injcode (doesn't support 64bit at all)
neercs (for sure no support for aarch64)
retty (for sure no support for aarch64)
If GDB can work, this is surely possible, but GDB is huge to analyze, and I hope I have some better solution which would not take weeks or months, like digging myself into GDB's source.

IDA PRO change .rdata value

How can I change the circled value? (5CB4F8B3h)
I am not a professional, but it is vital for me to influence this value.
Treat it with understanding :)
Using a hex editor, locate the sector containing the hex value you need to modify, and change it. TimeDateStamp is in epoch time, so you should get the timestamp in epoch time and convert it to hexadecimal (you may use a calculator in "programming mode", type the decimal timestamp and you will get its hex value.
After some googling, I found that a tool called PE Explorer can modify the timestamp of PE executables, which is the thing you're attempting to do, so this could be a better solution for a no professional. The instructions are here. I'm in no way affiliated to this product, I just thought it may be useful for your needs.
Modify these values in IDA with idc function PatchDword:
success PatchDword(long ea,long value);
This function changes a dword (4 bytes) at address ea to value.
You want to change 3 values at 0x14010D484, 0x14010D4A0 and 0x14010D4BC.
In IDA run "File->IDC command..." and enter this script with newValue1, newValue2 and newValue3 set to new values for these addresses:
if( !PatchDword(0x14010D484, newValue1) || !PatchDword(0x14010D4A0, newValue2) || !PatchDword(0x14010D4BC, newValue3))
Message("Failed to patch!\n");
Click OK and check the output window - there should be no error messages.
Generate DIF file - "File->Produce File->Create DIF file...". The DIF file is a text file with a list of patched bytes. Each line looks like:
0005A827: 5D BB
In this example 0005A827 is an offset in the binary on the disk, 5D is the original value, BB is the new value.
Apply this DIF file with some patch applyer or do it manually in a hex editor - move to the offsets from the DIF file and change the values of the bytes.
Your binary can use checksum checking. In this case it will not run after the patch. The checksum fix depends on the checksum type used.

simple_copy example on pmem.io

I have created the emulated device given at http://pmem.io/2016/02/22/pm-emulation.html, successfully.
It shows the device correctly:
:~/Prakash/nvml/src/examples/libpmem$ mount | grep pmem
/dev/pmem0 on /mnt/pmemd type ext4 (rw,relatime,dax,errors=continue,data=ordered)
However, when I execute the simple_copy sample given with pmem nvml, it gives this error:
amd#amd:~/Prakash/nvml/src/examples/libpmem$ ./simple_copy logs
/dev/pmem0 pmem_map_file: File exists
amd#amd:~/Prakash/nvml/src/examples/libpmem$ ./simple_copy logs
/dev/pmem0/logs pmem_map_file: Not a directory
Am I not using the program correctly?
Also, I have mounted the device as dax and I clearly see the performance advantage with
:~/Prakash/nvml/src/examples/libpmem$ sudo dd if=/dev/zero of=/dev/pmem0 bs=2G count=1
0+1 records in
0+1 records out
2147479552 bytes (2.1 GB, 2.0 GiB) copied, 0.910729 s, 2.4 GB/s
:~/Prakash/nvml/src/examples/libpmem$ sudo dd if=/dev/zero of=/mnt/pmem0/test bs=2G count=1
0+1 records in
0+1 records out
2147479552 bytes (2.1 GB, 2.0 GiB) copied, 6.39032 s, 336 MB/s
from the errors posted, is seems reasonable to believe:
without the appropriate option, it will not create a directory
without the appropriate option, it will not replace a file
If you open the example you are referring to, you will see the following:
if ((pmemaddr = pmem_map_file(argv[2], BUF_LEN,
PMEM_FILE_CREATE|PMEM_FILE_EXCL,
0666, &mapped_len, &is_pmem)) == NULL) {
perror("pmem_map_file");
exit(1);
}
This is the part that is giving you trouble. To understand why, let's look at the man 7 libpmem. You can find the relevant part here.
This is the paragraph we are interested in:
The pmem_map_file() function creates a new read/write mapping for a
file. If PMEM_FILE_CREATE is not specified in flags, the entire
existing file path is mapped, len must be zero, and mode is ignored.
Otherwise, path is opened or created as specified by flags and mode,
and len must be non-zero. pmem_map_file() maps the file using mmap(2),
but it also takes extra steps to make large page mappings more likely.
So, the pmem_map_file function effectively calls open(2) and then mmap(2). In the simple_copy.c example we can observe that the flags which were used are: PMEM_FILE_CREATE and PMEM_FILE_EXCL, and as we can learn from the manpage, they roughly translate to O_CREAT and O_EXCL respectively.
This means that the error messages are correct and you've received them because in your first attempt you've provided an existing file, whilst on the second attempt you tried a directory.
There's an in-depth explanation of libpmem here.

WinDBG extension - Breakpoint listing

Is there any way how can I get a list of breakpoints from within Windows Debugger Extension?
I'm using plain C (and I'm trying to avoid using COM interface they provide and I'm not even sure if that COM interface provides a way to do that).
I've read and researched wdbgexts.h and dbghelp.h but neither of them seem to contain any usable function or global variable, although there are some info on BPs in those files, such as DBGKD_GET_VERSION::BreakpointWithStatus.
Use IDebugControl::GetNumberBreakpoints, then IDebugControl::GetBreakpointByIndex.
Windows Debugger Extension provides function ULONG64 GetExpression(PCSTR lpExpression) (of course it's <sarcasm>well documented</sarcasm>)
#define GetExpression (ExtensionApis.lpGetExpressionRoutine)
which allows you to get results from any WinDBG expression like ?? #eip.
GetExpression( "#eip"); // Without `?? ` in the beginning
Next, if you take a look at:
Windows Debugger Help » Debugging Tools For Windows » Debuggers » Debugger References » Debugger Commands » Syntax Rules » Pseudo-Registers Syntax
You will find a line what looks like this:
$bpNumber - The address of the corresponding breakpoint. For example,
$bp3 (or $bp03) refers to the breakpoint whose breakpoint ID is 3.
Number is always a decimal number. If no breakpoint has an ID of
Number, $bpNumber evaluates to zero. For more information about
breakpoints, see Using Breakpoints.
So with some overhead you'll get this (working) solution:
#define MAX_BREAKPOINTS 100
DWORD i, addr;
CHAR buffer[] = "$bp\0\0\0\0\0\0\0\0\0\0\0\0";
for( i = 0; i < MAX_BREAKPOINTS; ++i){
// Appends string to BP prefix
itoa( i, buffer+3, 10);
addr = GetExpression( buffer);
if( !addr){
break;
}
// Do stuff
}
The only another solution is to use COM objects as Steve Johnson suggested.

PIC C - What's the purpose of this?

In Microchip TCP/IP stack we encounter the following code:
while(1)
{
AppConfig.MyIPAddr.Val = MY_DEFAULT_IP_ADDR_BYTE1 | MY_DEFAULT_IP_ADDR_BYTE2<<8ul | MY_DEFAULT_IP_ADDR_BYTE3<<16ul | MY_DEFAULT_IP_ADDR_BYTE4<<24ul;
AppConfig.DefaultIPAddr.Val = AppConfig.MyIPAddr.Val;
AppConfig.MyMask.Val = MY_DEFAULT_MASK_BYTE1 | MY_DEFAULT_MASK_BYTE2<<8ul | MY_DEFAULT_MASK_BYTE3<<16ul | MY_DEFAULT_MASK_BYTE4<<24ul;
AppConfig.DefaultMask.Val = AppConfig.MyMask.Val;
AppConfig.MyGateway.Val = MY_DEFAULT_GATE_BYTE1 | MY_DEFAULT_GATE_BYTE2<<8ul | MY_DEFAULT_GATE_BYTE3<<16ul | MY_DEFAULT_GATE_BYTE4<<24ul;
AppConfig.PrimaryDNSServer.Val = MY_DEFAULT_PRIMARY_DNS_BYTE1 | MY_DEFAULT_PRIMARY_DNS_BYTE2<<8ul | MY_DEFAULT_PRIMARY_DNS_BYTE3<<16ul | MY_DEFAULT_PRIMARY_DNS_BYTE4<<24ul;
AppConfig.SecondaryDNSServer.Val = MY_DEFAULT_SECONDARY_DNS_BYTE1 | MY_DEFAULT_SECONDARY_DNS_BYTE2<<8ul | MY_DEFAULT_SECONDARY_DNS_BYTE3<<16ul | MY_DEFAULT_SECONDARY_DNS_BYTE4<<24ul;
// Load the default NetBIOS Host Name
memcpypgm2ram(AppConfig.NetBIOSName, (ROM void*)MY_DEFAULT_HOST_NAME, 16);
FormatNetBIOSName(AppConfig.NetBIOSName);
break;
}
What's the function of the while(1)...break since it only executes one time ?
Looks like legacy code to me. It's common to have a while(1) loop to initialize PLLs and such, but generally the breaking condition is dependent upon a register status bit in those circumstances.
If it were me, I would comment out the while(1) line, recompile, and see if any smoke appears ;-)
Since there appears to be no continue statements or unconditional goto's in the loop body, I would say that it is just a way of enclosing a scope around that section of code. Interestingly, there are no automatic variables declared inside of the scope making the scope pretty useless.
Must be for scope. I don't see any other reason.
EDIT
Also, it could be someone was copy/pasting code from somewhere else that had a continue/break/etc in the block then just put their own code in there without thinking about it.
There's only one way to a truly definite answer: Ask the vendor for the history of that file (preferably with check-in log messages). Everything else seems like speculation.
It is perhaps more usually written as a do { ... } while (0); loop which does not need a break in it (unless you need an early exit from the loop). In this context, as others said, it does not seem to provide any benefit unless one of the two functions is actually a macro, but the macro should be self-contained anyway.

Resources